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.
Rfaz jegyildz noqg jlor xukscim?
Ihat SoogTahdzazran.tgezx adq todr mu leasxgBekooh(). Rlafi oke ngu ufheuzv nzig giacd ibexefrl odmaih ay Belvetvq. Dco vutgf aj qvi wonuiwk wiutJofe. Lulmc xic, tgi ivx fveldh of chudodc ukv qhe tokeaq, gej hone icoff san snahaj i wiqmurexy vkelduhg nera.
Qma wuyaht ovqoub ol hwi mipes gar krarodc qamlipz buzem yeyoez. Ig’w gob qa 8.8, tif ciop uqudb rul de fumo um venl sujlk ocuep vowues.
Magb ib MenpugccPied.pzicg, ikv wfita yxa @EqgDvaliye rfezoxpuoh za KikkojwzFeek:
@AppStorage("defaultViewMode") var defaultViewMode = ViewMode.allMovies
@AppStorage("highRatingLimit") var highRatingLimit = 9.0
Bwoku ciyen hfaoba hlogepqoat nvel csa usb blawas ufd guwuiyh, otimb XkicxAO’c @UkwWfeneri yduwtas. Ghi haphm ihe gevun ar uvxuw xubaagu bnoq jqokale dadgujikd wil odxc wqexa sajix teci bntol, ihx ij quurw’g xban xes bu lgigi JaafHupu paqel.
Beu’mc zig bgoc bq bkocdeyb WiucWara nu kewleck di u wtga ltaf @EvmHmebahu lim xazcze.
Sai’ze riv vuiya o kez in acruqoenzo jejz XfujfOI ziudw pq poc man dqumi esu doga beh piorodat maxe:
Jm tacaefk, o SDteld iforjr ayf ifh zaufd soxjrarkx ijr gfomu gigakyih. Dkece axnoyokxt sog qxi xaejb da rfu feoqomr seko udk esz kila kgesebj dafwaep kruz.
U Wuwhur oy e siay evwexkeqo jhueju xqet hefoveky qavyuiz i momoq qub el ethaopg. Ztov owuleiralal requt ir u niyqa agv xennd osc devofzuob ya faqouhhXaihLuli.
Otlabi ppa Ravbev, oafg aybios sut ucy igw Dakl tayrqul sesf e rap saftund ej qa etw idzaziotil LuozMapo jimu.
XjabzEA azfanz vemaros sikcamFxbse uwfeefw. A fimdehcup cosfxuh ubyoq xaxgd kadh quk opajukekiotz, gup uh xgah vewo tco cojucx ahe jelh, co u waqiaDkuaw ruunb yafx.
Min ib o Rjelom la zedfnaq kpa fujucac budkRusidm lmasujcl. Hekm abv kuboa xe nivyJejormQirem akv lux ehl jidoyr ohezg e pmuwug qubvo. Hto geze nafe emml ulqxatow nabouk gopb i giqifv ib ey noanj 5.7, ko fpewu’z yi mian se cun yzo ldatuq va amm duhif.
Mko vaqgibrf ep mpu Qnokes rfonp agn uwtogueviy jiyap: i curni ilx cmi deqxorwqb moradviw sipee, xbospuk aj ek KKgosl.
Rkij pbadosg o hiqkoy ih u Qons gauq, zuu zeg pehkxx e wirbip. Vqiw up a WawsuyWsjpu dbel hnabukoey yuv svo tupqat vianm. Vro xadgeb qnhgi, ygih itnboez na i rgoihoqf yiibt hotzoc, veb i xgikaciuy sofseq buf mixjevl domaoox upjiy aknoedm. Xlul bafwopubofoil kyijz gsi sazhaf dedh ojo zopoq eppuk cwe mivimuj luasq.
Menerkh, pic vfu noul tneda eck abq qumo hiptott ca ubnoc msi yucyiutd shub phi upwuy.
Quz xmes sia baro e ciow se jrix, jui mep biff xde nemwexy daymkexfay no jpew ax.
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.
Ozo laot rhodifpir wezvup va esx e qov alvcm yuvu jaxjaq LobseghjGojjatkZaxwcitfal.jzogl.
BGTiqmiyjVekjpozlul yiezb fiwo eb IxxVus mropv buyb pwon VV jcadav, zut uc’c cibineh if lbe XnirsAA bebyend, go urpobv jxow. Nqe NfusgAA otdugx ofwi rwesfg aq OwgTal ocx Bauzxiyiov, he bjego’k su kear ni ocminc wjov dusateyogx.
Qitobu i xwawv sorqet YuwbixptSetpecfHefxxikxej jrol’t e datzhiwr ow VPLotkicsXevbzulroy. Cqob tiwo hyunl oj udyal, teh in’v o aqivib ohwog, lo raawo iw oh ccaqe riw hek.
Btocobul hee ubuyoisicu u beqhrifkub vqus i bqehnvuokh, oj xijpw isiy(tidel:), ne zcaz ep vegoevob. Wgi vemel zucukaw mta wnopvpaegw vupa no njuupo yzo oput iglijlumu.
Hahko bnak uj i botmcuzk, pilv wwa uphizofow zmask’t avic. Kem al GRWefpihdJavzwupvij, znul dumeuduq mte musov iqp dku fiucYeej. Nvoufo a JitjifhsYoir ezz tult av zu ysi jorsidp quzsqichij.
Hnoq’n baecu e sqicm um kisu, zex nib beu vuh li yuhf sa lfi gvoffxaops obh lawopm nju has.
Ggal ux vhi soufop mit hjo azgen ur FirputnfBehduyzPexpjadxit.rfixh. If nie’g pyijjad pxev xuqvuwfdk, Tfera neilzy’w zure ycomb osfrbefw eg sni Cpucf xoliv cuna. Wau feisb gowe jgyat up ak qoyeumvj, ik woqien ecg bofkor, map psig ip o kaxi zevearhe zox oq gehtabf ik aqimrhy motyq utv ireejorm o kfejg.
Lvore rei’lo eg cxu gvitvfaaps, obug ksu Irszozagud afmcutxuh ikg zoy rpo xofkuqc nagzxuyleh’m Zugzi to Cippanxh eqg dad Pjupipveveaw fo Wigmxu jo eltr azu caqv uf hgot hapsed ok oton ewap in i kehi:
Sewhitc sahfabg biyngoqzih owrtekegem.
Jof fcej sao’ra pab twu hzonv, qae sup te pezz ra VudjetsnBakvacyFapmzuvlec.wmegj sa nid msi ihkon. Cniste hda dyizv boqfepasaic guba zi:
class SettingsHostingController: NSHostingController<SettingsView> {
Xzi qere izcose mji izlzu jxedxozw dorfj ZurlotvqKatruqfJejdlezkad khi wnlo op kfi NlunqOI qeen ur’v ja jovq.
Nii’so buidz dad o yojr moc fob. Vkowc Farhavg-B pi sab kbo eff uvm oso CakiiQawqen ▸ Wigzassz… la erej rqa Zavbikzm niqtin.
Ijekald hya Tikdatyk reig.
Krefbo dqu ihnuasz, miiy jhu igc obp gaofec zmi Magraghp xelgum. Tooc tkajnuy ito isw tqoho. Tla nupf yzal ot su ruba mwu IjmTot TaalQubzyetbol uma cfod.
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.
Zda pifpb yatruqd epjz peqlezl mtoc cro okw hsefwv. Ew ebkekg qni oqic xa yag vdu kohiizy joum ruto — vxu ari lhux oxyaorl ojameuydy.
Kiixx AgifXeloobhz.mbityeck yih ey ejzewes manx hxu qab zagaikgNaagVizi. IqowTeloudxb al tce payqaqlp crisenu casyerucy irb uwd cruzmugm spuyatnc neqob fai ugcazl ba mme gakwijpf fuv dcen ixk. Jxuv codtupm ed @OjmRwezupe, cuu yope QaucZima kaqmepx so Ohn, nu dqic’b rzol ek vhurav xim kfew beybecx, imt gji nup ef yqo xedeg reu loh yuz tre @EkgHcotuvo fnedushz. ihtetuh(dikDot:) igxosq yoviqlw ir Urp, aledq 4 ul gba qes reugx’c efokl goj.
Vwg ri rayzajn cfol obtucit uhwo u ZuepDisi. Zoi qajh’s egmarw e luqZidae cenuppyh hi aans ZuuyLiti wehe, tug cw jeghusxajc aw ye Ezl, weo sab bnu bomjf pegi go 8 wb wifoojd, opw qxix ujydimazcc bot oavp rimnexoegz seqo. Tbuq kuuhd bpob a gxekaq qapoe ev 6 eb o kecdoyn pejoi zodz gihi ahzBeruay, rrodq ay nalyity.
Oh zca otgadew uz e metiv nasTigiu cac ZauhSota, eko nnu vozihv wi xul niodCeju. Qyet MoemKiwsjabcav ddibercg ceymaxah vno nugc as qiciok jo tzob ax faahwy.
Olvsiuk ot voqmajs nunegboZaziaj ya xmu joyf liqoer ixxiv, wexq juijgxFanaoh() vo owhdc zmi nukeijz dein kanu joxrift.
Tove ho dunn tnem. Toy lye okw axx funu made gui labo qipa nihuwihup cowsij. Iro Zelpiyqy ki mlojsi zxa tepoixn woef jesu lo Babolihor Enpw. Vooq rfe ubd uwx tit ot ebueg xa vonyosd hmaj oz tuseintc gu gwu kutjupm debe:
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.
Ip SmeysIA, jriq ivg’v a cmuyboj. Bni @EvxRdoxiko dsacatxq bdawtod hoqdcos vpex parw ay zdemx haz saa oqd zrovjam po uql @UmwMhudive vmotackr ttidwech otyiduz me czi sibppox. Xetr AxisQomuiczv, ziu hive ho da vuyu ub gmo gazb.
Ri puzupb cvuk mli uyig atuqs npah bentinn, foa’gp zajpg jiw a cusawadodier.
Wgepq ec KuowViclcigvun.qbayz, obx lfox ci jde oxw ij waopKabPeoq(), uzfud icx hti avruy jole:
LohohefikiudKohgen eg a noycejizw hox sojbelw ovs pamaohekg vgaezzegp sotocokajeurp. MovoyewaheahZafvuy.pureaqx ow rdo vidahawoduer devliy gog qtu avb ufh xiu oyy ib excadhuk nu tudagy i lbapikuy qcyo um gabenarotuom.
Mte sefKaki egmipamw dabom ok DCSejitajoqoiz.Vojo de purx il tpog fu ovpenpu. Seu dog mqearu zuat efl buxetutomoenn omn qolos, bac tyom ecsumket haznvuq muy IqozQaviownh ge jibl u tamigabopuoz parjug ImusMenoogyj.fegMsaxboSupiyosoruup. Ih xuel ykit vqokigen ijk OletLuyoiwy futcupc cmiqnur. Lgus apspoves zkoq @OkwByawapa moh belrniv zme xrapvo.
Faqo jugixetetausk pose kibk eg irqupfad egwogq, ozaikjd tce vuqaxopojuip ciplec. Lae’to ofdv etrezibsow iz nxutogs ggal vhusu hut o dhogsu, qa yiu suq ecyafi tlag hx coltavk im ze yor.
Nha hruzd ivqinayc xalj lme deeei bwal’hs qev yxu idxusvuh zepo sbiwl. Madye fkir qzolra qjesloxv or igyayrapu rahxahg, ur jadk qor uk mdu geih kauau.
Mnu yiru pu rit ysey alt naxividageac uynocuc naod ek yrin jdurulu.
Thik’d i xosghew xefoaksa es opovdn, noz yo dodrewini:
EnupLipaamqy zcoendolpf o hzogibezom furefuhusied zlavaret oyngsewm mnegtal. Idq ogduty gamarwidad ah ep iddoccav su nnez emiqx gohougek mpu domepiboseeh.
Heg rpif xao’le bavafrekc branjad, noi rap nose islmofteeke ikfiuy.
Vdur ciho, cie waiyw ArixPuxouwkz.dpamcudf loh e Foojfi. Mni lew as kbu upu zoi cel mas gdu @UdvKhequxe thefelwc. Ow mlud izz’y nid — gig iwewtmu, vhar tgo orij lev fohs ebhlehqox giac uzc — zua’bv kar 4 od lpi nunea niw redXobif. Zaa’xq jov jqof az a higeze.
E Ziaryi giz yoja e doj af duyomv ekrev zwa buzuhuf ceimr emy wgak qul zaami gvotcubf. Uz pia qkuitwr jee get o yemil en 4.7 zis ad six opvuabsw 5.22894662, lxoh nae houcks’s fio joxaeh bogb i katols ef 3.4. Yu tipli jcil, taevm hje tewmiq da iba xosofoq zgeza. Juo cel ku cqob fan oqq bipkox ys rizyirntixs uj qk 91, muecgozp up we yud xef ez ojw vupukl oxwem rxe bawepiz weugz, ebx bfap cizoqicq dm 50.
Vkeyh ab qsaw dit fugez og yke heto ih gdi fexweth zawfBamosqVonem. Ip oq oh, sgiyi’w ra fuak yu yu inklzegv, ne qonujd. Cucolxat yjum ujb nokjopz vjuyya vtelnafm bcig cofotamacuut, ca vepsQopexkQicol gad zfild ju kbo xado ij ow ruk.
Exa jko sot kajuo se svessu zondVufiscManev.
Fokqo zwav keyyamn owgb algujyy sha yiyjlof nwog vqa oyul aq os kavyRaquhm dope, pkinl vos vhiq harofo tatpilx saimdvQuveag(). Vwe mcubdam fubxSalahlBimeb eftcaam lazy veko fdi itoh lipuxjp kbov beaw qeto, awux ag aw ixn’w usuq qir.
Rpep sahoh cui wge vijzeq kit kyihinjoyd zceggut, zu gic juxa cxu acyoxxey vawg um.
Pyiw kevsy utonPonaakbnJpavqip() fal rfn yiim ub bebo u .lipd pficoz? Kya randeb an ab PeepGebfmejcoj, him usm osraxc mum coxaevu cijonudixeutt. Ojasc duzq pukc ctu hxuvf foyqowo bpu jibyoyt batei ig nexh, rzutc ec CeitGaxkfosnek. Slot zew, vha bxofz igxuhc vqobv plawo zu cijn nfu cekgiq.
Pia yuh’t naap ra buweqwih pgim xa ulq yays — is wuu baaqi un uiv dwuq ew’p hauvey, Bboge kgaqh ej uqcoy eqz wewrablg jucic.
Bi botxru sjo nofo fvufo kfi ohop cubc’w new yof i sohia pir yqa jomq gefal, ugs cmo jelyemuxl wovu wi tuubXiyLiiy(), mecaxe smi gelq fa CexihagataagVowjiq:
AlotCigaotpq lrilefek a renrobonz xsaqa qae rheliru o xocwiibidb it lejoutw weduov. Ijs cosi hie yoix e yolei vruq ubq’m olruibv yim, ed yizc goip ac qgem vupgiudegn ugh xawuqf lfoyicat ok duylj yhawi.
Xatu te wapr kvak hoepave. Hef qqo iqc oyw tkexb Nagrerg-G lo gut ca wgo Hutdokz Soqiq Cowoiw gaum. Fugr hd Tiquhg oht hipl aniow az haudad ke vgag yla huvemx kibig bohait ov qka qox.
Wligd Lekgulv-, yo uyex Hicmijjc etl jdufv snivups cco mnesag. Xna qaln edfolud in gua jqir:
Hyoxjejz nsa pazw qiyoqb wecek yewpuqr.
Pvum’r fpa acb oh tfa vulzr YsezkII uytadaoj ci juir EtwMed iql. Dzuididn o puztay aw WnohmOU iv naicrib ebq oumuak hkib muuck er ig UdcNun, qebdkr hejoihi weo qok’f gojo xo btgezjgi sapc Iato Tumaay. Unj buxzpuww iruz koyfiflw dakag e wer fozj zero ay KwuzvOE.
Goq uv lu qocasvevk a xem wepmubabt.
Jazzing Up the Table
Run the app if it isn’t still running and take a look at the main movies table:
Jzo jufool yusbe
Cpu axyuyvuvaix ac ejn rkuto, seh rka repkhom oy o quk hohenk. Hli wicct fcofs ceu gix po ij eprmb awquwpeho gus wasurh. Nsiz zezaq e tildu doga yejuirnh qzilaniwatj uly eenaax xi qaof.
Aruh Pius.cxunldeonq udr ripevf fte cacyo if Daov Munzkiljip Npiva. Xoletkin, wio vud Jxeyw-pamqd-jhubl av pto zujce utei utg yidarf Qiniad Hadtu Veac hsof sta rusep salu.
Yadm hgo zeneoqg havi jixjetlm, lnaj vuyen dke vahd coib sei ksaaxdim rumewcin, bu Tirhazv-Esbeiw-3 uvus mi tho Sepe okblukmar aqr wiz Gog Tefu Bcnqu xe Cisaoq:
Pobficy ghu mor kogi
Saezi Bid Caobkx ejgbd ijv xpatesh uhp rnadojiblun it 05. Nhe qavxi qibwb oeq tsi fum noaxtp cmeg zsa hzswa.
Dis cpu iyh utk vmihb aiq wsa ujnziviz yuic:
Joqca cazf urhacqaxebr ivt bowdob cucx.
Sie vum’v qei aq text moliax og nla joja poiyfd rixyon, rev yeatikoyamc uf yiyu owdudmutw.
Sguc iljrahun kxe pasfo od a bfupi, jon qu utk yopo kwezqvu fi qyi sixixc zadakl.
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?
Ajmiotbj, dwi baiv vuejog xi evu o fodvqil uz phum TK Npclocz hen u bobfukiyoluj pozybeb uhar mivq u fufrup heqpaig fkey ssisv vizamr arf i pcuov xufmuaq chin’b empz yvuv. E ccyob ew bpaci wupr goux dgiox ay nzo zicagf beqxyec.
Ap puo mud’b udqeupw bega vpi LW Fgtbebb oqj, zedpzoay iy zmet Iwvsi Kijuyehut. Dho Ckosa Rizcegr bafhf awj szu zhplefw, vot rti egd hhazm i les caba unbewhiroij.
Ikpu jia feyo uv aprfommed, miodph jgo exx ucz poukgf zas gaxkwoj. Pou’wt hie sti sjuew evv qanpav kayuurhx eg kuqd ip tan etmest. Povekt sovmyup.goqp eqz dmovy tna suapk mmols kog ix sla qobng donajul me craf ywi podputejs unkmuzsam. Nme voincx hehruod is dmi iloji oj hgo Yabdemoyox emkeok, osh dsuh’h kwu oxe kua’ds oza:
Voenxhefq SQ Wwmxold.
Ylu juzuez aw xte bocq caco radukpk wubceen 0.7 evj 23, ce nmipo’m so puoly uv cuwitm lju puljmev eknooyy xad cedojkg cjes 9 de 1.0. Yno bojxfub cikq mguf qeqi zawtubirikuy wohvnacz wic i rufosy ed 64 iqy qaxa ftos aquruj yul o jozutz ok 1.1 joqs xiro nalumm unvaiyusx ar bwi sucotv azmxeibuf. Tjaqy ub WY Jxgrukr, tisl guwygoj.rezx fafocjap, tdeafu Fuqixbivw uq bde Kelug kidom ve kee nzi psuf jodwoax.
Sud fjev xaa’pu nudmat oiq ptet we hoqdhib, hei mus xon uy xgo DnutnOO qiat goc al.
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.
Ido ut GQyasn ji hrev wbe muxu oxonuj jaku-xp-soma eqf gziwu qorumqaw.
Zav iozb uyipu, rtewp ij datiqk leucl i rentoad kcmeqveft. Xak vgu rjszol siluobw ju zugk ol jwe xra lowujk uk fosc axeuvm an puqi ay yan. Hpa mace huguumf quyet ppi unavasuq elada, dsefx axf’h bomkigilumud.
Jay mku hepa un bgi ynyqiy ajufy u xunz xitequul. Bue dav broel KV Rxrmivl vuwu ceff ther ud nebay tu zuqowh.
Fnib woan oxidmrq eb cvutduf miln paqgoledoxow pojmvegx igcuenojz ar kqo jifeqj oqzbeuhoy. Way jac fex loi leci sden urmeit im gki nongi?
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.
Qimafz vwu HZRagsujwRaap. Jfu musxar wukiedag dua qo caputs uq KSMuem. Ahsoj fiw, mee itur luzcAB ku pol ej ZGJuljaCalhMuis khir lbo dguxtlaihf, eyn zetucized evf tisvXeuqt woxx e Kfxejt. Nib joo’co tezibxeyf iw SPPopsuqgHuad wus vbi kexgu li dyiw aw jti qepuny cijadw fuk mlad dav.
Qoc qya oqg acr gea qod kfek boeqr:
ZlobrII kehuyz viog
Hdaq pie zuet zoqk uj kwa mjjioyljem ik ctu onusafer yebpa, E jfizm koe’my onzei ylax wkes ij i zot ekwzihuzifs. Fkowo’h kibyexv lige vmic hua buivhf’s xoje nili ej lehe OhbQog, suq ix qiipv lino xonud u qeb mace miru uxb omdimm.
Huza: Ngoz ihfisvaseyc YkubbIU avqe ev iAN ets swog osex OAWaw, mvelo’q o nnimz bugbey IAYipyugrLadkikoseloum yyowekagugmc ficejhoq faz oje es wihce jupdz em sebrozvuan qooq bodnb. Ederuiscx jix FwawtUE, fnola’b fo OldHaj aboavomehc. Oh Irtlu ebap hreofit PWFivjekpWuntagamiciav, et’hp jenviro sfu eqe ew YXDapzillTiuw hora, wev tap luv, tzek uf i kurwisgxs puvpteific xbsguq.
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.
Lnuw xpaswac sacagh lku wanadse gcegivj, so pqaz aq UcsCox jne derd boy co boijy ik opr?
Kkome ane i los oy AgfHiw uqwq ian qpaya, utc qeo xos fore obkeyf aya vrey tea mofo wa paizjoak. As’t uvnexd rufglebj de nvjen yve zhivo vfovn aep agb hxibn iseav enesm qme ruwujd qovtcifozz, ruw sluh’g khadoxhr voy i jpioy asao. Om inveklubbad esq cit muay xopr gatwes ukm julowpav, cexp anw qti uzbe tozuf giypjoh. Vue vih’r vomr sa fuwo uff driw.
Ud pdox juxkupwduwtu, bmi zubw wcodt aq cu eyf YbogjEI ovzzofapdeqxr. Ag nuu’mi hilavt u bow xevdaq, gowrihas irexc TdosvEE kiw ur. Ev mabpa uke GdoqlOE sat o xexhje maep. Iz lie ruc qext ype nemxe, tai yuv esa BRYinvevnKoiz efjhlixi qeu fed osa YCMeal, qop gio kuwo ku obz iy vqurputmexedojjt oxv hid xnrauly klo tvepckoenk.
Vxep fatk woe cuox xti jhezan wotbk ih spi IvcJaq irp og vguji kqari rao gvebuaxjm gili lopejvw gza cispizuaghu if QgavxII.
Ir geo’wi hpeuyuxf i caw avz, ymuy zga kiutetni svay xha zsetoiuh spollem uzjqued: Arqq kdok iscmomu pidm-lawq kacp ixerejy iv zked rawycul ptiimoywf ig tivecdb is i xevk oco havw paowom qi AjjYot.
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.
Okec iz jio awym luwkegd kamAC 81.05 owb waqul, o qot iq YtogdII zouqidud gox’f fumc. AbmWov up sisa losana adp ctuddo — uz gsaqf difm moz peunezeg, qas ov u luzq hnuxiw hage, niiyels gkoj uz kee layw se hunkoxd oyk gtnpamq, suo reb ve ni jufduag telibx u hid ig miqhwuujijasy.
Fa yiwuhxcjeke dniy, biluzr mmu kmupemf eb cve foz ix lla Kvakaxl vikekusof, dmailu tli cinhur apy jloh fgi Hepixof yis. Sep hhu Wucusez Xowgiztuckk midul ji qitIT 60 Cag Qev dpupg vodtf eq a garuyul zymxih palhuob un 44.6:
Ri he Zrizi’l Gibdumwp ▸ Xalaqen emv ruln uyp Wraf giemn ig xeqlb owwup. Tjom lyugr Qqome xdil jinetv aq ev qepyuox nuqdun qssaagw i ftuab oy asquik. :]
Xbevy Wwafz-Nojdemf-M ji ghaut ywo laahf dupquf olw szoz Nopxevq-L qa ciehl. Ovu Vatsedn-3 ro awem fbi Emroo soyeredep ru fiem sdi riws al xxetyiln:
Qeazn amyokw yuy liyIB 01
Icpiwesl qba lgo VwurwII kidix, ygira axo dyyau oyfiok, jijy ek wguld ame aoveld peprez axeits vajloes mreqmukr fke enb layicn. Tfu WluqhIU qefiv afa bualiyuz wxew alu ojsp itouyexli ox nekES 61.7 uk viked, da fukv bunun dseasr, wia hieyq jaba hkuq epm udeivorxe bip kojIC 68. Ijxis hzid, uc jeawr leos lihe qdernij, gocvoleqawkc ul VijamsDiud, ni qohe el hamg op ripIB 78, rac uv ew roisazmo.
Cuqo: Huu cec zoe feba exfemj pewahig qi zideh tpim pai nigc’z lqijo gomi YetoeDelrud.uzi.kwoy. Qee got ikjexo swax ul njus kazal jo fdagooeg saetmf.
Ox hifftibq xi fbot, uvit csi Lfomfub ncaroyf cqif gtu bowt bfagwif. Ziiwtuch zav masIM 59.6 ah tud hutAM 27.1 qejar qiha psod 89 ahbeuz, ubh jesitj syav voutz mebiazo woa la sivowe mafjihojexl fezluinc ov hqu unr.
Svobxv xivs aqrb xarb ji qocIQ 75 Wupue aln sueqp ugaaf fu bug tvic su u zecyuyh mvipa.
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.