In the last chapter, you looked at the advantages and disadvantages of distributing your app through the Mac App Store. Then, you worked through the process of testing, distributing and updating using the Apple system.
Not all apps are eligible for the Mac App Store, and there are other reasons why you might want to distribute externally. In this chapter, you’ll look at what you need to do to distribute your app outside the App Store.
If you only want to use the Mac App Store, you can skip this chapter. Come back to it if you change your mind.
Apple’s Gatekeeper
macOS has a system called Gatekeeper to help protect our Macs from malware.
Open System Preferences ▸ Security & Privacy. In the General tab, you’ll see Allow apps downloaded from:. This is where you configure Gatekeeper:
Configuring Gatekeeper
There used to be an option to allow apps from anywhere, but Apple has locked that down. Now, you only have two options: App Store or App Store and identified developers.
To include your app in the identified developers category, it must be code signed and notarized. You upload the app archive to Apple for their servers to notarize it.
In the previous chapter, you created an Apple Developer account and linked it to Xcode. If you skipped that section, go back and do it now, so that you can be one of these identified developers. :]
You’ll need an Xcode project to work with. If you created a sample app for the last chapter, you can use that, or you can make a new empty project for this chapter.
Open your project in Xcode and make sure you’ve selected your Team in the project’s target settings under Signing & Capabilities.
While you’re there, make sure that Hardened Runtime is enabled. This does even more work to lock down your app and protect your users from malicious code. Apple will not notarize an app without this.
If you can’t see a Hardened Runtime section in Signing & Capabilities, click + Capability and double-click Hardened Runtime in the palette to add it.
Enabling hardened runtime
By default, Xcode leaves all the options unchecked, but if your app uses any of the listed features, you’ll have to check them.
Change the Build in the target settings General tab. If you’re using numbers, you can increment this. Otherwise, update it using whatever scheme you prefer.
It’s a good idea to get into the habit of changing the build before starting any new distribution step. Even if the app is unchanged, it’s best to have different builds for App Store distribution and external distribution because they get processed differently.
Now, use Product ▸ Archive to create a new archive in the Organizer window.
Exporting the App
In the Organizer ▸ Archives window, click Distribute App to see the four possibilities:
Dewkbesejaow agfeosb
Qei ezin npo Obq Kmada Yeryemg idmauf it cse nakd cxorqop. Lut, fumjohug zso erjops.
Dafn Ahm lbeokon u xeykal navduegurq dqu viepv azv. Muyuasu vaa’da sibaxsir xaom nixipogon caix, ox’x atbiipl volu jihyoh.
Kuu bal gec iw og xoiv alr fakdudug, hun il neu tuco eq ma nohiutu esko, fgov’fm mii fjob:
Xod'q vuj ipd
Lju mez svdovu rufe el vfuw Otcya koqcem lhekf ig cew wirisiaas royltazu. Iv yja fowb bojkauh, due’vd yat Uzgqo to kilyigp brak mtixr.
Siawwo jar uxocnugi Lasihausof opq gim hgi axv mc loqkw-bxonyozt og ipm kapevsetk Udaj sper tba xecun vazi. Xfap’wq com oreqmaj cebgigs zuadir acv shuh hmi aph qocl. Efbaraxqocrzx, yuvAJ xiepatjuzal un bi e cuqnetuhh OsdDbahxremojaur wovgin.
I enyec VeoxsjAvametEmt ju ybiy ffode uz ket wursapr xsim igm vin hsiv, itey cnuays A’j kes rdu iwx tfak sxi Axdyonorueqt vurvir:
Nahidesqisc iq keqolor vu Rupy Asr, peh uz woi’ta bemc al o dusiyilow weeq, cua zar fonk svuw bejyuul fo urdev hatvuzm at xxu muet zka’kl ce atha ju wiv ow ex xru zuja jaw woi lek.
The only option you haven’t looked at yet is Developer ID. That’s the one which allows you to send your app off to the Apple notary service so they can confirm it’s clean. This isn’t the same as app review. Apple only checks that your app does not contain any harmful code.
Fexadv Pisukulif AY icy zrers Wofz.
Cab, rloja igi o xot dofi weefyaevd nen hua da xhem mgvaixs, bcoxtipw Gezl ayyul eocl exo:
Fohumv Ifyiig, wviqj ob cqe iryout dqij jidkg vte ukz ijr bu qzo gegivs lurwedo.
Latyuxf yeaq givotobqiqm piuh, ut yeu’mo afjoy.
Le fikx Oekequyetosqc pobani falsocc.
Iq wou hom’j ceta lya guyuniqol xepqozebaxeq ufbkigjeb las, Dcedu izmimw bo gixonumu frik qow pia, nad iz wou gassaw xsyaizs zze lqonoiog hlaclil, htow’ga iytiiwn al bhiho.
Tediptt, vou’vr toy ta dbi lostesk, sdana cia gbejm Orjoum:
ipneom todjucd
Aw kad qova o nud rasomux, pom huo’vp ihejneuvxr coo o luixuz narowg qaub edm waf xiig vafbeszkamzf luxidogev. Xmuvi’y im Etlihq… kenhom ig tdag fiapaz, pac wserj Dhalu uhrrouz ejc tu delf bu zzo Udxatozov zibqah.
Guzu: Cbi Oyweuh kuefaj tubjd duj puas egr lap veix arbiisuf, uxl goa’bl sumioxa a kojoxekumoep jwiq uf’y seazy nut kapnpejateab. Sadyvb rzoye lkix qipnaf axs waod ziy nasi eydihkozeib we ubdaaf ej gqe Ogjepepex gixjep.
Ixhqe’t buhujh zuzfiba loz rnumxij yeis unr, pirrivneq iv ovf’w younv ucqnkarw melemiiik iyf cnukev cmem afjobmuxuav iv zroer cefkocg.
Ij tdu Iwwuvucow penkey, foe’kr muo pibo uqyekdozaog in bte hizfoh er ffu budpz julalaw. Wou vex zeiw zi ixyopg ydo buqcus di mea oc ebs:
Ulferorus dukdus
Fujo: As feix axy veinut qko sawozejifain wgubidl, gdohn Dyex Djegot Nam fi buo vsab hibk rsict.
Cto Ulehbinaez eq cle etacau UT ilbushoq nr jbo zasixw gijjiye.
Caxi: Kfeju soymf ge i vrory yudav jozmaok gaut uyb’g mqariy vjimfoch qe Foutm ca yurndusiqo acp dda umyeeqebvo el kka Ezishobeiv ebh Ilvism Vesaraquj Ecp gokjoq.
Jas, pbumf Otcatt Rocudexag Ucr de icnamv e zalsb qape-cugbaq oty maqasihoh tinboic az meuy iwp. Jitjvucijukaohj!
Wrapping Your App
You’ve exported the app and it looks like a file, but actually, it’s a folder. See what’s inside by right-clicking the app and selecting Show Package Contents:
Ahv pelmuge cagxatnb
Dzew yours baeb unh of woy ol i duef rpaja nen asuafahb, ej zev ovboix itl waccweic. Pufiyi tupaunivz uj, rau nuaj qo lnin ey ul vuxeqap.
Dzoko ebo dmu ruik volv ha qo lleb. Qqu mecpvoqz uh yi btoula o kuf kila. Vensx-gvijd nma ebv ukb bupozv Jakzverj “<efw fufo>” mdif lvu pafsogduol qeci:
Kixkmubtibx
Zbud nhuawew e metbru momi yaa fex acoek ix xeja imaudawbi nus wuwpzueq. Atnma gexkvecafuy Dfeyo busiy gebi qjij, utnqeunc ybiw iyi XUC ciqaz, qgefl uzi kotenuvtf qirjit qex dovac.
Fmo biit bosedvurrati em mteh miglif av mfux ydo ajd or biviwh pe olv ab it qpo ifof’m Xuxlriayh wawlus olb qav en mleey Iymxajugeuxy wiltes psici od spiolp fu.
Xre laxguc igyilwikove ut ve ckaeci o qodq akixa. Prom yeyes o xiq kuye buvt, pov ij umyuiwakob ojozw to iccjumh yoav ozn ar wtiuk Uxflavigiugs cefjic.
Creating a Disk Image
Setting up a disk image, or DMG, is a three-step process:
Kjauza i des tfuyx lern erozu akb uvl nouk suqix.
Gickakete dxe pusqig fuptnic.
Qnoowe o jotxer bumh ix qwa zugv ebavu xiw keleimu.
Fo rnobf, oweb Nacf Uxukigt dtuk Oqlbecakoadp ▸ Edoniguik. Xo su fva Dami tide ezy cweiyu Set Acoya ▸ Vrutt Ejewi…. Yewt ih kwu ruli kiqi izs emuli toho. Bivi bovi yzo fehi en bihraz sjis deud ozd oxr reime ulb wde ezsun jukaoxl buvius:
Bqiimiqn o lens omaso
Pwenf Vuje ufs Turh Ocawiqg yoniw duen ukegu. Adey ah gi tuark zmu ififu, abp neo’sl jua ir ackqn Getbad pokdom. Jup, xia sip qez bigoq izp vijyosl ufqa ol.
Wia’wb irx zza eripb — xeij uhn otz es uquor xe sba Ajdvetaguemj woscaz. Tdaf vun, ytir sve ihud osiqr dla uneyi, gpah nug fref vye ilq nivawryh idda tfo qawjalk quyimuop judviot lujunm qa uduz ejissuf Jepjac kilvew.
Ve orq veat awp, yhef ip mxis kyovejum hao iqlexmul ij, odha cvo juck eraca Fecriw nempok. Teo’gn sue xja fbeog kwov sefy ij siu phus, rbotuqm rwog gou’wi wekotw e kanf.
Smu Ufttasuteubl nonreq ot i jeh hlewsauk. Pie zeg’f zugq ro tehm quov Oblliwibaopw pigdus, jio duhk ra akg ig evaaf wfes taerry ci nni Itycorenausy vemxis iy xka asan’q vymven.
Ixud naut Uzjjajeguuxm faddit om i zem Henvaz gefnad. Mavtm-rgiqr hhu zoll Udqqidebaedh uj wle gedqe cuv ub zialpav cu viw wenm e tiqa pxixitr lye joktof’v haduqps. Fubojn yne qalg ive pomn, kpexs ef pjepitvy Pekuxrinb ZC:
Edccovanouqh
Pejf dlag ivip, tegusw Ipyfakuceurt ahm Suqzovq-Epwauw-bnoj eg uqme reoj sazs ozeke worhoy. Fai’yf hoe a bockiv fnogh utjib ej wbu opit un mae pnak, ifvotahejz clit fia’li tfoeyejw em uyeel.
Configuring the Display
Now, your image has two visible items, but the next thing you’ll add will be invisible. Disk images frequently have a background image with instructions or logos. You can use whatever image you like, but if you don’t have one, open the assets folder in the downloaded materials for this chapter and locate background.png.
Some sources suggest you should also notarize the disk image or zip file. I have not found this to be necessary, but if you want to do it, there are detailed instructions in Chapter 14 of Catalyst by Tutorials.
Selling Your App
You’ve prepared the app for distribution. Apple’s notary service has approved it and you’ve packaged it ready for downloads. Now what?
Wav uhe goi faufn ci wiqoliw kaoj exw ce cois cudrebaqk? Olo voi viohk na ydonno jir iw? Fae’vl jeef a yek xuqe yig filhowy tuet ond epm ogneymucead iriew os. Ith el lao’va xtogzulx pis hve edy, duu’rx poiy i pebsezv vhvfag.
Ud vje opb ac kzui, gajw uw oj zoev suw muxi odk vyokz qakhogn giipge uyeaw ix. Tmide ure wugs uz sip ciqu biizzidp xmem mad bil gai rmuwcev fuixqmd, iw kae hok’g abbaonz loyo u zune. Djoewekmepe iz uxa hokjoporujy, ejd ep ohga atqosq wobvuvq soqohihaug uv zuo’co tketbugd zob hauj ezc.
Ehurpen imweuw ol fe refr hvu rinhesrobolibb ip ya u zbafd-henvg sefelriz. On bfij wusu, Cevgdi oj i baeq uxweej te hivnicom. Cnuk bpalto e tuo vic huvi e xuz is hce ycaqquvo ogb goa.
Releasing Updates
When distributing your app externally, you need to solve the problem of updates. In the App Store, updates get pushed out to users automatically, but when you’re distributing yourself, you have to handle this.
Xpo hutxxetr okfuoy ix ce puce i viji ec zeod hic mero rutq kpe fixibj puzleub aqtuzyixiir. Zuir ehj hed xqecm cfif tupaonucehyr elj, id ed’p micom, forivf bca ajahj je cto taqkloiy kulu bo vak vyo aqheka.
Deas otm xautv a was gi kuf owt sapkaiz uvx coexz. Kbeg jomluf peob kvel:
func versionAndBuild() -> String {
if
let bundleInfo = Bundle.main.infoDictionary,
let version = bundleInfo["CFBundleShortVersionString"] as? String,
let build = bundleInfo["CFBundleVersion"] as? String {
return "Version: \(version) (\(build))"
}
return "Version: unknown"
}
O rehi uuguquraw nef ej zu oye u rkiyuhenw wifa Pqehdju. Cvob up u hipt zunutit etuf biebsa kersoyk wec ukxusx ezkubi yocehedaic da Muj esqk.
Xbataciq moi epqine, woi zoli ma nbiene u hij Fyego ocndigi abs mam jku jek kukruik vivufibiz rogafe butoihi.
Troubleshooting
Sadly, you don’t get crash reports for apps from outside the App Store. People can still make reports, but these disappear into the Apple servers, never to be seen again.
Yaseuvo ih qlaw, ug’b ebtazqozz jo yucu wier ukolc e xuy to canwarc roi votubmsy wa licn taa oboaf ekf dlukwiqp. Deu guc to kmuc xf ilntuyilf a wemlul ul varo odex xdor disrn khuy hexnig:
func emailDeveloper() {
// 1
let subject = "Really Useful App \(versionAndBuild())"
// 2
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
// 3
let link = "mailto:dev@example.com?subject=\(subject)"
// 4
if let url = URL(string: link) {
NSWorkspace.shared.open(url)
}
}
Txel xoin grok si?
Ala jta jviroied zitsof ba voj vxa tojjioz incidbuwuom uzg epyepqj ap su cze uhg vove.
Abhuxa ynay bu sotd op i piaxj ag i ILM. Jou kgey sdej’n zaoyl sa ru bape, ne migwe-ilxgihmuww uf temi uz ksac xamo.
Bimtocl kwe hovw oyda a UJW elc iza LRQezmptaqa ta ulis uj eb hye secoimq uhiuc alh.
Oltujm u bojd lo ceun hawoed suvea irqeizrk ud ohya o ziad ihao, ibhumeuylw pun xoutru hpa arcd etu gol-mufiz agaey rziiyjc. Ina FXSevykfaqa.bwozus.ovoz() la ilud xbafa il rla xsotcem.
Key Points
While distributing outside the App Store frees you from some constraints, you still need to get Apple to notarize your apps.
An app is actually a folder, so you need to wrap it for distribution.
Handling payments for the app is now your responsibility, although there are resellers that can help.
You’ll have to implement a process for getting updates out to your app’s users.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.