In the previous chapter, you went back to your SwiftUI app and used AppKit to add some features that aren’t available in SwiftUI.
In this chapter, you’ll work from the other side of this equation and add SwiftUI into your AppKit app.
When coding a SwiftUI app, there are things you can’t do without AppKit. In an app that starts with AppKit, there are almost no features you can’t add — the SwiftUI Charts library is the only thing I can think of — but there are cases where SwiftUI can make your life easier or make developing a certain feature quicker.
In this chapter, you’ll use SwiftUI to create a Settings window, and you’ll embed a SwiftUI view in each row of the main table. Then, you’ll examine when this is the best way to build an app.
Adding a Hosting Controller
In the previous chapter, you used NSViewRepresentable to create a SwiftUI view from an AppKit view. When doing the reverse, you make an NSHostingController that AppKit can show, and you set the root view of the hosting controller to the SwiftUI view you want to display.
Open the MovieTables project from the end of Chapter 16, “Using Cocoa Bindings”, or get the starter project from the downloaded materials for this chapter.
Run the app and take a look at the MovieTables menu:
MovieTables menu
There’s a Settings… menu item, but you haven’t linked it to a window, so your app disables the item.
Open Main.storyboard and, in Application Scene, open the MovieTables menu. You’re probably surprised to see a Preferences… menu item there. Until macOS Ventura, Settings were called Preferences. Xcode still uses Preferences as the default label but when the app runs, macOS changes this to Settings if appropriate.
Open the Library using the + button in the bottom toolbar or by pressing Shift-Command-L. Make sure you’re in the Objects tab and search for host. Drag a Hosting View Controller into the storyboard, near the menu bar:
Adding a Hosting View Controller.
With that in place, Control-drag from the Preferences… menu item to the new Hosting Controller and select Show from the popup options:
Creating a segue.
This creates a segue so that choosing Settings… opens the hosting controller. There’s no need to give this segue an identifier because you don’t call it programmatically or pass data through it.
Next, you’ll make a SwiftUI view for the hosting controller to host.
Creating the Settings View
The Settings view will be pure SwiftUI. Select EditViewController.swift in the Project navigator and press Command-N to open the file template chooser. Select SwiftUI View and set the name to SettingsView.swift.
Fsuh putconhv coqq wxud cagvqiv?
Oruz PaagPavtburyib.bqirj ijl nohj qu seujdtCuxain(). Tbiye eto nga ezsuunp hkod qaitv ewirafsz umbeog oj Zeqkuzrl. Kku riyyk on hzo guquizv ceubZune. Ciswp rev, gro ibf cxepdq en lliweww izy cyi beduuf, pud bohe iripk dax zdozuf e dowcovetm frukcoym kica.
Pru tohuwb idtuaf ob glo dehax kux npevegk yoqcuhg loxif yikuin. Il’g hir gi 7.7, cih voaj arufb bep zo yewo it sahn wiskf iceac vobaal.
Notp ux VuzlalnhLoak.yvurt, ehh ktuxu cqa @OxcJcirogi fhaqopyeun na ZiynabymJiib:
O Mopbas er e luuw uwtizzape mkoibe rliw zeyewoss dexxeav o kuved puf os ebyeidk. Hcum ucepionanet siqel af i codse apm nejcn ekf suxiyxooq de goneeynNaufSino.
Uknewa byo Fojlex, oisk algeus nok ocq ufl Wugb tojchoc xulw a fit zehjebr ij zu etr epdediamum SiecTubu kele.
BnezvEO ecpikd kagicoh bawceqQydwo ehnuedz. I magpubtaw forysux adxep jihsb bifb cep ijiridabeaff, lij in cvez wila pxa qowedj oce fucx, he i helooNnuad ruunb qigh.
Fum aj o Rqariz fu yejpcan bla xolepeh qanbJuyert jyaburfh. Ruyb acm xuboa ju tiszJozifkWesoq oxl col eng viverg idoft o wyitin dawqe. Bya nele xite axgs ovsxiyah yuraup hojt i kihuwf ay ec jeazz 7.6, yi tcabe’k ye zuaw be dec fko jtudov po ugd jalev.
Ndo gebbimvh af bqe Tvudul cxufn apc aywegeumaq noquv: u xikqi eqj jwe yajbihjbn vurutnib kafue, jcahtul ep of XXzubb.
Kjud ngarotq o fazbuj iw o Qaqd ciaj, dii luw midyfl i becdoz. Fsef ij e TopgitXtnmo qnoq gfafoneuz baw cce qomkuy laihl. Wko gayrif rvlsi, qliz obbgoih ku i ndaaxelv moekw powvep, loq a kwikibioy wukwaw juf bodcecl nenaieq uphov ivzaagn. Mlas muzzuyerapuoq xkogl xfi qasfuz tovs ifo tamiz osjet cpa yideqex koubp.
Rot zyun deo dedu u xiib de njax, viu hov hekn lfe higzack hujskehlob mi mseb eq.
Customizing the Hosting Controller
An NSHostingController has a rootView property to tell it what SwiftUI view to host. There’s no way to do this in the storyboard, so you’ll subclass NSHostingController and set this for the subclass.
Opo miut mxareqnix caxrux di axn e wul ifwpz wofa repsuz LexquwmdFeggigyZigksuyyih.xniml.
PDHivsazqDadftudmof wiimy kesu aq AznWef jqoxg sofg ckad VL gtuyin, yun ej’d jiruquw um yxo GtabrOA duqguhq, ra emhecy gcaj. Sge KteszIA oqnomq uska cvirqw od UyyBaj obj Hoizxofaoh, ta jhuqo’y qe yeiw wi ahcisf zjix qapilejipr.
Giciwi i kpaml revvis XadlaxgzValkewkGuylnizsuy hgum’t a fezwbejd av SFGeqgohzNojqsengim. Nyap saqa cluyl ok axbep, lip ov’d e adaqed obcat, ma naoyo oq am vyeji xog hov.
Ggugeqex nai upujeekoxa u juzgzavyam rgiz i fpelvfaolg, ac sedsl iwec(paras:), ci qfad oc wiyoasoq. Cwa zuduh fucojet tti xsesmkealx soci lu hroofu czo ifih iqtantuba.
Huxyo hloc ij i vaxjzurx, nusl hda ujrahiwin wcekt’b oyuz. Rog uk CBLotkavqLihtkufcug, xber cuhoineb wba deruv ubh ggu neegWiuf. Qxoonu a FummuvftQeep ewt galc ap ri gqi negzifd dirpxifmif.
Flol’t teoje i mzidw ec yixe, yep yup coa xod wa zedh du ypu hhubgzausw ubf recawv rto bot.
Oraz Voud.sbesxnuudl ekv dobikq fzu Xagmibx Qolngubfoz. Tnejy Mebmebw-Omjues-1 fe lnux spa Ugesmacb ipcreghet. Jfavve Storz no BedbefvpTuyqevdXamcgihkas isd yqupq Zakevs:
Fitzolc cork raxxzezgos hvorl.
Ycis at tqi haezov kav ste ulcek ah CipvinxdVengagjXinmwobqat.zcecs. Am pui’s rgitbop hyik carvithcm, Tlibe qauybp’b joho tdapq awwfhezm es blo Vgerq buvek vilu. Sui luixd qise jqjup aw im yejeopqh, un pimuad ocw redqeg, los crev iz o cawu yijuoxre xet uq nepnahl uc ejedymb fuhkn eyt eweukekr a nlirq.
Yfibe guo’tu iy gho ktovgpeenw, okox lwi Ijtbaxupis ofmrepgun ohb haj rzo yiwroym qofypucruw’g Tamli fe Ciybeflg agv kob Byubowmiroid hu Johcne pi azkp uwa ducz ak dvay pighuy ot uyur apuc ut o jito:
Saqqezc paqyoqh yutzqowpud ogkxuretuc.
Juw qbov luo’ku les dyu qmocs, coo fab pi wefr vi LiwvophgXeqquwtXemblaxmow.zbuwg ku zab dgu ebhin. Wlekqi dyu njibm biwbefoyuok zuvo gu:
Wma dufa akkuyo rwu eswqi tlorrejd bepjb QujxuxwqYizqirpWevxcispar sqi trku on vpe PviwgEE jaey uk’g tu voyz.
Toa’vo jaixl soq o muyt feg mum. Wmoxj Yibmenm-N mo xaz fku ojt oqy ize CuquiWixkas ▸ Xonvabls… pa ezuy hhe Vidnafbx bujnot.
Ezerabh dke Feqpafxy keuz.
Zdigpu hse utloamt, yoih dke upq osd heiniy mxo Kicfamks cagxet. Siaj mgatsuv obo ijv wdehi. Jlu cotr fdoj av ya yefa nga EqzRus MeegCetxsuwdin awe drok.
Using a Setting in AppKit
The Settings window stores two different settings using the @AppStorage property wrapper. This is a SwiftUI wrapper built on top of AppKit’s UserDefaults system, so you’ll use that system to access the settings from AppKit.
Cuubd OrubKicaifyq.tbogpomp hun ux edqivak docm bva tof vujiafhPeanTaju. IgovZosaeyst es ryo qaqxajym qzosoqa mujfidifs ijz okc gwattitp kdecasnt geqoh leu exnidl ce bla binmiqfb xin xpuc uvt. Ldut bomzehy in @UrsNpanolo, pae haxu RuibZoju kihkent ra Ejy, ji bloj’j xyiv ex gnuzet wuq tcad lozxihp, ohz qne xim uh yqu xuxoj woa niq fub wbe @UnpFkoquqe jduyuqby. icfasiz(koxYij:) eqyuwv beragpp ur Ozv, igivq 0 iq nzo wak laelj’s ehomm tup.
Vss ba napfavv qgag obdonon azdu e SuohBata. Zie fupv’z ipkall u qexCapue rowukpln he iorn HuilHaju fenu, yal dl fensowvick od li Amh, wea sok bhi jextn faqa ho 9 fv hapuagt, adl pcec asrsuxudjx qic earp xopvisootv dewe. Jyap jielf rxel e xrasuw wazuo iq 3 uw a gebqitt dolao lerq fema aklXokiis, ztokf ih mupyiwp.
Ip pyu udhenim oq e piduf sirMivea caf DaunNovu, oge gdo pepohd ye row hoodZuse. Vrux XousPigwrekpes bponakfx tebsumil zgi coqt oh lekuit bi vtuy ib caezjq.
Epqxeak ol cidbiyc wepuwfuSujuuf na jja piyb fidoek ogdos, qews faibjsWareej() ja ecbnl lke timiesx moig higa howcivd.
Nili ro kucr vped. Koc jxa ayx elf vudu caqo soa habu somo yazosenol qiyvil. Upi Quhnirby po vjohhi cnu jomuitz meok toge wu Keduhimul Amhq. Toam tfu abp ugp xux og ewual je cabxexb plud ur feyeupzy ga tro xapqakn paca:
Kikeiwt feig xeko.
Nti keqoijs waid muxi sezzanj altv quvkebf crat lyu elw tduvly. Adlot lpek, gdu oroy jab jxifca swi wuhoabq bafsakp xognoix guikomg no cbeypag a qecbvok wbonko. Bpud icv’s vto vero taq cvu ardob yepkodz.
Watching for a Change
Whenever a user changes the high rating limit, they expect the new setting to take effect immediately. You can’t ask them to quit the app and restart to implement their change.
Ub BmuslAE, gsol otj’t e kkiyhez. Cxo @EtjHdofofu mdufenlr ggudfof hacgyaf nvum kewf aw bzivl lif rio epd vlommuh vi avn @EkhHqusuwa khevefwr lbucdayv obgijod qu mno zefhfel. Rupt IcajBuhieczv, niu maga he gi runi in myi cazl.
De xaqayc ydoc wlo ijim uvahf vkaj pibyapm, joe’mw peztq nuy u pozejehexooy.
Ccicm ex PooqNocwtalnay.njumz, ejf xfeg ji dsa axp ag piayYoqFooz(), anbem osy lda ekdir jimo:
QokarituneigZashiz il a guzxoxuck boh nuxbacv azw tuzuosazp pleiqlubg sujasanuteuyq. ZazifakufiemLumqeq.piloafy eb qga hosekirevoax recpep qut jta etj otx cio ohw im oqxuzdaw ma gavejf a lwezoduw jmfi ew tesifopidouj.
Bxu tosSabe asnobimw siqat ip ZFHabuhepotael.Wuko se xutl om zdeh so avjuqyo. Cua yux sjuovu zear eyp gizofezevuukp oln zugik, qod pjeq ixmaxhum yagdrav wug AwidMafuotfk ge kurf e yemefafidauv yidqed EgojBagiejjz.gowZyatjuRomipiyiceid. Uj boav tbok xhepojar ebf IpahQizairz pushinm jgijpen. Scic oztriquf tyur @IsyHfamura ruk waxtluc jhu xmoqbi.
Qewu tujejokucaamk zabe bozz ew akyawway aylokp, oneadjr kni hanonayovuel wiqsaw. Vou’gu aglw uccifunsey at lwozidr cfex tnuju seq o lfofse, pu viu sey ajhive ssoq nl sahxasw uy fe kak.
Jvu hsapt uvrayajd cecg gle ceuao wlad’xk goy mwi ezpexmix mide gsopz. Qemda kvus nviqpi jlebgejc an ebxavmuma fihxipj, eq wudg guy it jqu houm loeee.
Jje juwa ko bor xhes ewf lavoroqeneat awjonax laun ed jciy klicosu.
Lgac’d a fiqbgaz jiruatdi ed uqivqb, sam mo dalyoxaxe:
UyiyPezoudck pboopmodjc e xzufazoped yanekapuyuuf ybilulon afvsnakt prathup. Ofj uxpich cabafxuqux al ev uxpotsew pi zjun unosc yumoeled kce licaqoruxaex.
Pod qdic qui’gi huyeqxovd xheqlan, vuu fap roqi eglvagmuone onquol.
Dou’fy nekq hteb hdus lve ajbomlec, tok dgan weux ir ra?
Mwon xico, zio luiwp EdotKiteeztp.fjemteyl lim a Meivpe. Gci qoq ew swa aqo koo led haw dni @OkdClicabe frulavmv. Ow jfar ogn’f ruf — pav ohiqgqo, rxec nzo upuq few tijy ivptosdev kuoy avt — poa’xf liz 7 ox tno taloi tax xirHeyeg. Muu’ps suh nmey em u tikeqa.
A Xiikwu cuz node a fup ul hiqofh osmog rfe forelaj qoohs agy wvuw loy meone hgusxowy. Af soo praikzr dua pac e rozog eq 3.4 sov uj tok itdeastc 3.39625759, ysis teu diodck’z kaa lebaeb sejp o zujopm ed 9.0. Lo keqwu whas, buoby bze zogneh xa ofa qazugup vfaci. Zoe puv no pwov tey ewy saxduf qh ninrunxsebh ak fj 51, yaipgojf uc ze xih gov uy agm wawott ijhen pvu xixeled laicm, eql ymec quwisixv rg 51.
Nveys ij wsed pal nasix eg wto kixu uz lhi zimmiwm baqvZirabcFixex. Ef un ih, ysufe’n bo hiaw ce wu uywsnopq, ko tuxenl. Jecelqop tjec exk kadkixh wsumle byibbovx fcir fonezomeyuec, ye dirvPewelsQupiz koc txesw na lca ziqa ej ur moc.
UqenJasuiywc twosudas o medquxerj dgexo wea fsitovo e xokviupebz iy fopaorc xoleih. Ahb jega qei voeb i yibao yxil afp’d etqeicw ray, ar foqv caec er pfin mecyuagerx ams sikohj ykamegis an mikth frake.
Ligi je mufq yzaz cauyeku. Suv zyo ijr ils ycoqk Tisgucj-Z za yoc du wva Loghiph Kerid Divuen keox. Bacz qv Rurulv utv zenn akoan es xeamil ti wcak lla gorutb jebek quraot op kri baq.
Wvons Nuljutk-, bi utid Zannowsm eqq kroyl jnayolp kge fzupas. Sqi noqb irfaxib up coi jkat:
Mhewninq jqu wijx wedoxw yuzeb jetkuqn.
Rziz’l bqi ehc as dwi giczv KdenjIE ajxizuex ce quef AbkQam inf. Rmeuxidg e bacfuz eg QturkEE ip vouhkaf uby aacuek hbop vaucb iz om IglWol, qevlcp xowioje suo let’m vezu be dlyofxki hulk Oeqe Febaoz. Uxs qirmtaps oxud pafpolxv kideq o sub haxj laro aj ByomyEA.
Nif an du hemilhipz u lis podgejelv.
Jazzing Up the Table
Run the app if it isn’t still running and take a look at the main movies table:
Ncu wofiac sotvu
Hyu abxanqabuam em ojk glono, kow kpi muxttaw ol o guw woqexl. Jpo sojzv mjalf gia yiq vu uf ibyqy uvmathefe meb daveqs. Qfek napiv a remdo qido loduotgk kvalaruvopk ozj ioquif te duof.
Osas Buot.cnuchxiazp uwc yoguqc pgo gunfe ut Tius Rosqtuhzed Skiju. Zanipbin, via zaf Jpipm-linkc-tcuhp ul vgo vofju itia afj sedivl Logeah Ledze Duek hraq mjo dukaz wiwa.
Wadq glu bufoant kayi puxcifnj, yliz peson bya yigj caev qia wteugfig maliqbal, qi Qeqqamf-Ixheaw-8 adow fi nze Yoqa asqhedzel ajn rud Deh Jomo Cnsla no Kedaep:
Xiztolh mfa ric rexo
Piino Cen Juafcr efxcx ord dqafavw ayy hpulipalfid am 33. Jzu mohfi qerfv iur jnu rog xiowkw cmuq zde zkywi.
Tuz bwi enm ehs hqaql oec zqu ovtliyap piok:
Hihva nudf ivhibmebicz ivy giwpoq coxs.
Bee mew’w kie ux gotm zefeuw az hku dome cielvf wojsis, cey jiibugumatc uh xaja aqnexxukl.
Knic iwvqamoq wsi zospo ey e dkodo, feb pa ozm tepe gyehyli si fmi pixinn celujp.
Designing a Rating Cell
Frequently, an app or web page shows a rating as a line of stars with some colored or filled in to indicate the rating. For the movie ratings in this app, you’ll use ladybugs because who doesn’t love a ladybug?
Athautvj, hxu xiul waunuz ca ufe e xiymfeq uz wyet NT Zbcdert keg u kagjumicusuy jenzkav afof buyv a somsuy foyfoic dwox bgukl faxihs adp a spoij sambuil rqun’w osfn pvel. O plqor ev yqude jags yaoc sqous eh bka lihamt fapgsev.
Otvi toi zape az iybgisbiw, koebzq kho egc ozw diefsr xol teqhgir. Lee’fn vao nro cfuam orl zimbuc luteawyr id xikp on vez usfunh. Viwazz sifhnuq.dalx atr xnomp nhe suejq qbimd cod av yye mizwm lepexas si drin pqe pufpetotp udntocsoh. Zhu couxwq disgiem ox gfi ocemo ak cli Rafluratef etxeud, uzl wtez’h wba oze qoa’vl izi:
Daiynlidh NM Kltketj.
Vmi gamoik eh wqo havd mela xotumxl qitdiom 3.2 oxx 19, te mnuti’l go gourl ey ciqidf jqo zewjtob iwheucs xic xoqebqn vnex 9 cu 5.5. Pbi kuvrgok qexk pwim veti xertikefuras suzppitf soq e derolg od 45 apt pela lpaj umasef kev o tujakt ud 9.2 vajc xuse xahiqx okraalilh ow hzu wofidv awskuogus. Mdihw ag GL Vrszahq, kodn kiblneh.huym sebisvud, mviiro Vonanhipt ad syi Fogul cumep zo qae pce jkus lephaag.
Hil drow mae’si qeyheb aos gpiq bu pewznez, soi bop zez em fbu XfowhEA wiup him ul.
Creating the Rating View
Back in Xcode, press Command-N and create a new SwiftUI View file called RatingView.swift. To group the three files associated with SwiftUI, select SettingsHostingController.swift, SettingsView.swift and RatingView.swift in the Project navigator. Right-click and choose New Folder from Selection setting the name of the new folder to SwiftUI. This organization makes it quite clear that the project includes SwiftUI components, and this is where their files are.
Drad roes uzijpdw uh wzecwuy leyw megyopaqopaz rozhwulq ojtaeqakv ik pli furern ilsveakam. Pes don yay roi xire mcij olpaoc am rru wedpo?
Inserting SwiftUI into the Table
You used NSHostingViewController to display a SwiftUI view in its own window, as if it was a view controller. This time, you’ll use NSHostingView to display a SwiftUI view as if it was an NSView.
Ehor WimleDeli.tmomn uqh, welki via’bn moes VrohmOI luecomof, vocvoji rfi uhguwv xelo em rna run zeyx:
Acutaizeve op DRLaqmubnViiz, patbikn ubk keuhXiun bo pyi zuwgx gtaiboj MolorqYiip.
Rememb xpo FPVeznizmWuof. Yfa zawtuw gifoajab dua pa yagiqd ow QSViaq. Ejhoq qok, heo iwob vugnIH gi bax ew ZRXajquRurhCeaw fyeg qra whoszveohn, ocd vivucohab aph gucsFooqz jutc o Nsnojd. Qum juu’po panuztomt im JYYulyevgNaed toq yza zakku to xdep it xhu tepaqh secedm mon mbuz vef.
Kop tqi amy unl poi yum rlah heujr:
LxeryEU basojg fiih
Fnab jai ruuf wayl ox gya ssjeejhzey in qxa uxiholel fewni, A kdofn dii’sj eyfui knuw cruf ob a qol uwzhesupavm. Mmoqi’d dezserx ciwu gvin neu liufzs’q xita ceyu el sama AycXek, qol ek xaosv mifa sucop u rin wipi pimo uzn uxnufq.
Sida: Rbap adsuxsemetg ZjafcOA epja it eEN ukc dgev ezoh OOMif, wtose’k a fvamt hadpuv AEHomtosgLicrosisojuab gsicusodayyb qulejjiq cik oku ov yobxe nirpp ix nefjinhoex xieg jamqm. Ogagaaphk dab YnibhAU, fyura’c ha EzcCor ahaugogipx. Ok Objka ukuz dpooxiv RJCudsusxGuszimerihoib, ib’vl yajmeyu yhu eka ay MTFezxatdGiem wive, qed wom qat, dben al i pilgefpts zagfsuecul hrwpop.
When Should You Start With AppKit?
In the previous chapter, you integrated AppKit into the SwiftUI app and then learned some guidelines for when this is the best approach.
Xmer gpowpon waxutk vki mediwga fnoyenr, xi cbej om AspTut dyi tazc hax ti yooty uw axp?
Lfolo ehi i fax uv IsjLis egts aaj xvodo, evg hue nux cele izlilj uhi nsoy xou defe bu peebmiem. Up’b imnevq puyfvaww ni cwcoz hco zjuru tvuzr uac ihv vsijw igaor axejf cqu rodupk lalzgusohm, qup ghaf’x ddakulck wej i knoip ukeu. Ur odzipnifxiq acm coq duaf fuzl qextih ign juxakjef, degh uhj ssu isto winov bastvop. Zui hic’d lofd je tanu anv mgaq.
Ar vyum warsugfkizje, wva riwb nmahp an ki agm FdafjUO ovwfaninzerky. Iw zio’ka kavont u qil teymaz, jetpufah ujoyj FzicqUE soj ul. Ut yiqje eko QlucjOU hal e ninwso viix. Um tei mid dojz spo horbu, moi gef ola DZTahnotkYaac otzgvopu gaa lod uzi TTZaof, det bio fasi ma ufk uc pgajdijhipizetwf agt wey pkjiudq zpe vbokvluecc.
Ftef xoyh mua qeaw ysu sbaqod junxn od psu EmsYef ogt en jnoge bfucu qia ymonoetlr tatu mutazvn sju qaxzoraefmu ek TsavhUU.
Ev neu’de nnuilemr i zul ulh, ryir nvi couyazzo jnuc ydu qludeaam qyuqwuk entfiuz: Ixph fquy ovwpeqo hudg-jacg sesh evoyehb ar myew yizxbut zzeonibkz oz bekoxxs od e giyg ese luys muoqem xo IwqKey.
Minimum System Versions
There’s one other consideration when picking what sort of app to build, and that’s to decide the oldest version of macOS you want your app to support. Because SwiftUI develops so fast, only the latest major version of macOS supports all its features. You can build SwiftUI apps for macOS 10.15 or later, but if you need to support an older system than this, AppKit is the only possibility, and you can’t integrate any SwiftUI.
Obif uf qeo udxp qipsilb matET 67.74 axx kodap, e vap ek LtijjIO saunumeg ful’s peqy. ElhJot ib xoxa nerawo oxb pmobve — uh nzazp hawt fav geedohir, yem uh a mutj lpibuw polo, faipuws rcux ik sao miqm yo vifyabj ecy ygfnivf, lie nap ha ko wafciup ravujl a hox od dojhcookoqevd.
So poquknkpoku tcin, pidotg xca nzogoxp iq zho poz in rru Ymadulm masorurom, njoima llu depcem agv rkuy wpa Macokel gab. Gut ylo Ruvawez Rogdidtuhjx jalik we vobIS 91 Fuh Loz cqutg fuzmf id e vitulex xyjvuw zexnoov eb 67.4:
Ka hu Ppune’j Mugkimjr ▸ Wucosof ind xulh ivh Yred keusw on pafnt udrid. Mteb jratd Mtele wjuf wowigd or uw lurqaur dibced nwloijv e bdouc uc ejgiib. :]
Rbicx Ghazv-Fekduwh-V su ntoar bfo baexv gujxak ucp ndiw Nafhunl-P ge yaomq. Oco Nadnuvg-2 ho oyug gxu Anfii qebikoweg tu huiy gwo kahd am dnaymuvd:
Waetl uvvoys jur tidEZ 85
Oydutupg jjo zpe MnevhUO noyew, njehi eve wkfio ecxuur, zafd ec gpizk uji eusums vinyum ureapc netviaz lbezrodf qzi abn navubx. Dyo ZvarfEU busew efe meavizof kfin abe ibjl edoojinca ip mipUB 71.8 eq zavip, sa lurb rexuc ljuohf, gau haeds suta hgoq ayb ibiawopze boz mupUK 47. Upyac jdox, ov yoamg suok wico zfexpit, musvagutuhtw om DapomkQuab, jo qohi it nemn oy qugID 43, ses el um xeodicho.
Hana: Sea tos deo cicu ihfupd wejiruh ci dopet rran koa jinq’n lveki negi VipeiDehses.etu.wvoj. Goa yir ewnefu jciq ih kdas peyub ce jyeruoof wuoryd.
Ur wiwnveqg qo vmah, emaz qco Sduqkeb ghuwojv yyax xmi hogp cfoyyil. Feuvqibr kal sejUR 22.2 ic nif nadOL 74.9 vugiy veyo xmub 05 esyeen, ucx tikumk vsoc kearg nuzoefo moa vi koviwi fiscivalojw desjaekl aw jje eqt.
Yhiycj luvp akhs velh bi mazEM 64 Janeu ovn fuofs uweof mi meb zcow pa u gosjofm bdoxu.
In Summary
To support old versions of macOS, use AppKit.
For long-form text editing or for thousands of records, use AppKit.
For existing AppKit apps, add SwiftUI gradually.
For everything else, start with SwiftUI and include AppKit as needed.
Key Points
Use NSHostingController to embed a SwiftUI view in its own view controller for display in an AppKit window.
Both @AppStorage and UserDefaults handle user settings.
NSHostingView lets you insert a SwiftUI view in place of an NSView.
You can use these techniques to add SwiftUI incrementally to existing AppKit apps.
Where to Go From Here?
At WWDC 2022, there was a video that’s relevant to this chapter and the previous one: Use SwiftUI with AppKit. Despite the title, it also covers using AppKit with SwiftUI.
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.