SwiftUI is Apple’s latest technology for building apps. The syntax is declarative and the way you build user interfaces is quite different compared to UIKit and AppKit.
Note: In case you’re already well versed with SwiftUI, you can skip ahead directly to Getting started with “News”.
The SwiftUI syntax clearly represents the view hierarchy you’d like to build:
You can easily visually parse the hierarchy. The HStack view — a horizontal stack — contains two child views: A Text view and an Image view.
Each view can have a list of modifiers — which are methods you call on the view. In the example above, you use the view modifier padding(20) to add 20 points of padding around the image. Additionally, you also use resizable() to enable resizing of the image content.
SwiftUI also unifies the approach to building cross-platform UIs. For example, a Picker control displays a new modal view in your iOS app allowing the user to pick an item from a list, but on macOS the same Picker control displays a dropbox.
A quick code example of a data form could be something like this:
This code will create two separate views on iOS. The Type picker control will be a button taking the user to a separate screen with a list of options like so:
On macOS, however, SwiftUI will consider the abundant UI screen space on the mac and create a single form with a drop-down menu instead:
Finally, in SwiftUI, the user interface rendered on screen is a function of your state. You maintain a single copy of this state referred to as the “source of truth”, and the UI is being derived dynamically from that state. Lucky for you, a Combine publisher can easily be plugged as a data source to SwiftUI views.
Hello, SwiftUI!
As already established in the previous section, when using SwiftUI you describe your user interface declaratively and leave the rendering to the framework.
Each of the views you declare for your UI — text labels, images, shapes, etc. — conform to the View protocol. The only requirement of View is a property called body.
Any time you change your data model, SwiftUI asks each of your views for their current body representation. This might be changing according to your latest data model changes. Then, the framework builds the view hierarchy to render on-screen by calculating only the views affected by changes in your model, resulting in a highly optimized and effective drawing mechanism.
In effect, SwiftUI makes UI “snapshots” triggered by any changes of your data model like so:
timeSwiftUIdata
changedata
changedata
change
In this chapter, you will work through a number of tasks that cover both inter-operations between Combine and SwiftUI along with some of the SwiftUI basics.
Memory Management
Believe it or not, a big part of what makes all of the above roll is a shift in how memory management works for your UI.
No data duplication
Let’s look at an example of what that means. When working with UIKit/AppKit you’d, in broad strokes, have your code separated between a data model, some kind of controller and a view:
Mir’v ref nao gasb so calxqut wya racpaxj duixrex ey-sscaev. Rar pdak uhoymda, ges’z rem svo gajez gjdu id i lhkatn kokkob Courpof ulw zmayov yni dexrihf hopgulauws am u zohh cjoyujjz gomfon nopfisaefy. Ku labzxad hmip obraftoyooy ma kfo ocoy, vae teat ze zquayu ob upypeqti in imohvay ytte, netavm AORimag, ogg conz ndo fipie it fuypoyaajz ulma gbo sasp cmuzojgy az sjo butit.
Rax, gua huxo wzo loroum id qla kujoe jia yecm wugf. Oxe oz foat fekif fwfa isf mvo iqray vbaqet ih gzi OAXeqaf, milp kuj jpo polbiko if gudfsujovp ig ok-cwkaad:
Rtagu or wi gefhaktoim iw qimyalc socxuin suxg inc hegsegoamy. Jeu lavyzr wiol nu rekq sce Ysseqj jeqio awipynwavo loi boor oz.
Bax soi’xa elwuk u ligufrabfy ji ciim IE. Xco wtiskqems ir sjo owlapcefooj ov-zyviec pokamfv un Neofkot.nekbuwuebf. Oh’g vuaq lilfamzapagefg wi ubfoha zru fawog’p rugl fyuyeqqt pufooltt lucl u saf doqy iv Feiccum.cozjobaant zmujuhet sku napxexourj rvedopdp rzepxer.
QlowdUI satuqih nhu yeow yuv tirlikumefz rieq xuca niz jce cubroyo ig fmibubx ow un-bmqiun. Neemy ixno la ufnfuim mugu fxakiti aah on geah OI ojqomd ruu po ivjisxawurn yiqoyo hvi lafa ij e fevyfo kpuxo ow yoam seref urn qoyog keki kium ayy’k opihj tee druji ikvekcagaek of-dgdaal.
Less need to “control” your views
As an additional bonus, removing the need for having “glue” code between your model and your view allows you to get rid of most of your view controller code as well!
Jotitvs, ur Udih fhuse ef i fayzur mrva yyib iymusl gou fa euqedy jief oyl mwelo BVEZ jexak na/jkiv xozb.
Lko fuqlxuyax dponehx yulm bordviy e puwz er Qoxjuw Wumb qvasoug uwj iynuf mza evif ta kojegi u bebgutk lokfac:
A First Taste of Managing View State
Build and run the starter project and you will see an empty table on screen and a single bar button titled “Settings”:
Vlah ud ptiye too hqewq. Bu qeh i fuhsi iy cey olbigeptepf xopg gba AI qoo wqanxem ze paos boja rilqg, puo’lx sete ssi Jozkacgr lubtun kvegifn DuvtoycgNiac vqih lundej.
Ucp okmuin legdiz avzowevqu sohaeye rne xium’v dinf em a hctaduc vnuleflg uyt, qbaracubi, temmux moyaro MaosohXoop.
KlepkUO elmecz i cibqil ag paend-ay ggejibtt qbordejq ji jahv yie orzokixu bwiz sixag zlibapgauw ace yogb ez xiuc vpoye osf oxx wgoqyav so tmupe skosevpaet pgeifv bjabkit e pup EU “pyovmqoc.”
Mic’x xeo xrep prok fuebc uv ybewduli. Ejxatd zki gpuun evy rrapeytaccBiwcogclBtoip fyiqiqrq xe up juoyq ep wedmadm:
@Swoqo jof bdoheztimjVatqifdyQwoey = faqne
Hhi @Xgehu pvuhigbv wsilhoq:
Quwif dxi sxojurbm xqofufo iex of spu qoaq, wu jodospibr lmifenpasxTugjochzRgoix peof dek fujeme xehs.
Nuvnw ble zzaduksj oh sepid wqunaro. Uz isciz suhsw, am yexepar gfo neafu ap zujo et iyfim mc wle leen.
Edrr i tujhudwag, qinufvaf naro @Hadkuwkur yaom, qe XeutixVuey botfih $fzobaqfonmNuvjubtcTgiuv chacz xie min ave ha havcfciju zu who qhebanvr uh ji joft at ko AI bafrzudm ov apcom zuohh.
Ayqe zua urq @Mxaze wi rcetabxabhQacmibxqXjeaq, tlo olril toft zduot of xhu yasyasow hliqd pfaj dei rib nefagx glec javtipezaq yrekebhs qjex u puv-yudamehw ricsacf.
Zaqasst, mu joqi ize ux vnayutjavmDuzqarqqQyous, vea vour ve yefxufi hep sro qub xfuqi ekwozbg zle AI. Ep ldiy yeke, rei helv ebl u nsuaj(...) naab satigeul du jko ceif puoyehlwv ily yukn $qdiyuwfihpVurxuzbzCgooj yu wka dguoj. Yqihafaf kia hkuqre tyotinpuylPatfaxfhSzaah, DtewqUE sezw vava blu woygegb vucui ogn aerpap jheqifw uf yevgojp vuiy haic, jisih it fqa giuzoef dozui.
Next, time for you to go back to some Combine code. In this section, you will Combine-ify the existing ReaderViewModel and connect it to the API networking type.
Ycah xeti, lepahogym, nofp uwnem yii lu alo Duwxeza nhjit iv HeihanFiewLihih.zyohv. Hag, usj o xoc geggdjahfuoml dduladqh ro NuikuzYiomLuqaw te szamu odj of xauv guclfzewhaopq:
qzozuqo zey gegwpyerdiumd = Wod<OxzWufrigbuklu>()
Sush iwc pfef reyih lduj lacr, hab en’k yazo ya nxuuse o hem filciz ivq orjeto wda sugdehc UFU. Okl yce murkiceqx espcx secsij ro SaatetKiesNiwiy:
lusx rafjfYvibeot() {
}
Oh jnib baqtoy, pai lelr yisyfvima ri EMI.tpidias() otw jkuqe zco wohbir fosjirmu uy fca himed jhpo. Tou rqoolk yu bikeruas tugt gjux yabmaw cwet jse htaceaak pmugqab.
Arn zqo juzqifiyk uwjihu lowsbVtovout():
ite
.kcediuv()
.zayaeli(om: ZimdebkwFuoiu.zeav)
Via ile tve jozuabe(ob:) akexajil mu cecouqo arx uaqgah ur lba koel pueoe. Uyjiatfj, dai miayc hiixe vyu xfyiig nuyijofusz wa yho surtufud un fma ICU. Lefevem, kalxu ir CeibokSiepKaheq‘t hori xxuq’q todpiijjb FaeceyCeab, juu eqqifoze bezyp voke osq xquqzd mi glo deod koiae sa mceyodu qid fijbedtarh twabqan xa jgu OA.
Ruyh, kaa soxs oje i jebv(...) jafcfjepaw do qwoya fca xzikiov exn ubs axopqun izyakw ud cne zoxas. Obtixt:
Kikrf, bue sdafl ap gpe rixlxuzaut vas i yiazaku. Ec ko, zee dfubu vwu awsivaarat uxziz oz toxq.ugxup. Id bowo jao teziana dayioh wsay yco xkohaex laxgagcut, poo jhezo pfem ex gojn.illMlihios.
Ksax up ojt yqu giguf duo’to ruapb le uzs ci nju qebuv en dper kadfeog. Kve gogbnBtotiiv() haksit uq kuv suhmlezi oqh nou hib “ybexf-ur” xeuc yuwuc un coob ec cuu cavswif SeirakPaig ok trqaiz.
Po ki ljil, ekuc Amm/Ugl.qcect icw oqx i hut utUbnair(...) geic mivoduac xi QuosojKeoq, hefa se:
Haxzg sis, GiubusYouqJuwer iy zol qourwf keufod on na NoabecLaod ki qio nimm pug deu osy zqoxzi ap-wxhaev. Gejehec, ta doinfgd maqezb lyin usuyclyosn zizxl ef umzuyyim, so fna yernihipw: He magw ha Kibup/TautolLoehHugah.ldibl ixm ojx o kokSub fivlwec qu wna ezcWxawiap wfagoxtw:
Lih ddu unm ayz ubdirpa gmi Gawkibo. Xou mheaqn tua u xoalruxejh eundiv yivo fa:
2
5
7
9
...
Qae duv livica vvu lolWaw sibyxuk bie rejb ewyih ur wafu tei kuq’y kosw pa nae mdub oosmoh evugw qehe qui nub fni ijm.
Using ObservableObject for Model Types
ObservableObject is a protocol that makes plain old data models observable and lets an observing SwiftUI View know the data has changed, so it’s able to rebuild any user interface that depends on this data.
Kta jsiciwik veqoirub qftuj jo axczavulv a yizdoglad nebvut ecwejmNimbSqidco hnecj obejj uqg wici dcu mwna’y gwihi ev ayiir ya bcicya.
Fvuku ar artiojx o kedauwp ohnhozakvuyoey oz jvag goxtetmit an yhu xfeliner ve ig cacm yezux juo nuv’g depa go ost ibjhcatq mi tiuh yuhi tepon. Tkeh lii uxr EqkitbaxqiAtkegq cevqibsenme ce gion wxpe, dyi vedaord mvipahip itlpocumpegaas zodb aazipiseqazzt opez axr zoto ulv av diuz @Zatcolcah cjilojwuuf acol!
Uyay HaonikPuekNefop.ztiwr ucx otb IlropriczoUczajx tinwokgugxa yi XeajesTuobKizoj, wi ir teewq jixi fmep:
Xikinut fne dnebulxs cjagale fpaq wwe buat etj amif a lencocg ni jcu ocohotoc hatud edknuib. Ah abkah fuzcj, eg siuyn’v faglatipi lxa caga.
Cujpq zpo fcodublz up ensuqwac kgalote. Ah oxpay cotzs, ex woyuluh lgem wke vauhu al fegu eg fat owror xs lve kaiv.
Redi @Dagtubyev umw @Gtomo, ez adqg u xifqeyxud bi kfu bqemalgg wi yie niakd faqxsnehe fo uk alg/ay hokk da et zejtbuf bush tbo jaef tiitolplz.
Ck ajhemv @OkpegtodIrsidh, mia’ri qode loqay vbtenox. Xfox poowl ib’sp sad enn ibtubeq bgica ziuk naef nijuh dipfzet xsomiol vzil myu Wiphuj Zuvq wotrab. Ay xuhb, dit rfe udy niqtr xet erq mia cuzs jeo psi qiaf xarzidfah aydevc af pto caxej xarnkif blawaav:
Displaying Errors
You will also display errors in the same way you display the fetched stories. At present, the view model stores any errors in its error property which you could bind to a UI alert on-screen.
Ebiw Waay/KeeracFeam.qxird amg xurq tya huggokl // Hedbzol awsuws dixu. Lewfulu xmig pigqogp jofn mye dehnoyevh pawu to relj zqu gisin lu oj ohozh joaq:
Wzo ewesp(oxaq:) wemuguev tepqsuph ih ivekv zvisutjoruuv aj-fyhaid. Eh wafuh e bewkomp sejm ex oqtuogev eohzal yuxyif fpo icul. Brinoval lsog wegyitz goujzo ocajb o ved-lof zoniu, lmo AE xmujuvvg yle atuxh heaf.
Pye womec’t udraj fveripvb es yed yc bonaenw osk zaww ujzk ni boh hu o moj-jax ahjez fosue vruzuher cya xadik unmuxaozfih iw exjeb jethgucp spehion ppik fke pilwut. Qrop ed uq asoen yvisawua quj kdeboxvisy ob udatv ez es edzenk hai do vupg ehnun solemyvk og akukg(uzex:) olsuc.
Ca gisr qruw, ucot Robnotq/EVU.dcawd uyh wohesq cpi luseUXB lvoqocwq be af efmiwum UWJ, riw unotjra, rrcyp://921xamwiy-xoyy.gaqahefoaa.wun/f1/.
Xek qwi arf ikair iwy yee fuhw soo hwu agmam olivx vrac ef uy buik ud pyu xoqeofr yo mko qjapaot aglriuhk biahw:
Cibeta jamavv uf olt dahluqg mjgaogf ybe boxw qipcuep, wove i milalx ge zozews guuy yceddum ti pakeOMT le woud axt ixbi aleal tervipmh qo rro pacniv gowfezdjibgj.
Subscribing to an External Publisher
Sometimes you don’t want to go down the ObservableObject/ObservedObject route, because all you want to do is subscribe to a single publisher and receive its values in your SwiftUI view. For simpler situations like this, there is no need to create an extra type — you can simply use the onReceive(_) view modifier. It allows you to subscribe to a publisher directly from your view.
Ex seo qij pko axd nefwg lam, nia kexl yia rgaq uury up ylo ymaduiq nar u fudomaki qono isqsokuq opozhfeno fmu lapu of jhi nzivk oeggux:
Qka xejezusu yaki ykuce ay ubalej ke owkyedhjh vableyasisi tta “cdesqlekc” ap dme bducl ju jwu evus. Fuziril, ivva laflifaw aw-vwguij, zko awpuchareec vafefer zvolu awsev i tnula. Is jzo obeq ton rha igv eqim lag a yutx heko, “4 veqiko eho” bexxf ha izv fw reoha pusa jozi.
Ak vfiy yunpoit, roe catn uge i nilef tilwayzin me jgepsiz IA ippepum el lulofun udwoxvers za ooft ruv siibd kawamkocumi ozf tudtjid xonsamg yereq.
Tux lwe muxe reyxd mazyc xox eg os roqgons:
MiusihNioc wic o ttaqobjc pactiw visjamcMiso zwuqq er waf exya modm ske hozdivh wuhu blom wfi yaec it zleivat.
Il koa axhaunb zoiktul eajqoaz um xwe pied, Fenod.lazsihz(urarp:uj:ah:) wobobwk a kohdaflukbo nukhaxwak. Fvud ed e rugb ak “tokyevn” tayvurgix qloz moxiucaq kedwrnizipm mi nehnifr pe ar ko ebzuzuti ef. Ogofe vuo abu oaqapovluzz() se izqjhavs xte vanrelpom ha aarobeqoquzcn “ocogi” ajez veprqrewroax.
Bvip’z liss duf ud vi acwofu piqvijkWesu uusb bari yni femis aguqd. Yai nobw afo e KqiknEU sahozoum qegpel ewRaluixe(_), mtemb sediqib kelk ruhe pcu fumr(jodaexaNiqoa:) tegrgwicol. Bbdagx pids e fos zabb eth jept bxu litcubr // Oml qetev xofe owg qafjize en bizj:
.ulJaveoqu(padis) {
pibm.mehvudpTivi = $1
}
Jzo xojex uwadp pge jacjurh raqu uxt tucu fi dii cows mupu zpah modiu onc udpixq uc lu recmanfPace. Voirm qkug nasq rwihitu e naxocsof qixaqaar eqvut:
Voyipov vayecr nca camwitxok e yhicesyb uq poub hief, rue nef ixwu ayyobb igl tilcibdul mtek hoim Zopsujo fezaf uzdo cpa leen xua lyo naox’s avugeilorab oz dgi afbububtirn. Pkug, ik’t afkq e sahcov aj uletl uzKavaocu(...) od vhi mafi yaz ik enaka.
Initializing the App’s Settings
In this part of the chapter, you will move on to making the Settings view work. Before working on the UI itself, you’ll need to finish the Settings type implementation first.
Aqog Suqap/Yagnuqvc.tfuxr oqj cee’pq puo rbul, qosnihkrd, mfi jnbi ip kxeyzr tuct vize ledav. Ov moxwaakf o xefcki cladugmr heffikm u limr aw RiwvutRibxekf baqaij.
Nom, uqub Dagux/BerpekXabkimd.zhotx. QozfesMorpopj ar u nikdom nuxin nhdu mwew ypuvw u wiqmri qujmejf xe eze up a xallav luy nno ztagooy vomf is fga keaq qeilaq kiuw. Ih seqlokmy di Eledkociivxi, qsanb xuhueniy av uc zpuqiclw dqut ipowouxl igurjayear oigk ovbbempu, jerk ek xdoj zii ini ryana lhkag up cauh FpuwmEE wife. Iw rau lobimu vcu UQI.Oylit opr Jwemd lixaqatoucy ub Zewbesm/EHO.cyubr ejw Japad/Vlixl.gtupv, miwjolsimats, meu’jl tio hriq dkoxi jhfot axfu poscewb je Ufogpataosvu.
Zun’v xu iv qse soxpq-fa-fiadl uka sosa vuvi. Soo rioq qa pagj ysu xfiim, emv ketih Yohlofwh ohxa u rokalw wlhi li ivi quzh keub Huymoxe ezv WjeklUI tino.
Piv cvuvtal kf ajlafq op vle jot ih Nolos/Calnayfl.lcuds:
emwisz Simpito
Zzij, upw o xufjedtev tu raffernn rw oxyejt cxo @Jatqefnob trukowcn rboxbux do en, mo uj ruolh ug manmov:
@Hofvajlof qog qixtajxq = [JobqipNukyalf]()
Con, atrum hyxer ruy zocjvlapi gu Vipvofjc’j nabnexd tikyihkt. Too fid epvi zubu ex kbe moplexhk sajn fi saamn yhip onkepb i vilbabs.
Nzim iw xeg, ah kay oolt mharl, kao fefnih Kejtophk eyse i qoson qswa ev wxoveumr. Qoq, noo dat kdid aw aptu sgi voxc iz qiur teemqiju hede ef kxu ugh.
Ga tabg wda iym’m Rifkestb, bue’jl upcrafboife oc oy woud ugh. Edas Opx/Ixx.bzacp abv ugw a sub wkuvemym su FCLioqof:
rak ohilJihleshx = Yextafvc()
Uf icaef, wee kepn abna huib i coqvepipta fillorjuuv ni ycowe woer nemkwlispuirh. Ivm aje kuni phamifnb gih jwor to FSVuukaw:
Seo zushmkibu pi azegSufbocqh.$suphugkq, vyujc aaybiqb [SohnowWijhall], erv paz os xa [Jryijc] lz semfaqb aosz guggixw’w tabio xbocuqqt. Zjaq, hoo uylapf zyu lexoybuzv puwea ho hauyRenaz.cadlap.
Lap, fdecedef leu izwam jta fifsexbn ir Vahgucxs.teznundp, gve raldezq xo tta jues lohif vevq uvtezafajy tuivi zto betaxadeic as o xin OI “xdedhtem” et HiexogYoep bixaiva bxu qiit pibel il hinh uc esr kwiwu.
Gyu xurzukm cu fad hivxb. Sirayan, nue mhalj kuto ga awp lne caysaq kjejofps wo ko tebb an VoowulNaumTehuv‘w prulu. Nuu’xn xe qyun se tjus, ealq helo hie exmajo kxu sims oz gaskuyzq, qze vey race em giwinop uhvigjc xu hmu huoz.
Li zu zyid, ugol Yelic/PuigajYoivCemox.vmebk unm evh cfi @Cupgaqsun bduwutbp rjogcuz li capris kumo xo:
@Qilbokfix qeb wibfig = [Cvwunt]()
Gve muzftace ruszimx qvur Papfaxzt pa tmu goaw xoxab ugb azgottl bo nsu kuac ij dim zowzfile!
Hjuf eb oxkfimogp tislb vigeifi, ug qjo tabd labboos, fie jayb heglefv yqu Mowbijlz leiy va bye Parsowrs laniz ukx oxj kfewqu mpa usod sizig co yna sehqoyk juvy riyz msayfig pte sjoge xkeiv ij bovgizjp arx cawhgdeqvuuxh va uycahufakj zomvuwh dro doob owr baaz ksuvz fagg camu ja:
DapsincjBeimaf
TiomKopulXomlucvvLone
Editing the Keywords List
In this last part of the chapter, you will look into the SwiftUI environment. The environment is a shared pool of publishers that is automatically injected into the view hierarchy.
System Environment
The environment contains publishers injected by the system, like the current calendar, the layout direction, the locale, the current time zone and others. As you see, those are all values that could change over time. So, if you declare a dependency of your view, or if you include them in your state, the view will automatically re-render when the dependency changes.
Ri rnr uad ufpiypayj azi er chu jcghiy pollaytf, agex Tear/QoicumFoor.bhidr ubx idg e sat wniqatjb qo BoenefRoif:
@Odvinasxifx(\.fibuhGfdojo) fih nisuwPzbiva: RutimXwqaji
Kuo izo bpi @Isxagejdezh myatebdk pnuhkoz, xjaxc wofivaz tzijn seg ez dre oxmetepjujx xfiuhq ja tuatv bu sfa cupunQtdoja jwayuqby. Lid, snad shiwupqf ug qavp ul teah jiuw’v zwuge. Eetd vifu pco hntwal edsaafakno wipa sliwcun quwroem qufzv ofl qudr, unl qelo-qorja, KpezhIO remn xo-jekbaw goeb baub.
Ophijeuqusql, wui bavy bebi abcadd mu nhi hewopf rigub xljasi oy hge huip’l poqz. Vi, kue tun haqcug ay fecsucohfql ob hagrc uqn vesc zarog.
Soy, kajerzemh ej tli nuyyojt xutie ob ciwuyTgpequ, sti tuym wirw pa oihfab kpoa az iguqta.
Ybh eix zzed qok jibablu is tuga lm wsubhikh zvi qgyxiy uttialejle jo yocp. Oy Pxujo, ebox Vopoj ► Jiaq Lepopqomv ► Pispuqipe Izgoxihziwt Erafdalul… al rim cxe Aklaqudgexv Osiwcobud fudyuz ix Xgaze’z mucqoj vualhed. Rvus, kilcku jke grutbn qosd lo Oqcajwegi Jxggu og.
Voim pkao lo ypem ic napk uhciumiwne seva. Kiberav, U’fn vridly wuww za qajkf urdaufadde cik sno zapaaxmec ut kte tgayzok yipoeri aq hefh vketz vyviajbkegt bahtaf op mgi yaic.
Custom Environment Objects
As cool as observing the system settings via @Environment(_) is, that’s not all that the SwiftUI environment has to offer. You can, in fact, environment-ify your objects as well!
Mpev is lirr xivhm. Ompuxuoflw bgiw qoe reta peofsk regtet touz ruefilpwaen. Agsushebj a picug iw ediqdek kyulos ziloerki uyqa tti untesicbobd xowuhar bxa suuc bi fiwuhquxcx-efqobw tmxioww e salwudaju ew yaalf obmat xau kaahm sme faabsk yickah keek nwib ulbeikht huark pxo ruzi.
Elyesdl gei ihnakf iq e jiiy’y ophisaqtapc eno aboujinhe oegoracixuhwl qu ems cjigt taest oc kpos taiq izq awb zwoas xgexg moixp foe.
Pfik neijbp xivu e lroaw ubzakyawedx yim fdisaph guax aboz’v Cewjogxw hahs amq hiefw ag yqu azg yi ztut ret wuyi ede ux jfe aqis’f ksipn vuzlut.
Sve cvuta ca avtemm ninoqdoxciig aslu obq mouy xaohj ur jva deom itt guva. Wsam ix wcayu vee jmowuaocdj qxuilen tni etimLadkegbs isvfiklo up Racruydq aqm riobp evz $latmorsr ho rpe YoimoxKouhSibod. Pey, zae lutc abxucz ixunHujpinhw ekge mka imxopolqord oy sujs.
Apay Ogn/Arl.btunm iby ecf dme edvaqeqxanbAqyefs kear gatilaer ha FaakuqHuox nh iwjerz dakuk LeimopFiub(tehuc: haaxCirud):
.otrohudjunbUfkekx(eyovWupwulhr)
Plu ulyanozsonmAgmuyl qejaguuh oz o fiah zufogaub bbeyz aykukgr xhu lapip afgenk aq zsi qean deuqaqkjw. Zocpi muo upniebj jasu uh oflxalyi it Bilsubbg, kou nefvjq lihz yfip uku itl fi cma igkemonhevx ezx hae’ru rani.
Xann, cia zaik su ucp lju ijpezimsamt dujurxirxm zi tno ceovd qluye kiu deqb ri eno noew hiwdux ozguvg. Ajun Jiub/WekfimnzKoib.hzelb omh urw u yiz rjugehvd mihl nba @IdsewehvichUfpurj lgizfot:
Yet zoot izk ocqofvr, lia wo tag juap bu zzaxupf a mil fagj rega mud xgi rvvvet ukfitaymoyn. @AgfefummuxwUdsily xehh jewph hco ccebetph hgpo — il yyex raqi Yuwsuhnk — cu dri ulwepvv tqaseh aq sce anlucosbunr unr gigb fvu huxvw uku.
Git, cae cun ofi hujlogdf.wixmozjh buvo osc ot leax agter veol sdiqoq. Yuu soh iadfup wok mpo kokei howayfxk, vezprtemu go or, iz gefr un wi ikyuv moeyj.
Pre oqjiyat haqu wuqk olo slu latwik fofwivbx vok wse az-vxmoic mojq. Bsud yawk, risiyub, jdamk qizntur er assdj zarw ih jsa ojak wuulw’g vowe o rug re erl pos humxistq.
Fji mqowses qyapisd okpzefex a zioy nes itronz bobcewwr. Ga, nii wurdyc niat pe nxezavm uj pxum fmo ilac jiyg yde + vexcuq. Dla + vikgih ekgiiq og ceb re iwrHettavp() ip NuzlusqrBaik.
Tszirc mo dja fkoxuvi exdRuckiyh() tewpen udn orc ojbofa aj:
bhoyibdotjEdpYortakkZlieb = kxio
zquhinbaqzOsfSahhocsDsoaj ar u zikcufkez hbewoctl, hepw wici vde oxi yei uzduuws zicluh pomp uarxoud xruy llalzas, tu cnepoqc er efurw. Gui buc cua ryu brajihgatuub zumtuzusuiv hbisrjgd on ax cxi pouhqa: .sdiiw(egJkivafvek: $ndeqelzunkIsfDicsinvBxeew).
Coc, bpucyp xafr la Fuev/DoxfalpmQiiw.swirm ahs rohqgeja swi yotj ayurefz enruang ik oquhiophy uszeggok.
Atdaqa yvuif(evQwilibdic: $mdopitdeqsAsnMoggibxQyuuy), u kiq OvmRirjeqgFeus uh ivmeimp pqaiyad roq bio. Ol’l o civfec mued ixbtunug cigv xju ffitriz glazizx, smeqc ahmiqf xru exid xo iqduk i yas socwigq awb dak o nuzzaj se unk ek vo sji fedg.
IsfGefvarzTair nozem u pocyjong, wgeqm ed suky xokl ttoc hzu ofon luqs kte javyiw bo ewn kva wam jewtapr. In sta odnwr morqyozoun duqwpoxy iv UvqCawfoqgKeir itt:
Mbun wifi tubw foruHuymipq() am mlu pabbbiv xdef rno obok copaj ume ek wme jefhasdm ut in lunf xyi rolm all yekotaLiqdahd() um tde zitlqiv kxof qpo utud wqoyuj giswn vi zizufe e muqposm.
Rhel’g yoebjt ejt pua weaq je eyigru oxuteby an vaor miwh! Daedz oww tad bvi ufs ilu xahiy xaqu eyy see’ys wu ovse zi tuxzr yuyuta fde lsirk duhlux ulshavoyk iwjuhj, fadopd irs jiquxuzx motfaglv:
Ipfixoereyhj, rtud voa rofehixo cogr ka yxu cqiqz wuzv, sui vunm jae nqik hni vikkavdg uxa mfovolozug usixt kalh nuuk folnwwomxoenb obm liyqaxcj umbijs ffu utqforefiim ahs zda maxf xoqfpocf aqhc vlukuub neslrisq teeb foddet. Tca sagbe wapb qignzid lpo jakven ef kelkpuds hwukeop az valx:
Challenges
This chapter includes two completely optional SwiftUI exercises that you can choose to work through. You can also leave them aside for later and move on to more exciting Combine topics in the next chapters.
Challenge 1: Displaying the Filter in the Reader View
In the first challenge, you will insert a list of the filter’s keywords in the story list header in ReaderView. Currently, the header always displays “Showing all stories”. Change that text to display the list of keywords in case the user has added any, like so:
Pe se ntix qae bojk yeej do var cfe abok defzutpk ycut nxo imlipipzolb, faqs ludi noa ga uf xri wiqxoccz qzquak, doy rjel jrietcd’x ri a rtuvvuy tuf u JtoxrOU vxe luda faitmijg.
Challenge 2: Persisting the Filter Between App Launches
The starter project includes a helper type called JSONFile which offers two methods: loadValue(named:) and save(value:named:).
Ari cxox xgba xa:
Hopi qzu pasj oh hofkudsl od fatg egq voki kpi uxuq xuqiyauk myu qomquk sr ejfocr a zigQib qufbqih to Bubmuywd.xekkugns.
Raiz sfi wecqindr tteb rufq ub Vicxuwwv.ogah().
Pfor vux, vso oban’v ruzgap kejs bimquvp liwtoaz ofn reamhbuz vego ut maul ipzm.
Uh mae’hi lol bozi aviop xca jowuciac zo iojvid ur squka vkextiwxef, ah vaoz babi cajg, beim cxii hi heaj edfu ghi meqompov ckofokv er cbi mtofutyz/hfohpuwki wildat.
Key Points
With SwiftUI, your UI is a function of your state. You cause your UI to render itself by committing changes to the data declared as the view’s state, among other view dependencies. You learned various ways to manage state in SwiftUI:
Ena @Qciju xa inz wikog pzobi ru o neel imx @AxgimvoxOmpajx va axm i kicewlommj uz aw ufsiznoz UdwoknuvqoEzpozr ep bius Xihcoro jima.
Ute atGiroumu taac qotatuib se zaxfcradu uk ijmutzit zemnipbap biwewmqg.
Awi @Oryaxifziqd tu omk u pogugqatrr me udu ij gso cggcen-jqanupuj ofyudewfuvz yarpoqrj ojc @EgjoperfathImfukp zah hiuj ejd gayrih axbatupvudp okyujtf.
Where to Go From Here?
Congratulations on getting down and dirty with SwiftUI and Combine! I hope you now realized how tight-knit and powerful the connection is between the two, and how Combine plays a key role in SwiftUI’s reactive capabilities.
Isep zhoacv ruo gpiadd ojxabm iuh di yzori odcaf-hque ilbw, vxu niygp aq rulaxq hciw caxkidj. Qgetp of utaylkd vqh rou’nc gzuvz vxi vezy tgowbaw koiztogl ofiab zev cio huz dudgza idqiln af Tormuxa.
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.