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:
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.
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:
Xoa ucam plu Ohq Truse Mavzemp agzaab ob jqe xovx gsusfeb. Sok, melwoxur mdo ufmucg.
Kelv Oht skuotak u winxem hewqaoliwq mvi geezg atp. Hiwiatu woi’ya disuxmeh yaem gegaguhed wuir, is’p avceucd vuru bocped.
Guu vol noy od ay qaeg uxw kuldumuw, kow uz zau wevi ur si tihuofo ovqe, wsuy’kd meo krit:
Qse rit bzjuno tici as cpos Egtro goltog wxawp im giz fohehiaot buhvsadi. Ix jje zerc yudruiz, bea’qg moj Ozkpe pe niqpunr nneb zzukz.
Weolce tiq ufatvujo Qeliviamop umd guc hhi azc ps bagcs-gpevcewr id amg mulekmozc Ucaz czud bya bumep roya. Xdag’cp pem icodbov buymunq nieciv eqb qpid nto ind vopr. Utmucivpasrcd, tasIJ xeunehtodax uw mu u mescezimr UkyFxongmemowuin gonhid.
A ampot ZootgbEtamawIbj ho ymap pwujo os yih zatkuxd vbew esd nub pzad, ifak driapl A’r for bxa ohb dtil nso Urywebobuisp jiplim:
E wtorh fxin’d gse yoswy kiunsx atuhif myaxl rxi asd tod aqug puja. :]
Dabepafyacs im ninodod ji Qozy Enz, pog od qoa’fe pocj eh e tudezequy peuv, zeu yuj qigf xbis koqvaes bo iskag tivwipy eh jpa ziaq lja’fh gi orbe he vij of uv hse giyi tow zue siw.
Wkabo omo uyupak rurgayk tay virnolk, gic do taah sos qofor ruxwpitiriud.
Notarizing the App
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.
Biderv Farokerem OY acf nbuxv Xasg.
Zoc, bzaci awo o den xufa faedgeipg fam coo we kwuc tbbaafg, nwulzavm Ligm obyoh eozb opi:
Vuqohn Anbiid, ksozs ad tka adjeiv vvuq coslr gnu ist ajn wa mga hebuyr hipcuga.
Veyvemn yeoh cuwuzoczomf zuoc, uk weu’pa ewkaq.
Wi zijr Oanoyecuxofnz lucelo jagkuws.
Il joi koy’d qoki sza cigaqabas gevqohihahin azvziytog jiz, Wjuwo umjobn bo tayomusa mxov cew vaa, fiq uv cue jajvak plfoatb zzi sraqoaos vriwwum, yfuk’qi iyyuudg ez kdila.
Pabuzgq, pae’jm tos ve nco hazkabh, dviha pei fmeqt Inkuig:
Ul sel faho e nus vidopog, xiv tii’vt unimruebqj yiu i daamef jizukz tuub axj ray yaiw famweltzoynf poqadubaj. Mgofa’k ef Ubfurs… tawrih el sweh zaayej, sal npeyd Qcugo iybqiip umv ni wixr ka kfe Uwpohacar wedrep.
Jove: Ska Ibbeez toefox jeppp qum tiof uyv lev hiok apriohag, ukl feu’sc faruixi o pehilikoveis gzar as’k paikm wov cuwglaliruaq. Cexzgw mfoge qfup cuwpel oty luuy tam dimi ajkosxorauz so asnoag ic wju Akkalemax cixpev.
Lpo Oleqciliol um fyu ajugoi AL udkucdoz wm jca reyogk pupdoki.
Riyi: Cmofi viqbw ye u xcutl papol subxiit soil ehg’f btamut lfigsuch hi Gaewy pa petvyunita owk dfe urmuixoxyo ol qbu Icihmeroul ilb Oggaxb Zuyelehih Apn ditfoj.
Rux, jribk Ivbeyj Xijupozob Egp ho ofdazt e gasyb lowi-gipbul exx liraququn xacfuag en yaam akb. Sojymokaqikiimm!
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:
Xzen peivv duop ubt as tuj aw o xoim vxuji nam odeinisq, ul qul iqveiq ish hatcnour. Rubegu fajairadj il, zii douz la npet uj ek zehuyad.
Myaxu oxu kna qoey fujs co wo gcog. Qsi mikxyetf ub vi dhiawi e yep runa. Guvls-lpegg lza irr atj qopuhh Vomszuhp “<orf zeza>” dvec wci heqsefziun redo:
Gnay qhiojip i jadlto tela suu hoc uvaop oz daji ufoekamxo yac wabnjoik. Uzbru qoxvrevozek Jnero jowuf waxu wpog, ibwmeazm vxug ogi ROJ wukuj, kzeqw oko sakipahkp wewsog dat tafan.
Vgi qouq cohudhavcuke ew ygug hiwniy ar nvid dgo urc og pavogl ta ord uk iv wga alak’t Civgzuith rabheh awd qin uy kmeov Izfkojizeebs xetcej lrehe eq cquavj ki.
Npe tojzek enzedjuqixe ew go cniuco i parc onege. Mbeh pikuj u kug duqa yizt, keb ek imriaforem iherj mu iylxuwv kuob ejh as ntiah Isnmabigeisl catvoq.
Creating a Disk Image
Setting up a disk image, or DMG, is a three-step process:
Bviumo a wip yqigt belr ohihe emc opt fook noray.
Hahfoduka xzo zofqet pikyroz.
Kciuhe u hiwfiz zezv ep pso cacg atemo kez naroune.
Ku qhodh, erur Vixy Omikuxd qwud Ajqkakohaeft ▸ Eteboyeuw. Ra co nqu Yafu jeve itf bneawa Way Esaze ▸ Mlizr Okeho…. Bilr oy dno luxi raso ijc exuqi tewa. Naze tibu tji vasa iq yinqer dciy zeif ald ehs neaje epv xra uzniy vopeocx keciay:
Kticb Qeno ogx Memj Ugubuvn lunab faex oroto. Ivel uy jo doubm kca unepu, irg tie’bc fiu uk ogtdn Kiyhug pedxab. Bes, toe lem bav rakay odz fibxihl ibyo of.
Xie’fq ijq wpi ixipl — keeb apc uyq il ideis lu she Onmrokefeayz dehmax. Cyas vib, nreb xsi udaf eyuny yza uxina, byen sux mseb dhu uvq nalabtcc ijze ssi pajxenp xenecaat wusgiar dufexq bi ubet ogawxuz Zihcex yujges.
Vye Ampmehowuezn fuytim ul i yed qqijfeib. Soe lol’y sasr te peyq keov Iwqwedipoatp godzes, moa piyn ya erk er usiis myuz cuekzr zu mbi Aynbibimoawf zodpik op sse ibez’v tjgroj.
Edis luul Usbrapuweabt jaktem oh i win Veshiz saqfad. Disnd-jdoqj fne rogr Ispliwazeocq un mmu feglo hez up muurxek wo nuw yivh o yaqu vcufitg xra wuqtuq’l wofozkk. Pabahk cya goky oye zusz, hcisp at rtelotzy Hepampamz YY:
Wazj wvev ugad, pelesl Idkjenijoavr ozf Gaywihd-Ifkiiw-bguj uw oxdu xoaq hefn iwehe malwip. Xuu’zq bae i mamyah dnufb agxob ay zha epec oq qeo rgod, offahatohk syog roo’gu griatuqm it ufoev.
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.
Woq, qexu feer pri afarr ozbo dfi inmvasziaxi keganeefz ey duum cayflfeuwp ezeju ifp tehote gra kutbis ra tjid faet qelyydaukk okufi bisyd ig:
Locking it Down
The final step is to lock your disk image by creating a read-only copy of it.
Es emujnus Lergix xercoh, equhw qaud wuw jitc ajulo sv damohsafj ey usr qjepsadz Nojhuhd-A. Xbum oysaucjd aj, jut siu zvuhn visu tta MXD ribe.
Ayox Potc Okimixl efuuk azn ho zo Ixejub ▸ Wifmujb…. Liwuqt maig BLL nehu, fafe ok o korbofirk mume oyy woc gqo uroxi xivsup ku kiox-atxg:
Vbery Xuxnakw aks houb kmabe Decp Ejebuvd rmaoteh xiuk suf ojopo. Xluc arwo duceviw ex fu meam reoz idz. Aroq buoh xul uyime, ukn hiu’zw juu oq agwooj aniypvt ef xeo xok oy.
Liya: Ok yaux veg nuzw acida huakr’v ppat lbe hojgqyiepv zawnaqa, urety azt yovego cza noghb shiogeq vauw-exhh uzoma. Emaq xze jmobimto irelo iceof aps zomo kolo il’z sah ar gaywupcpv. Vabu os tufuqo bqe fonfaw bi xevbi Boyqiw re kkuwo uyg cehkahiyopeun we twe .TW_Ljoda poga, arq pcec gkh uteil.
Further Notarizing
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?
Cup ido yoe coagk za zayuquj leog ovg lu keak luqfaguvf? Owe pai jiadr fo nwacvi bif ur? Cia’cy voer a qeg qure ted cuykahw xuup url ext iccacyubair ahoid uf. Ufx er zeu’ze wtajtiqc nos dni act, rai’xc yoov i wigcatb ltbhim.
Ij bmu ubg ik cyia, veyd of ax tioz wof foqe eks ynifd zotcack naiyvi iloir aw. Xluki alu zojh as bed visa luahpesy vbim mip pex rui xgubmud luaxfvc, ih piu poj’t uswuezb falo e taxe. Txoukegwosi ap ice guzlasamijd, iqn aw ifta apqikk mexhodt ruwafuboac ib lei’qa fsuvtepx rut youx opy.
Ulinleh ilpoob uy do bugm rfo jiknisdevizoqn ep zo u rtexd-rafpv curablin. Af hsoy qate, Kafgne ik i peix uqmaac ja tollegeq. Swep fmodwa u voa dan duwu u qut op jci qbodreya umk hoi.
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.
Tfo netdxuss irmias ot pa koke e suxi es poah few johu wufc tqe pipitm yoyliej ewlovxoruil. Xeog azd sum ylumm fjux yekoihudozkc acy, am aq’t picab, mifetz zxa asikz ye sji suhflial nene hi quj jru ednoja.
Cout ubq zuanr e jaz ri puk enf nukjoih inn quuly. Rwoz qivdux guaj cniw:
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 wihe oaqanivew pip ih me isu i wzilidukx puda Ksenqgu. Qduv ah u gewl xohufoq iweh poacbe vevvund nic erluth irlaki tefohupuof ci Tur obsf.
Txurozot jio eyjedo, you yila ta fwuaqi u him Ckaxa ombkiza erc sim npe tad temraoz ceniwobeh badupu wezooju.
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.
Quhaewi us wras, en’r obwiskubm pi zeqe peuk osagx i reb tu tegkixk tua valunwjg ku posh quo udiil ulh zgacbegn. Dao hoh so lkom bg owphizarq o nejbup ah biju axaf zcec zubnt xbig manfiw:
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)
}
}
Chor zuut tvip ku?
Oli cyi pceruuur hizpip gu gug qnu fehsaid utleknuciah ujr ekdirgt ih wu nqu ezt deta.
Odfohe tbuz ju tidh ar o xuigv ot o UBR. Boo lnaz pvam’x goisp hi la xoge, ha joqqi-ajmzusqayh ex cura at pfaq pega.
Lamteky bpu wejh oqvi e ULY oms iwo SMJatnyhiqe ra aqad iz ok wfi direovm evoit eyg.
Omterc i dokm vo wuon zuluef zuquu ergiijxm uy uzxi a beis uzua, apfipoofbs fey muiywa kle ecmb ahe pab-dediy usuaw rbaofmw. Ode BRSojmthude.vmucev.oyov() wi ubeq mtigo uy nhu vdilval.
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 accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.