If you’ve made it this far into iOS Apprentice, congratulations! That means you’ve built four apps, covered much of the Swift programming language, made use of key iOS APIs and development techniques and have most impressively, read through over a thousand pages of programming tutorial.
If you’re reading this, you should have worked your way through the previous projects. Everything in the next two sections was written with the assumption that you’ve read the previous four, completed their projects and will know what I’m talking about when I refer to concepts that were introduced in those sections. Each part of iOS Apprentice builds on the parts that came before it, and it’s best to do the book in order!
With the first four sections of the book out of the way, the time has come to say goodbye to UIKit, at least as far as this book is concerned. You’ll still see a lot of UIKit as you continue your iOS programming journey, as there’s about a dozen years’ worth of UIKit-based projects, code and documentation out there. You have enough knowledge to read, understand, and even change and improve all sorts of UIKit-based source code. I’ve met a number of developers who’ve started mobile app development careers or successfully submitted apps to the App Store after making it to this point in the book — in fact, I’m one of them.
It’s now time to say hello to SwiftUI, the new way to build user interfaces — and not just for iOS. The next two sections of iOS Apprentice are dedicated to showing you the basics of iOS app development in SwiftUI. By the end, you’ll have enough knowledge and practice to write basic apps in SwiftUI and be able to take on more complex tutorials.
In order to keep the focus primarily on SwiftUI, the two apps that you’ll build in these sections will be ones that you’ve already seen, namely:
Bullseye
Checklist (a simplified version of Checklists that uses a single list)
Take a moment to reflect on how far you’ve come, and then get ready to dive into SwiftUI!
This chapter covers the following:
Introducing SwiftUI: After some congratulations on getting this far into the book, a quick explanation of why SwiftUI exists.
The return of the one-button app: It’s the one-button app from Chapter 2, but this time, in SwiftUI!
Building UI in code: This time, instead of drawing the UI on the Storyboard, you’ll build the app using Swift code.
State and SwiftUI: What is “state,” and what does it have to do with SwiftUI?
A quick look at the preview code: A look at the additional code that lets you preview your app’s UI as you build it in code.
The anatomy of your SwiftUI app: It’s like the “Anatomy of an app” section from Chapter 2, but this time, it’s about SwiftUI apps rather than UIKit ones.
UIKit’s downsides
UIKit has served iOS developers really well over the past dozen years, but it’s not without its downsides. I’m sure you’ve run into a few of them while working on this book’s projects. Before we begin exploring SwiftUI, let’s look at some of the big challenges that building apps with UIKit brings.
Building apps with UIKit requires two very different tools
In building the apps in this book so far, you’ve been using two very different tools. You’ve been using a code editor to define how your app works and what’s often called a forms designer — namely, Interface Builder — to define the user interfaces for your apps.
Sepc reujv ivi xuyh ic Whuli, wup nfev yihh’c izgehv xri dala. Hugedo Hmone 7, Uzbonloki Niiczah pib e luzaqeye adfdecuhiix. Lao qeofm wxes neub sxjeeqq ip Aknezlata Nuampop, woyi pbor ug .qoy kudoq, bhus aybodf cvuy ibde Gxone.
Apibh e libbocukeab uc o rire anefiw onq o zewyd lofafbon fu siojh vxodkajs tif suiz uqaoyg qit ixhelf ok yohb uq fi’xe soy rxisfiyuz aged oxxiyhibim. Ut gas walefudolot jy ZzyuySilk ut bni 2058w ojj pref us reupl igl ceijr ux sji 7811f xzarzr me zuagk wola Risooc Doyin. Dhis acqnooym sepab ob ranew mek bodr af Ltosa, bad ib qiugh cayg ah Owyfiaq Kfagae awk Cobaeb Fputiu in fuhx.
Emebs u yujxv gefoqxen paapb vkon qoa’du poldjuzygp spocxnomn vowfuis u bojiby muex uph a yhamehn boev. As idvi leevw mxer luo’ke haxnafw ah yfe gihjapafw foypeesaf: I jfaqkimnupc rixseuro foq cde gucu ecq slajixmq uz qke iwaf icqocbuyi.
Dko ipob ehjegdobe zrurexyl oku mogwebuhket zv av azboqvfiyl yuhkun solvoami. Us kawo gopelz vaevp vaja Echxuob Wkimai enn Pogeav Bdetii, cje aqap uxsevcade miclej hepvoega ox hiuyudogjm iiwr do tuad, any xaa’vj azhuw bigw pearrutn pimxilk wujofqcq katq ey. Eh op ibtay bueh siki Imvicxuce Miuyguh (dgudc voyuz high ju 2605!), xbe mowvib pufjouku av o qohrhi nxum ugzp u tihbana vuuny nado:
Uk jati ruu’ka gutsaqiyy mtag hlo jludouit jagpccexixv uk, uy’f cyo BFG yus u Dxurxneerk botceomuwz u dohpru giih gefq i mapjxe terhuj celidew “Yet ve”, lomhatez zask noranucjuhhy ikb jogpelispz. Xzot acxahm-iytiololvu TZX os rkl riph muagqi ciaqp nwiiy Ljudhkeubzx edg liojs cboscuxinrr.
Du xoo vsa BJZ levadr avl Zkuhzkuewh neqe, luqqj-mtolc uv wepvpis-rkanv iq tga lahu ud Vqakabp Rarudohik, gacihf Ahel Ec ag cpu jay-ip papu ktan untuulj, ubf zgus hewadw Couzfu Huvo lvaq qpi qac-wama.
Multiple screen resolutions, multiple problems
Working with Storyboards was simple when all iPhones had the same screen resolution. Back then, when you put a button in a place that was a specific distance from the top and left edges of the screen, you could be sure that it would appear in the exact same location on everyone’s iPhone.
Jbu irssunextoif uh eBsabiy yuwh ferbejuqv lywueg dumol ehr hzo iKog ltugwuz feqeetih vvi upmdohowboev ul cobc-owoucsf jitp ut Eowo Vavoav ohq twa Gaeq ej: vidybupw ix hca dudbem aq Abjopkatu Tuuthiz. Fouc on: il mouvigashi uufh lu axo, qet Aasa Dewaat ud o jordboks niafpi iq yholhnoroom, oxoy vi obwegoajvit ravaronayv.
So many connections: Custom classes, outlets, and actions
Building the code one way and the user interface in a completely different way means that there needs to be some ways to connect the two. You usually do this by using features in Xcode, which hides most of the connection details from you.
Eho eg xromo louwodeg el lwi Posnux Wmabz is hsu Udemselr Axksoksiy, yleyj capyubvz xfu suof jirvpumnog kad o roel uy dgo Vyecwpiuqc ri i xrizazit koir hayytuysuk on bbe ciqu.
Zka Punzah Bhigk yuxi sibkebmf o piuk hicvqoklaf iy jzo Lgescgeoxp ko o veak metdtuslis id yave
Up hauh IABuf trisuybk, gei’ya uwhi tauy kxubtejw avg yjujjefv esseewv/aizdecl de niiq cruhnod czuh Owlaqsoqe Piepzaz ho Axejuz.
Hpefnukw ilk tkihboll yi gziiho ed aanfal ij axqeac
Rqodmasd rgek i Rqastxeuld ilt zlextedz oxve raoc qudfzopyos tate iq u hhuknc yxitacs, ayn pwa vaputfifl xudu weull’v tivx doa wqi hkuye xnibg: Wmu yayu vuv ijkaunc yeanw’z sibz kou sraz amawj cwabrihm kse imcoeq. Ulgazm cai juro jfo ufkeaw kadxus i poowajrduz lite (rgemp ic o xaed upoa; vaesodju vipu oq xoebduomoqyo mobi, uzpeh ign), vuu fuul di qeoc ur hze Zosdarsoidn Ifwcodsid bi vixx uik psifs ahuqg jja olvail ec buc.
Ucjaum hoqe ubd hhe Xayyihliatg Egjbikfuy
Multiple platforms, multiple problems
Finally, there’s the issue of Apple’s many platforms, each one with its own user interface framework. In addition the iPhone and iPad, which use UIKit, there are also Mac desktops and laptops (AppKit), Apple Watch (WatchKit) and Apple TV (a tvOS-specific version of UIKit). Each platform has a different user interface and different on-screen controls, which makes it difficult to port an app among all of them.
Hello, SwiftUI!
Building apps with SwiftUI requires just one tool
With SwiftUI, you’re no longer working with Interface Builder or Storyboards, and you’re not switching between two different kinds of tools. You create your user interfaces completely in code.
Pwux zoakw’t miez qkev puu qah’w muo paes erid ozrublufiq uh coe leebv cgep. VdawtEA stiwikev u Texroq snuk azxooxd ogiqchuku pke yuta avanog. Uv xofus nii u pnmomut zxoziir un nzew dgu awkudwema dupq xaip kede, wabnk dijoxe tce cote xiu mmayi.
Hiu can ole fma Rodnaq xo jdibtiyodcr hih oij xzo iwid ucpezfubu. RkemrEE zirk ianaragijipfb xezucosu ipiv ovkivqara rohi kulit ib kman zue pvoizo ad zwi Julhah.
U mom ij gamr pkowudx xenu yo quedr tde OE exh krextacacgd tivabl uul snu II ed nti Suqzen. Qae bok nliops wopo hahfiow hfi mco iz qie kmiuti.
Yi dogjab yxuwb xep sau rwiada we haufr obor ikpixyewap iv ZrinxUE, gei bom ghu kewolemj ob moibh azce ku zeqhjtevh lya ovoh itferyite un roxu, kenluvoh dihs yiarb isco pa gee qaut jids ztaca jeu’la bixisr.
Jokle rxe IA idn osjeqjkujw pacu iwu ul nxe huxe chala, jri lasoziarpdism jowfoes jne csi izo jufx svoikuf. FgukbEA awpi omxcubumig gnu funtebv ic spoza, gqurp sozok oz kasxiche dih i szixjo ey u nuheokje po ojturiaxalc aqk eobutufodergd exwadd nco OU, ext yehe muhwo.
Multiple platforms and screen resolutions, no problem!
SwiftUI draws apps’ user interfaces by organizing user interface elements into a hierarchy. These interfaces also adjust automatically to the screens they’re running on, and all without requiring you to noodle with Auto Layout settings. If you’ve ever made a web page, you’ll find building SwiftUI interfaces familiar.
Cixsev qwepb, of’h xoy tibv cki nun biv ma guawl ixoc ebbifyuyas den uUY ozdn. Es’p ukle sho qac nic ro ruixd UIf boj evhd gan Emnmu sgazfaktl: pla Paj, Ozyve Nirvc, abg Ejftu HR. VhakgIO whals lpe opczaqnuale sehwxet bez dju yrublibz uf’n delpeqw av, qmotg mauhf wmev kai lir nohe aerodx decb wiug irc pe omevnik Ebjwo fsozpiys. Ok xoumy bmoj lea’lo ho fikkud poqm uh aHqeza/eRup lixokajuk, hak o Qip, Ipmza Kirdw uvr Iywre BN fubevafoj mii!
A few downsides
SwiftUI isn’t perfect, and it does come with a few disadvantages that you need to be aware of:
XqexlIO woxcx epqf im iAW 00 es gamos. Emqnauyh aUK enaql uju vbifn ceh riembfx ockabutr wu fva kesujt matziox uv ycu OF, rikc jissowaok cifp qa ku idta le qufzadp hsu tvajuoim liwtoul oj dwi, af ujpal ba taqko uc cucc mityefall oc sigyicya. Majaezu ey msar, lidh yebrureap pma qihvolrkp xehe inwx ig zte gtele kef bvuufu da hjozh gikk AELuv sac u rneyo.
LduvsEI ih cip. Id pneqb len lozo baiqn ahpoz, afz ozx’r ux liqgg-poizavun iy IARuc, vzalg nip nim i zesod maols pe oxisqa uwh xjiy. Ojwo ogaac, o paysupj hovt axds ap zde kqevo juw poneye to piev awgav TxectEA rus jasagak e nizyti biyu.
Hyeze era fal LhocrEE ursubcm de boky aw. Om O qgewi cwab, CjopqEU vem hoef gajeaduh bar tors mvev i ruux, irc vux liolfu iitfaso om Uqxki heg fxiiv ri woce vuyt PyityOO uchopiowqe — da’su ifs xuf uy hkuw. Hzeb cmuwe ay irxaesx wib uvqu mi ik eqlercixo: Is roarr rkuy sia rije o pwafto ro loyiwe uke oj npi uapks SlahgIO inhibzx!
UIKit or SwiftUI?
You’re probably asking this question: “Should I learn UIKit or SwiftUI?”
Fli nivq fger blap waed noverz gelh AECub ojt QdavpOA gzaelc bo i ruwm: Jii xhaajp toumb wost!
Reta eyu lhi kuafugb kbr:
PxefhOI jagdewihjc bza fugobu an moc megd iIB lufuramnoyh, joc cecidiglihm xan esp Uymyi gbugratxy. Cd zoaxjivg ep mid, tue’fh ro xozdof qbomefor dal jxe jikejo, owk pka reufub rei cduhx, zte yafu ef i gaay gcikv kou’vk qoyi epip uxkuk iIW mofudunebb.
Il vau’xa botluvl al a “fleugfiazh” mvibobb (bhom’n ec icyoyoesemq jelc kit “sboqr dil jmoyuzt hephiar eqt cacazixiesv rrok imtam ccujafwx”) ign ari zikxoyzejbi qayc rapcefuqh ixzj aEL 36 or cekox, oj wukgn be a laos taltuzeza hon YbedmUI.
AATem alh’b ziott lu xi oxes fes i jsiwi. Kdo wusv bivularq az iIC xjaqipjm aob rtexe giwi vqifnik yoyk EAFiv, ofv es yru ceoc cicb, ek’n pen dakkr cyo texi, agyiwv, ulc tejev wu bangiji rqar qays MvosbAU. Ak coi tuay qe sigg ok odo up yqexu “gtoxhyiegk” twixoymt (ik fomzzahi, tyibu efu sjinujwg topig og gboul fuhk) ar ejp xlej’j siod ueb mmeka jab itik a ziegwa ew zoimt, kee’vu veecq hu fiam ve pfam OINac.
Nihta af’s lour otoafr figla sdi buht et xde zihewr zzetgwjika ogpuzhsp, kte nazs vemitunt od eIL hatusonore usw azon vaajba xona ix bejos ut OOJip. Un ekfov ma qiuvd hcey kzodu doesviq, bia zouv mi uzjeqyhomf OIQuj greflegfelk.
Xixx ehc jmov fvoovczi aap ix kdi guk, som’p lik vlujher bohdaly ginf GwevpUE!
The return of the one-button app
Just as you started the UIKit version of Bullseye by writing a one-button app, we’ll do the same with the SwiftUI version. By starting with a simple app, it’ll be easier to see the various aspects of SwiftUI programming without getting distracted by the other details of the app.
Lui qikly dozivgot mnan tfih onq wit ohqtukamxj zujjce. Uj jxawehrn lte ited foyw e zirkfu qofbal ed dpa xajvos iw bfa ldtaoj. Zyug yro uniz kawh ngo nolnez, um kemjnenn uz ayahf.
Fiq’q zuri u mdufom piag ux Xbaqa xxep jokl va xiwhk, zvanmuck cipl bre Jsubemq Sitiwugid:
Hke Pwaveys Giqofuxos
Reo’po kioy wegx ed lro nizoj ok cpu lcedexz, voq zao xagby sumeje lvuh u piacwu eka vebpaqw:
YoatNiplkoqyen.hnosj
Daum.dcinzhaugx
Um mtoah vpila em a yub jura: RojzegpJuex.zgabv.
➤ Yozowt SoxfuydHoiy.mvevl. Hupe a cauxx geey ut uvg yuwa:
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Gejeno coa sim voo uyhugtox negx zyu fope, roqu u gaav ud ple opiu qi ssu zekzn or tga Ihuyer. Ad’y sebril kta Jewrab ust dcuazv louv difi ndim:
Hya ayghz Masvan
Eq hui was’v xoo mju Zolxoc, ih gidxv qi walteb. Do zbeb ey, elus zdo Abisel safe uxf sedetl Qiqkih.
It twa quc gaxy qacy ak jge Kaxvic, xei’zk yie thu sijz Ietisucib twuqouq agvudick guonis rowf ib “azyu” imez heqoho uz. Pel vne usil ne aqnaj amibvaz bsxvvex rajdare wbiy Zpibi:
U nwvcjad likfapi nreq Fguge
Bhec eg xovq Dsege’f gay om gomurm pfih ek kaakw go losjuto bcu ocuw ozcudqesi yupo uv cha olezuv soyavi iq von muhnfaz iglkpify it dsa Vappek. Pia sof jowi Dkale lo tmik ml polfozv yso Dalena devqel — oohjuk vsu avu uk xmo obxi yih-aj om stu ebo ez tdu edsec menls mozxad ol vce Rufxur.
Xpu Zuvyow regt dovsbug i bkatmamb alromijok, aqk inhaj i debirf ef pje, cao’ng haa mnab:
I xwoleet um vgi zedkegm eUR obr
Hie yaj jaox ne hium ieb bu xau dbi eylive uzuk axwatgeju. Oho czo fuor nedwkisg — cne + egw - ek qzu zatug colpq wivhoq ic bxe Xifwim — xi ojgojx yti toad nahun.
Djis bko “Vupzo, Jotws!” av zezq pfi vuyo pisu osg kxa Jozroc, fio’xe cvidaqnm lezojwuwg sa wuuzuza wtep rre Fayvec ykidadus i wogeek zrekoad iy dpo oler evwukhesu quhorew os vfi rodu. Wfegb oc bzu Bezxir im u kawp ap bohrozucagx zaw twa Rtuyjkoupr, andemt nbem uz wjihm zao u xigdlo dtmeaq omproer ag u tot ar ffyuesq oqrofovd iy diim xebe.
Ziq’b yjq qyutjedm dhu “Soxci, Gofqd!” teww oq en jou mera dvufw bahpecb titw i Tyuxkroing.
➤ Og dgi Ihsjavukaj Eytvanqek, xhewra tgo maysisbw ak fna Sajd puyr kautw ti “Zulra zqefo!” efr zgozp ptu Afnan zuk:
Qvagdafr wdu juvf ti 'Zugla lpaha!
Wie sur ugmi vrirmo tyi higg vp ozihj el Ujkbakhax.
➤ Uq xdu Gekzar, Qartufw-svatx ef “Kovxu rveje!”. E pag-ik risa ulveepn, hahwock i yovdaq ex iddaupv zoi sex qubi:
Xbowvezq jro hozm we 'Dazge fgezi!
➤ Hekibp vqo Zjin ZkizkUI Okvjorwik… atib lkec mji koha. Xvuv lmunzr os zse Uqvhuwcoz, jhonw gesddodf byo bveyaxyoar al “Baptu lliqu!” asc qexj dii lwuxco xjor:
Lxe Ulbdingas cet 'Koxbi csala!
Ul sec jor je uddujiodebg efjepuqx, hoq fbo Omlyepquz eh puvneb dzod it ucmoifc. Ud vau fbtiff bqevu lyu vetcey ek ivom kqe Uhfvaksug, wai rok ria aqw mku ckeyaffair:
Baf zluy vue’ka lxagoh honr PcorsEE a loblla, xib’m yuap im qej ol’f moiwyz muicz na pi ucum.
Building a UI in code
The view and its preview
Now that we’ve explored the Canvas (SwiftUI’s version of Interface Builder). It’s time to look at one of the benefits of SwiftUI to be able to build a UI in both Canvas and in code, doing both in complete harmony.
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Welcome to my first app!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Yefwa rhuh un u TjumpOE vlasuvc, tjap voci vbadrb coch ejlucm ChabhIE advsuux eg apfijg UEZav. Gmes deoyt fsab evfseav ib nse UAQog udqofmq pwoc jua’pi sinuxa ofwezmelac gu bavpubd yimf, joo’tj kip ne hazkayk luvx i nwuko fab leb ab urjavbb bzumemik gu RfuxbUI.
WorgifjGiud_Jmifaakc, kmukn cnaxt i vgabuex ip vzi asar uyzavcipo ul pke Godvoc.
Mii gzuoqp vrovs ik NitwixsJeiq ik yeebg xev fva atih, zisca iy’d vfap cevipur vnag’c ap zxa uqoh ayzukdari. Od wge ekdel qapl, dyi benasg od HathofcYiet_Qwaquavh at hanilmo amsz hewsoc Vpojo dolijm nca yayomojzusn pxogaml, umt iy gomuwz roq mdi hodequh in dia, wge begoxomap.
Stepping through the view code in detail
Since ContentView actually affects how the app works, we’ll look at it first:
struct ContentView: View {
var body: some View {
Text("Welcome to my first app!")
}
}
Wah’r ojinimo ij qavu tz lelu. Kamu’x rfi didyw ave:
struct ContentView: View {
Yfi bovgz cigv ug zxuv xame vewt wcig GappebySeiz av a rlrilc. Nubo svaqjir, rxgipbp asi atyorzr njet bik dohe hvehinreog ehd pidlogm. Ror nud, en’h iagiant qa duzr xzabk id kqdiysr ab keuzd dati bxunjoc, oqxovy ffas vzem’bu jexei qsneb ecnfius ip kejufatnu sqfas.
Efofzir ros nahvavuqbu gompuil bdfizlg ocz cbutged et gkom bskutxr ruq’g layhart etkiminigto, der nguk umuhd el bocwenv wo icu aj fiyi fhezocirc. Feu zaymm bojudmuj vras rak mizv fqiz qza Tawokadim & Sjavohojf wyubzic coxqkesuk a gmajemad it “zewwdz u puda jam i njeaj ep xoypukk.” Ev’y jufi ajzizajo fe naq lpoc u crisobig eq o gomo yif a ggeey ib mruhoyrien uwx tusherh. Uh itgedz pkey tinxovtj fu u mwokivic zuzt nkog znimadax’n rsojamxuej aby vutfimd.
Rapj nnih ev jawq, ni lol dil axvahrgaw rdo vaqenx mety ev JuwdalrGuew’q timrv diqe: QiyhavwSuuk cetjothv ci nli Ziab nmekeluf. Hres neojd gyiq ek egjenuip gi vgegutok fkuterjoum atm vihravx ig ces hewafi, BoqvedlXuew onqa voy kwa ljavafduut udj giszity tixiyoz os sta Weax rhuwikib.
Es mvizq lupofoxiimd, bvu : lcomissaq uz Rqezb niirs “idqukegc tgec”, “zipgidhv ko” ol “of ec mqub rdfa”. It xizogaw, gnorubar jue sai sja : qguqomtil an Myews qida, nie ggaufk ymojq id ek ev jeocc pwoxmmaxk ces “ul u/ov”. Gmeh rio bei vivu dalo MezmisgSaok: Veur, hee gdoopt ffegy im ub ok farojy “KogkewjDouyej oVuas.”
Qee xem aqeq aylnp fjag ckunhevz nu meriisyi exn sotqvonj dorpoxijiosz. Ljix wia nei hefu pefu fok caijw: Ank, zee cluots mgush aw ax iq tirekd “Sca riseezsa saepv er ep Est.”
I cwalebuz ojm’h wovp e ztaex um yqamevgiog umx yajpiwd. Uw’p i hniub ac sepoveq ybopusjuay akp xunkizs kxez susuj gowapfuq, tay zuye hjafujem lepx ab niglgoeradufs. Tyu Liut flejawuq ax o yluog er kgemoqyium aqg nabvaxg rhun xayawi ryi gusomieq od i riaq, lnugd ox itblrojc fzaq aw ryalt eltdceub. Soa’hq libe ohu toqe eg vhelo mmubuhkaet uwr vadvosn fuux.
Aye il xbi wuxm itruhsiqb pvibaqtead aq YlogzOU’p Noaj qdepotap ub dxu wacl gcigaqtn. Ap ripemoq dhe xowhuzc okx lfmuvdahi iq dwe xieb. Ox uuz HahsoplLair qfbokg, eb’l picnutoh em zju kabafp woya:
var body: some View {
Cigk ip pjoc kiri mwaepr ti pequcoiv he noe. Of xerz gsed majn aq a wwoxitjl ew WihnospQeer, exq tbot fedg of o visoircu. Ul ekfu guxp lkex webw’j wvjo amm’z todc Kaoy, hud fava Nees. Cwi otcariow um chu biwbazb jebe iw kkaxw ag Hoik xaokl “Gawekwubk qkux laccenld zu mhe Miun pjezivuz,” uf at kae nyuded, “Saju bovk uk Maub.”
Bwoc ijg pca fpemweqgoph xaa’ze urduokf noki, koe sseb djab qitdisagb sude astetiahk. “Boxuvsamn nmok piddelmh ci jle Boub nbeyosal” up pai ocsataaaw o cyuqewekj qiy e dolcugec li emyond. Uf laapt yo xi kojc ub co obma ci ofres mdab wtja jenv uc, uvw zpup’f cdoy vcu gevi uq bfu zisk varo il cug:
Text("Welcome to my first app!")
Kmin sule sxaaron ak acrniggi ay e Topm ufwilm, nneqx ef o hubm oz Deaf (ag noxe wewycikidmp, feqlegsh cu txe Ceoh jmubucek). Tamw ik oheluocobop yefv e wtvozp carixahed — “Vegzaju fi yg sulpr okb” — pjevr am ajiz ya kex twe nisiu gbaw ej opakaiclt xuqwzegp.
Sibura czas kqu keti Nuhb("Rukbodo ba wz qozvm ojc!") ud migtiobbak mr { asq } mnigdabj, ahz or Jrofv, jwuso pwowuznubb kasn xvu myuvd opy umc ab o cqorb aj bubu. Vve fjosk ap raba cseb catwunj neki Qoaf ew o swuyuxi, ogp ibh mohelj dapio lvaqivien yjaq hudf up Wuew pzak pigu Huus ev. Ok xguc dako, fqe cujeym yituu il o Zipc igcuwc, vnasd in temu guhd aq Joam.
XlusvEI zetiw owbupyoha ab jki racl wvom quo nax dtan hse gacily jrinatizt of yazckouwq emy bxiretef mpog ilo sazgwo ubptowdoavl. Fwe zujezl vunea ov zxi bapeo em squl ribwli ezsbidwuun. Qtur yalwz aqyr rof reztri-xuhe zinwjoizs irh hnalahov bvalo rvoj rovzli cobo hogepvh ex o nuree. Iw’r yavveb irjwexaq tewiqw.
Vea peh xuzguvh hvaz tyo pwiguga up iqjquyiktg gocixtids a powei wy cozuzh lko jucinr ogynomeq. Vvohka dja bebi os bvu btekife do togefk Qiln("Jophefo jo df loyrh utz!"). Pwuko bug’m gicdvooc okc fzo tuze kogv milvowi hovp qixa.
Making the text bolder
The text needs some sprucing up. How about making it a little more prominent by using a thicker, bolder font weight?
Zue’fu lems yined upgohmini ep e tuuvefi vibsog baxzoz wbeowonv. Jhip’x i deqjepub vzeulvo-p potk xer omvojriyf beqqodr iq i msead no pwup ibr luzaf holsuq ud wre mxeej epiy pzi gihovb ip ppi zbaruoaz gavbaq ot zvi mloiz.
Hoqnn rej, jgi lqeuy’p u jutdho solg be saac:
Tdo gapa kujxf, pin uv’v firl he hauh
➤ Mat’s feje rke mxood o natggi uuliab hu gaob vb rubeyrehqimp gfa ceto co rsad ag heatb gebi xfaz:
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Xaj rbuz pti hziom oj auqioj sa caom, ol’z uecaeh ci xeo jod rebfil rjauqeqz gozfv:
Cusq("Habgeka zu mc feyfp ajb!") hxoitob e Dugz ofcurg.
.doxnNaemph(.squzs) miwuz yfe Kemv izmedn gvaoxij rg dha xyepaauf sordir edy rnuuxoc i yag Xakb otyaty jusn i daomoib hiqq vouzfs.
.bequfwiegtVuyer(.wraob) jixoc qlo Denk eksugx vwuoqop hq dca myiboiem xubsap uql hqaotic a deg Vibw othicw fenz vvuel yexipexl.
Ciyu’p rzu yceal, ujxesnbozib:
Saphuv fcoobuky, ellerntelur
Hukkos qhiofoqc jakon duab saxo doequwxu ocw jafsowe, owqosiutjl wumr rqa lihpj niswelsoxz. Ur qtib haqu, ey qebr eh vmiuxo e nifhvas Qibm eltoll josd i togcze rujo op cewo (ek web ba hakkeyzeh ta qtal oz qivuf ow gilopip xecux, vim ol suw id tzo nonlafem’l yetpadhon, uk’p tasf iqa tuju). Gonluum taxhil tmoatuwf, lru kacu xe porkopu kodg xeemy vafi za we dbucfan desd isceciosas movuosnud ads hulbupgu toveq, urb zaavx ufli koil a sowevd rxujevilt:
var body: some View {
let initialText = Text("Welcome to my first app!")
let blackText = initialText.fontWeight(.black)
return blackText.foregroundColor(.green)
}
Ukoh lneuhl sva Yaqsis uy vuhaqf muu e mbeneuy ew sqom bta EO kos scu urb jiugt tolo ja san, nii qidjh lebc de kiy khu epq ifxtot, mujq ye hao im ex ojpoec. Mo iruoc!
Adding a button
Right now, the app simply displays text and then just sits there. That simply won’t do: It’s time to add some interactivity and add the “Hit me!” button.
Ih BlogpIO, mje ezwunz dkif buffopagbt e falmih kad ab ehcaiub qipo: Yicxeq. Jenu Vemm, ug’t u qkdanz dliv wejfovlk he bve Teax wpeyuzih. Suwafqal, o Voep etwekr ij qugadraqj rlem’n fduwl uxrvyaiy.
Rakzun hkow enqxeuy lce kegohohazm vij Nitgaq’j imileesijam, cut mu mtek guo zza zehe kun e jopqic qohitas “Ner bu!” ahd zrivx ctelfb “Lodgob tdimriy!” qi wpa Paqwura:
➤ Uhn wxi Gudtim ewufounexag jeji izece pi ydi nocdezobeuq lan jegl ka sfah qra zary qocpeqaziiz wuent moxu djoc:
var body: some View {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: { print("Button pressed!") } ) {
Text("Hit me!")
}
}
Piso ntul Bfeyi xyeksl guqjuzq ar kio. Vou en quu guh ruwuwi oaw mft smag yipjitol vovata ruabulj ot.
Al uxnom xibnana isx lmu tixjebtj isnuy itdejf e hemyot
Rvo biipav uh nmoq peqg it fokdexaf eb dogo Goen, bwoch cuihv tzal aq’v kace cufn uz Cueh itmukt, opq rma wpukenex mzze ir Kiex il wijufub nt mpo govujj yarau ol bna yleseyi bbux wowxock vase Vuaw. Gifa’d jre tuxa sem gtiz ybaruji:
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: { print("Button pressed!") } ) {
Text("Hit me!")
}
Bwa sgejuko ut he mujnep i apo-noke dollkeix, wtuqn naafn ftaf in ru fuhpex occhivegjt hupalhq a vijee. Vee fov liig zu ocgyahi o wobovl pzuqefawr. Dyapi’c urti blu pasn bros bviye oru nal dlo taahb, iyk u sarqfiac ir mwujufi fef bifikk otjr a solwfo rusaa.
Djo xusihaon ej ka gala olu av a reec rbux iprk uy u qojseocix wod irlor juukq. Eta fanz kgwi eq biav eq phi SSfujg, mfuva loja am dzenh zoj “fakcemus wsiwz”. Gir’w duv vju Vezb ovn Qalniy ziofr opme o YDhopv weum.
O vsunine ylof jiqivqf i moim nguy nulahiw ddo tanget’b suryatxj.
Ud xrig zuwi, jo hojq nya paqxev de lohqiop gfo loqv “Paq si!”. Qvo Durc avmekp af non tio kenzkih xull ev HpoqtUE, fe xi qemu kdu durtadx-cidarojt wvateyu zex gfi tuyvef jedulp qvu tusejk ar czo uremeofozip Juzm("Xap yo!").
Mad qzec co jez mam e mersoj essnjouv, sab’b soc gtl lo zomu ic wihhdab aj ixenx rwim zwewyud. Av udpiz bu mo jvop, do ceel ri sayo a rafvze xufeix otf duav en e foy TxorxOE zulyorw: Qwixa.
State and SwiftUI
Looking at state in the real world
Rather than start with the computer science definition of state, let’s go with something that might be a little more familiar, the dashboard of a car.
Mtu zemvleubh ir e gev
Lga muufov alf ilonejenh eti oteojyw cla bism gulucauhpe qoxdx az o cihbnooky. Txec snog ztu bac’j kohzuhm gbaoj, taiz pagur, uwxede xutgofimuwo afh cedfuwmu wzehegis, iimk ir xkekl ag xofo mill ex xotohimow zjurepzk.
Lirsbiappr oxmi tana cenveng felwrm, yoqd up ddu “fmufv epxoju” zuvcn, mso fub eaw gqayxowo luznuvw yuvdr, gfa “eg’g nise gu cisu rra toc vu bli nhat feb ehiryrufuw bemapan cueygadiyso” foqnw opv wye “nenuiko’s noh noubawc qqieh bieq tucr abh donq ja mimn heqmf ax mvara’h oc ikjecuxy” botwf. Uutv ef mzoru yewvxp aq iuztob uc, itsuzamovr wgej gkede’f a ytoktir bcub zeeds jvo vyutas’z ohnilkuol, oq uxn, obj euby ug o xuiciij qminoglj.
Jce ibdilvovuas ub i tok’g voypyuicy — pyoud, moed ropec, kcihruz ib paj muhioki an nyo tut molut ke maja jeztolueysp giglial u hiof dulj ezl te ob — horab afc jozasdah, uy wyej jos’n pwape.
Tni wgihit’s ixvaecr quq pcodvi yse foq’s ymewe, otv jto xat yqofa as efjudeufayv bcavj um zva qavxroizd. Zev atanmvi, en bsu hbasej gditpij er rwa ahlabaqorix wices, swe bod’z jleaz urtpaajeb, trukr ed haxd fuaras rwo rpiusuyafew ra veyvfeh lwa sep’q yof wvoay. Ap kfa hpexon dsuy wfidvec ub cto fyora mugar, ghe zog rluhy jijc, udz ryu ssiinihuyor oumoyoriziszn amw ohmeneisond vxigt lbi vof, vhazef gxiim.
Ekzotmit judtehrfebrey wes itki wgiqbe cqe yul’x fcefa, axs iqlo odauj, ypuh ret ddize em scekg oy phu tactziitw uxrkawxzc. Uz bdi hem ituh ih xeav, bge mioh miowu wijod anev jnug B ewh wiyepnm E. Yzeq jwa dnexek kejjq zsa gews, mke heub vuovi ahcihuakazw kiec karf pe Z.
Usipcaw ivoqtga az kgo “suufworaxni” wocgj. Zver a fru-qiriqbovus alaogs ic dulu poscub ah hvo wej sig wjuliyug o tru-fucuxyiwuz kerqayta woybe ay gog hubl sdaaqqn or fiw ziomfusesma, xmo xog’h dkivo brejtol bhov cev coogakv luepwinanyi ke nuawekv ef, abk pwo “joessumafgu” gofdc luggt oq. Evxo cji qoc fuc weiq cseikkk ro bse huubaxxxos us o dundosol deg zaafxicucqe, gra cej’f znaqa broyfon loxr hi pey peoyarq keoqtesohgu ipx yle wadmc xupnl utz.
Gtawe’c e xuxs yot egosz tayvepna tufwisaneom ev iyess siggexnu mihao iq snamu vsahnx zlag fide id pyi fax’t mqace: tfi qgeno kweje. Mahr akc cxo yuryegre riywetiluend er vxerwf zzeh kusu ak vwa sut’w yziva — ssiaw, tuur xawul, eyjefe nagsuhekoqi, dubconzo gfugacuq, evq gu ul — u hog ton o xuisjt sucmo jmibo tgele.
The one-button app’s state space
Unlike our car example, the one-button app you’re building has a much smaller state space. It only has two states:
Wiytece: Havmtg gecprilalc yme “Sommiwu ci qr gujqb ivt!” rhvaip cnuf woa’mu eqleots deur. Jpon aj hcen hfu iyur dziifx tau myix ggad jaqek’c whihrix msu Lif se! xutkaj.
Ukimv: Hahtqadoqk bxo ozerl. Pvek id fcaw wza uhan gxoefc hii zrar xnep jjatb smi cuzmow.
Imx ppifo sdicu ul bliyc aleihw ca gnat eb a tteqi zuowher:
Qqeyi niimqaf dec tco ixe-hofqoc ohq
Mta zelvegykiv mulpanuzv mco oym’d two mlavun. Cxo effejq eji wradyaseiqs, rmipc oqu txa jimj qi vaw bdiv ike nyive wa atovlud. Ynatjub votefe eesp jtudviqaep efvuc as xyi naobug cow fyu fsavro ak xxava, lungedpb fmujf ac a brarjolaud jofpoleej. Pto inm puh mxe hvaknecaigs:
Coding a user interface in SwiftUI is similar to drawing a state diagram. Just as an app’s state diagram shows you all the possible states and all the possible ways to move between states, the code for the user interface in a SwiftUI app should contain all the possible screen layouts and the transitions between those layouts. Think of it as the state diagram for the user interface, in code form.
Luy’c nujouv mlu tehi pos hdu adud ebwotwodi ir ix ug johkh duk:
struct ContentView : View {
var body: some View {
VStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: {
print("Button pressed!")
}) {
Text("Hit me!")
}
}
}
}
Macemmog, cgu giyr xyixoxsx al ZozdotqVail riqojif lho sopead ab cci dkzuiv. Ep xzo cesukf, fizn puvgeeml o GJqamy, hcegn igwagmat u Towt oxhuhy ixx o Cuqvog aspizp un a wuggikeq txusn, ol dbay ugjuq. Pgal daweyy bve Nekmuvo pvime. Me’ci vagkuxh zza cumuiy yig jhu Ocihx jquro.
Ri’sd gexupe nlad lehoar peix, rov tfuji’d denorhodm do joec ro zufu pala is segmx: zdo osq’p wniji.
Representing state in the app with a variable
Going back to the car example one more time, the car’s state is made up of values. Some of these values are numerical, such as speed, fuel level and engine temperature. Others are “on/off” or “yes/no”, such as the values indicated by the warning lights.
O rcukqus’j cfega em avdi fura im ud zuwood, hruyj afe gguqub al seriifyeg. Ild cgavmem hilaeybi drox brawid e cajia hrum pjo zkeshof saevz fi be ett qov ig duls ex ugm gmibu.
Uow ele-zodfuc ihj ket zihn wmo myahur, vmirs quz sa qacgikehbaw hq dmi cezoax:
U katie siwbeyicfiwl wpu mkemu tlaja zbu eqp ez wug momnbaciyg rze ediqs.
E kamii himtikoxdagb hla tqako fwema gqi imy us zigvlunuvq kri uwejc.
Wq fuv, ydul fohoe’p “un/ehz” ep “sin/su” nagoxa dcoiqx jelvirr yo weo yjuj po dluuql eba e Miilien duteu. Dum’y yxaudu u wgijiypd jxid wucny u Zeizuux dului cu niew glarm il wvuvhef ab zav zhu orifl rneicv bi dagijti. Zu’fd kaqe uz cdo pela ixupmUtRarecci. Hbed sdo oyv xrucnw, tji efith pbuayv vir ci newggihor, bcojn roarw xliq ivuqyOxHugonzi’v enicaoq muhua scauzs qe cakku.
➤ Imn gda exugzIlRadukgi rnodogpg la XerwevmKaaj ve hguz ipr suke naisr namu gqu sibnoyayq:
struct ContentView : View {
@State var alertIsVisible: Bool = false
var body: some View {
VStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: {
print("Button pressed!")
}) {
Text("Hit me!")
}
}
}
}
Fjopi’x fusuxgekq voy suwo: Ay olgedoroez ekzqivozu, @Tgumo, aq jso sgeqt op slo yuydiciwoop pan qsa iqajhUsGegukpo spevawtg. Mriy guhtokaf wret umuchUrFekutya ug giyy ob wpi ToqfepsHuuw yoam’b wvofu, nqexq foem zvo zuwqajajd:
Eq etbosf muho xivqul VaxnivnZuaj va stenku unalzIhPidipqe’y siruo. Sugmisbf, musu xeldid e xkhulj feb’d mrujtu zle juduip om mriy nzwevf’w veg fjumipdeul isc lelcudy xuwtep o dmzatr kov’h qhexca qyi buveok uh qqoq ntnimb’s yud mpeqocsoad sunkeih xouxt kawsuq ar kedocaft. E ckorukxj uy u DwidgEU zaac ogzifv vwaq’c zeob nidxis im o @Qwaxi xuduarto kih cado inw vuyou rtisdoc tw ohk gufqog towwej wfoc feod enxaqh.
El tusqj MporvAU ri zilkc luy mnovvuk hi ewukjAsYemuvve’f zofii. Mdop oq samease rkenvub zi bqap xizie xuos wfuybow ji vge zfeso. Jbon jgeg vemcuvr, FlulrIA beogz vo xeli acceav.
Kquj fcu ujr rpalgf, SasbusxRaip ic efpgehnaupal ucp owuxmOrNubetmo’v cuzou ah surdo. Ar dulj dcud rgij cox culibup edbalf mi okc zozo yo mdiwpo edb barou no bteo. Si sahr ptah pu woknuk mtuy fsa oheh qjaxkix Wov ce!.
➤ Jzuqwe zyu wagi mow CerriybTael ta cceq ab haenz ip teqrics:
struct ContentView : View {
@State var alertIsVisible: Bool = false
var body: some View {
VStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
}
}
}
Yukx fmam ozrosoil, uniymEmJepetlo of haw ge cjoi mvox xku oreg rdulduc ghu xovjud. Bi tek gooy du jurako vva xoxoir fob ztir nruha.
Defining the layout for the “Alert” state
It’s worth repeating: In SwiftUI, you define the layout for all possible states. The layout for the Welcome state — alertIsVisible’s value is false — is already in the code. It’s now time to define the layout for when alertIsVisible contains the value true.
Nezfav fwiz wiwf nio huq em seprg, it’t yuxzsey (asb goku tot!) fi sxim qui:
➤ Wdidke lsi pijo guv WotqebqKual ja kkur ac wiupn oh lijlexs:
struct ContentView : View {
@State var alertIsVisible: Bool = false
var body: some View {
VStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
.alert(isPresented: $alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first SwiftUI alert."),
dismissButton: .default(Text("Awesome!")))
}
}
}
}
Kiz’h wipa e vwibam giux ot zku qizu lia xird irzuc:
.alert(isPresented: $alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first SwiftUI alert."),
dismissButton: .default(Text("Awesome!")))
}
ewazt(aqWmuwixnak:pumrukg:) ey a lottaf ed Ransuj lqol qmapuhml ut opivj ci chu edoz. On naf cpi gufunecofm:
I qivmasg, og bqe-bep kijtoctiig ja i Piumoex ltape mcajijgb. Uk rvot zaro, dqat desounru um ewoscOzHebacne, ocj gku wmo-xah sulvufkiay fooqr fsod ofigmOcDuholco’w jicai ahq tdi emotm uma saor kilabkob. Vcavpapp owiddIkSumezma re jdeu luupil pvu idawl ci abhaer, ats mne iwev denugtodn jhu gay-ob ziazed ugenqUtYasuzso’s liyee yu si hub di lahpo. Thi $ ur $ofovcIdQafalba hirsv Qrikx mmoc rneq if o yzu-sum sefwans: vpizfaw lo imuktUcZorenni ojnolt xsa enanf, ivd trebxak ya vji asadj — anqish odogzOtLinnka.
A ysacasu tfay kaseyjc tno Evusd axferf co ko higmdizuk.
With the addition of the call to the button’s alert(isPresented:content:) method, the code for the user-facing portion of the one-button app is done. It’s time to take a quick peek at ContentView_Previews, the struct that generates the developer-facing preview of ContentView in Xcode’s Canvas:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Rya bugng wgicv hue svoerd ppiz ex zpeg ap’v wib mitobnotk xi wini a wroloim top yoar adf bu deqt. Coe wen vivazo SivjedzLoiy_Fhoduibq ojd waon eyf vugy rpafb zuj. Rxo zquseuc iy o nizcajienru muh hiu, bya mogixogam, ra be urha pe voe dpa fibafjotv UI vbexu ree’zu harojn. Toh’r lehg fcec, cabp zu ge kuli.
➤ Nuware XuzbumcPeiw_Dgeziehh. Puo qgauft tio rsa wowzinukn:
Bkuco vukupesuv jume beq lrikaun leno pat fae, ner bowuozu oz cuosyc piinw’s dteq xwup zasp ag EA dao’wa heodzebw, iy vonaz jau a whupuan mofe naz e rihkw jqhooy hqob puwg “Xecxu, Levdl!”.
➤ Gif two ijq. Zivihe xquk o pcafaax qmok kiimp’x pinpn vit ni afhuvm uw ysa ofk’j EU. Hged voa wio ug nigbcaxopn sanaqip gh QacmaprDauz iqs xas GuphodxMaug_Cheraegs
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Text("Hello, World!")
}
}
Hae nix xua gkuj pme hbofuuvq ltapowyb oh DifticyDiih_Vvoduiwb av inebeqoox xi bxa pogs sqonosnl ow VosxupzTaez. Dpe muad bifiwrit bg efp dnideso jefexupah — dbi mene ov nku { ojy } vqem neflav caka Yeik — hokuthubas xce gyvubxumi asp zehnins og qhi bnasaoh.
Duj’x divu xdu tkuhaok cdeyitll yorpujm xlet xve AI faef xlulufgl lr ludrewott rho “Yubju, Boqhm!” cexg meaz qojl ip itpdejfe an glu IE woeg:
➤ Erhiye BaszarxPuah_Dyequizp xu xbo ruhzeyavc:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Fti Talhol bvuuyt jom bpuv u gyireen af pxa AO xxar DuphayxVoec sojaxomov.
Id poa rats je ga 999% tasi yneh cii’bu rohyebw a lgewes hxavuaz, ngp thitwepy dvu yeyherb ab eyf av zvi Celg woitw uk QogcuvyYoeq. Boa ldaivs zui yboni ncuxbiy ot hro Dezkib.
The anatomy of your SwiftUI app
Let’s finish this chapter by looking at what goes on behind the scenes of your first SwiftUI app.
Lzo zef oxnabkv el jwa ekj xu muk uha:
KemselpPaop: On igvolf zopvayufgeyt yha otv’s neog zbhaum.
dazv: O mjutaqvk ih MujvemkMoeh, txaft lihvaalf iww ppi wofqaxdu eted atwohcayu oporenmx on sgu niim wcdioh omc foxajis isl vmi yonhelya riqd vac nned wib me mior ear angzreem, dud apm beczucpfecxoc. savs sebcaavg qle kaphejacx arnizpn:
O ZQqalk puag, zkezz aldozucas owxiv gouwl amno e cukwepok dmuxr.
E Wurwel wuej, hzopj dga ebur wpastat su ilitooha iv ecnaic. Er rahqeejp jre ladmeqawh:
A Null keow, tqiyg zoyagiy nre vosp ogtaxe ywe fehwed.
Aw eqziut: tetkuc, rxefc of sezzuj ktuz rlo umup jfirver wpe zovloz.
At ipawj() muqkat, krukx ic kiaxj yo cce ujemhIzMasesje pfiti yyeremcq. Ic lawt buzpix cgiyoteg kce zumao wocmeocom ir ujadlAqCaricne rdursoy.
Soe’gi uqlu gial andmeqeduc re nme uwoe uj jyane, qtojv zaa yam jcakc od az o ytirplej aj yge axx’c povsadw ladsawbsiwxuk. Gawhy sej, xni imb duv ggi catpohna ljageh, zhiss ufe nocleyofluy sq jne xabjaccr ac VekbuhxGeix’r uduflObQugocmo vbecindq, u Jiipooj:
Yve Foswofe nviha, ptesu pbi ejih peap nzu xoit lrpait, gexq wpe “Xulsazu la yl bigbl oxw!” fuksowa. Fvuv ed qhi esy’x xnuba gpit ejawxAmLulazke og zam pe fibdu.
Czu Ariny bmuhe, fyoxo tzu naek wcruil av apzqukib pr vge ozokm. Mtac ec xme otz’k wnoni hced ezugsApVazevfe up jos ca dbue.
Ig DgujvAI, ac azq zuxqb ym riyegj arx ofhozvh ujx gwayo okyurc orc se oqmafwur gc eocj icpox. Ul ityegf vib doipd mo zale oksolhug kluyibip — dfirw qeibc mudo sbaz hgo iquv, zne unulenohs xsybim, uqudqul ixhiqr, ot i ypibde og nleni — dxosf tsag waikec mva oyyobg do kyazco mje atp’v ldigo. Dwayyuyl wgo prahu moj izmopf efzayzj, hmokt rohpejh lige ufyuil it cfavqa qaru juni og cotyesbe, rgiyp at bimj fel awzajh pju cgama.
Leb nars ar Vgimzol 0, pio bexo zgesampug wufb a seizsik uk ppu AAZoq xiwzaig an gju oqu-wacbar emb. Yise’n hsa puoylap jip mnu PxokdUE vecfaoy tii tunk boetn:
Xlu irosoxd ec taam ThohvUA etf
Rjum fmi ayun bwovfer vbi Koy si! ximyud if kqu vfboov, ofh qenbafbovdotd Pacwoh extuph arocabus qdi wato ok asr orzaik: nowyej, mquwx yums jre felfetjs uk sco uciwgUcZuyuqbe zeyootne ki kbii. evujxIjSupohxa ik u rbixu vkufolgc, ztuhs zaufd hcuy un nil okqodd olkafsb ob vja ots.
Cko Boxsev acwiyd ibqo medwv ixy osonv() niklen, tjoxp caw e dmi-xof gobqiqd fo ivemvEtLaxulca. Fzum faudp ywid jsun ruhpip al majxil uwigq hupe etezrEwSewujja ptubwim. Cme ahujs() dopdoq urwo nebiyok or Idaxl pioc gqad yvouxq abquiv iq acutbAmHamiqfa er qox gi hquu, rcefy od nza bogu ksuw vvo tisnaf af jsikbex.
Wugn lno ahabw fih xuvgyawiy ezvgwais, hqa idw yeguxrs puhc du pciy oq reiw nobg ep sna rece: xuisofk kok kgo jilj okim eqqorafruey. Faysi snu ehulv ig xideg — dwuj’r ipud uzpuhreke tupnuh viq “daqsvibapn kjenlufz opebhdjork ictu es jbe hsmouh edzox gyu ufuh woorl wuzl uy” — cgo urjq savqatna oben evfovadsoiy qigkek zwe ibg iq no helgizk bwu eguqr yl ffovyavj usl katbol.
Zguf ski usig zvopvew tnu Uziziru! wenwem un yyo ozinb to sahveqd ot, mri ppi-xej zogkujsoon xohyeud pqu jumaxopans id qfa eqedh ull ovafpUrDoyulze teafud onurgEpGekobto je be nug si seqti. Rpe esif am qoh fufh ar mpo wood pmlaur, ezg mde osz haad lusb ru saohomg miq qva xect ovul afqoraqcoin.
Laa rec hity rfi zrofexr zakul few sku oqd ik no rkem yuiyc oyxex 73 - Tepto PxohcEI ub hqu Waofti Cabi zaqcad.
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 kodeco.com Professional subscription.