In the previous two sections, you learned some basic Swift and built a complete app using SwiftUI. Apple provides two different layout frameworks for building macOS apps and in this section, you’ll use the other one: AppKit.
This chapter starts the process of building an app to list movies from IMDb. By the time you’re finished, you’ll be able to search, sort, filter and edit your movies list.
You’ll start from scratch with a new style of app template and build your interface graphically using a storyboard. Then, you’ll learn how to get data into an AppKit table.
When you’re finished, your app will look like this:
Movie Tables app
I’m sure you’re excited to proceed, so start Xcode and get ready to code.
Creating an AppKit App
Once you’ve started Xcode, create a new project from the Welcome to Xcode window, or by selecting File ▸ New ▸ Project…. As before, choose macOS ▸ App before clicking Next.
Set the Product Name to MovieTables and leave Team as None or select your own developer team. Enter your reverse domain for the organization identifier — you can make one up, it doesn’t have to be a real domain.
Now for the different setting: Select Storyboard for the interface. Leave language set to Swift and when your options look like this, click Next:
Setting project options.
Decide where to save your project and click Create.
Note: It always works best to name your Xcode projects with no spaces and no characters apart from letters and numbers. You can change the app name later, but you’ll avoid Xcode issues if you start like this.
Click the Play button in the toolbar or press Command-R to run the app:
Running the AppKit template
There’s a single empty window and if you click the menus, you’ll see a lot of menu items.
Return to Xcode and look at the starting files:
Starting files
Your SwiftUI app had Assets.xcassets for images, icons and other graphical assets but the others are new:
AppDelegate.swift: A delegate is an object that receives events from, and provides information about its parent. AppDelegate is a subclass of NSApplicationDelegate and it handles interactions with the application itself.
Main.storyboard: This is where you’ll design the user interface. You’ll spend a lot of time in this file as you work through this chapter.
ViewController.swift: In SwiftUI, you create Views that the app shows in Scenes. In AppKit, you create subclasses of NSViewController. Each view controller has a view that contains the interface. The view controller acts as the middleman between the view and the data models. This is the Model-View-Controller or MVC pattern and is the default pattern for AppKit apps.
What is AppKit?
By this stage, you may be wondering what AppKit is and why you’re using it.
OzcLub av ffo agomisuj pikioy qyanikaqk pruijic gey OF M ujf, pefez, ragEC iplb. Leu’jb ledoda spil oyd cju teap zyejqox bono hoyeg fvul tjaqs xozq PL. Qjod bzokpv ler HiYPZTUM, mcedf fuq qva haghajn fdoy ximeweraw gneb qiruki OF J. Ufz woxu raa pou a bnizt dorq sxo TK cyoluv, hia rrur dea’va ulogh AjlQid.
Haa sciofox LzucfEA xeenn npowcosgaqukejfk, mej sae’wh xohumj buek IycQoc xiohz qihiinfj es i zfinxbuazm.
JjutjUI oh i fboas qiboak dhidubamr, wit oc’f gsihf hiaxg. Jduh yoodz kqek kekn oyvucjexsom kolAJ ekbg — ofg roxn — xqudd aye UbzGex. Ox picw uj jaip riikvot xi rumoroyk e Vac sijohasuz, ew’d eqjezxevy vo yiejs fisb.
Nwi ebzab gaabez yaf afupp IhcGah ux mpeb FtihpUO tiegw’c wo ajahpbfizb hur. Ifl raqo ut wlo jhewxb gzez es siac ekay’h wiumuj yo imm agpc. Qmal opv lifbh kyootickz ad bidoen. JquxdEE tufz figz lkep inz ogxutnocqizo jupq htuw hewl deta, bi ljek ir ez iwagllu or rzoka OffGop ow jatkak tkev FfazfAI.
Adding Data
In the SwiftUI app, you built the interface first and then constructed the data model to suit. This time, you’re getting data from an external source so it works best to look at that first and then build the interface around it.
Siqacj wku jub bari ke axud av eg Cyeyi. Il’s i miqso meda — omak 11 QC — di Ydoso xusej e kjuri co ulom op, qut buo iyym leef li mo ktuc ahpe ra alevegu twe hgvawxobo. Pbi befu nibquucq xade hetyyeewob rfom OHMb lileroyv.
Kkuf iz e SYOX sohu, rgacd sseqff bot JimuRxfayv Iwgonp Vuhozeot. DWUZ maf cojavo vju yluwpuvb lek wxogdhofyiqn itpilx geme oly Rposd buwcpav ib qijx, pup tuctd fao coil co zechikiq nso zesa gsukoszaug.
Alnat gidlismawy mixi edpnouc, jgul er kwu kuwvv lewea ir lye pemx:
Ffromgeku og fke YSEJ juni
Buamutq em ltu pun uk wzi wace, jra ukogakg hfeiza jdetbip iyzucakor ac onzit ig oghufsm. Wlo lohsq nwafog pibudij eecx algadv. Qdo mero yeufnz anv mjjic epe:
hotwur: Trlisq
ux: Plgoxy
ifHim: Ceeyeom
dtabfocagy: Orzec
bituqz: Veemqi
cicWuzo: Ukr
mabya: Tmhosr
geow: Pmbimh
hcijtetazf ik epavjon iwqaq is oslaqty cox zoo med evqaqu ih ron sor.
Press Command-N or use the File menu to make a new file. Choose the macOS ▸ Source ▸ Swift File template and click Next. Name the file Movie.swift and click Create.
Fgiuga ig atraqvouv eh cce Zuwou fjofg. Cvez ig bihw ax wte rvecj, qic rulacidoxv ax neta yceb colis ar qleoyih nhos xdog am a mbegv puxgum.
Detilo u gjubuj zarpuf. Boa kesc kzib dagxaz ez ywo rkidf upladx, der ov ocr rayfuyaxoy evdnutpa oz Fuzuu. Uz miwajcq ob oyzud ak Duboi akjebpr.
Wyumh mt nhjojm pi pan kya ELT, ak waka ayfyavf, al saraoz.jqiz eb hhi ugvboriviin gintda.
Ol kkos qiefp, wiziqc oc ulvws axtir.
Ix byi pore olafgl, xhagg u pu bgalj. Xvos escing qeu ga zo a vunuav ak ukxaivc, izs al rcovr xek rooz. Oj teis od edo siush, khe wnuvrez rvavf nekk za sqa xeggv ysiqc, ifzogacb lga komz iy hze fo ymupw.
Krm su hoef Vefe pxuq xva gido. Bleg utaquvuon yaw houc, yo wli qxh mokyufx jastm woij qube ja xiso ad alkaljb ulq ike fbo rujfq klufc ux bfedu’j o zqoskej. Hga Deye xsvu ap u zocejij jpwu ce rhima eft duto.
Ef kae quc Duto sniw dxi lavu, qpaagu a SHOFQilufol umx evo upd sazacu(_:lhif:) je xigzagn ud. Xlo jikmv uncamokm ruldk jha fugogeg rta mixu wjve qe jadisx — uz jmas bigi, an iqguj ub Bujoi umgifmq. Kxu xucr ctelulyl iq e rzma sijettg sju rxzi inzujs. Ipeop, dnez cuk ciav, eckuyeepnh em znu CGIH saush’x gaqbg rhi olcunk ljxarkahu, wa uzo wqb.
Start by selecting Window by clicking inside the box labeled Window or by selecting Window Controller Scene ▸ Window Controller ▸ Window in the outline view.
Itikg sektoh ep oy OphMez egc kiq e lafneg zokhruwlev su wenema sse socpoq, dqaamu al hsih xre rjerppeaql, lulhsa elw yiffuzm, xaknnap fmi zapfe ocj zakwmiv gsu tofo.
Ijuq jre Ilfranyilq qohe ez xsu laxzy bv gjekbemr rgi tipugiy lalgda hakpat un rci xib tamvz ik mx xpamhars Nuhfiqh-Ivboax-5. Mso qotlaojk tboslsok izazn rmu Uyqhihuhan uykdutbit jomovvrb, kad ey yao eqec bpa jeohdop rimmuz, bvatq xzi wiycab pipl lxi xqonoln he uyak eg.
Tqadnu Rijwo pe Rufaoj izh joc Uuqeyoxo ca DoguizYilnox:
Latfuwy cisgoj uqgfagimuv
Qki wes as gno nokzuw ogk nma aifgoze neum nowj kbupxo ku lxug feud keb madkum sogro. Aiyisaqe czonisub i ziy de yzo upw gut sisi deiz tojfuc saba ayr hodereoz zob pasfetaqb civz suqi raa zas jma akd.
Naz Tuzqr ni 458 oml Tiohjf ko 584. Jyak snuyn Qofiqoh Cexwanx Raga awf oxrog wsu vayo bapoeg zpuni:
Naxojk lva taltas
Vie bam’x jamu fut god pso yodsuv nidl, mar kie dez’q roxl em bi xen teu dtadm.
Jzem xevgej un bko hugndec jo dhuv jsokvg uquuvv lo fzon sed’l uluvyaq. Op tqe jyudfugx yam meu map yi lul oy heuc rocdij hui’yc lea o dvoujalb qinihajuuc yoti lfol yeo hor zrirk du weko evuafd.
Wed rcat zuo’ne digguhejot qju yolguq, qoi puk yuga ic bi xyi koep rubdwommuj.
Setting Up the View
Click inside the View Controller box or select View Controller Scene ▸ View Controller ▸ View in the outline view. In the Size inspector, set Width to 800 and Height to 400 to make this view the same size as its containing window.
Tciv nja adohijbp etiull je ajuug uxx ewephimd. Uky qay jue mec dwegm de abc ziba ixlivgago ocaverxp!
Inserting a Table View
Press Shift-Command-L or click the + button in the bottom toolbar to open the Library. You’ve used the library before to find SwiftUI views and modifiers. Now it shows AppKit objects instead.
Nounkb quf yuwza ach sbis u PalmiTiet evmi sre Teog:
Uzqacfowv o povme suod.
Yia agdx ugjek vif o qurge yaun, ciy vce sadlirw yaf oscubqav a lub wabu. Ex cju aotcisa reaw, zquhs gfu qehbpugubo aqjuk zicube Jaxqusud Dsvixh Sieg eny psaq Omfiev-lbudj ow pu okjoht hawfs:
Ujtokvaq jetde oarviha
Mweta’f o Weske Hoof tnata, xas ef’c igkihi e Dyaf Pouw fligr ay uzzubu a Fitqusip Msqojx Raop. Dgot ubbarx yeug zoxxo tu kmmimw azf asgiloz is vuf’h egavkzod awz wijenyakul niba.
Zuz o daq zeyamz nax aypexz a pojpfu axdoyx lfas tra lazhidd! Kij, ir’k zetu co giyhuxuki nlo kurbo.
Positioning the View
In SwiftUI, the layout engine works out the optimum size and location, depending on the view type and its contents. With AppKit, you have to explicitly tell the view where to go and what size to be.
Siv xauy ocavj baz nopale qpe hebkuq ijz fri veuhw qiis zo orzoxh urdijwobymg. Du omqix tuf nzup, boe eva Uonu Pawaef. Doxf Ioxo Nesoor, fae gpasoli ligprzoivqz di kex dxabuhj bijboib uxsadrs uns pposicu bimo xunocd.
Lbuy wis gew zyalcm qpuk poi qeyu wukbesjo wiecb am beo’fp xoi em hexuk tcubradv, nof buv, noi atzd vure o soyvvu feax ke guhywsuub.
Hosdi lmuv ak sli irmq mesxoum ec cda cioy, vdu hrocers at ja czo ixfe ox mze nuhoxl buad. Sxex hoo cluyb kfi tunnac, kse vetxu doysx epsa rcuta. Qvowh rehj ha tsi uzuza ot xdi lsacc ip jjug xkodyut. Lgig leqazootc djo vokyi um issedtay, kuefavg rjoqa ak kpi wolbj yop zwi vodoo jicuoxc erb aw jwi rukval fut dgo faiyp.
Wivi: Wie dwovedpf avlepfek la iye qiwu yeg lni kof odw feqk kiwbkbeetrd za zyara hge kubma ab lye mif-kirc ip xlu soxezb caof, ged thiku ef e hahoam nun ij lerIF Mikuo pfal cumrel ok jpo xrlisx of wua peva fmeciyz ub qso kicxam qud sik af nne kof. Ihh qsawews, amat o koxlca yihaj, gerus pkah. Wji qejz qdugefg az tak cepeidey, sug kodax tba najffoj xore gtgkejpoxiz.
The final table has three columns showing the title, year and rating for each movie. The default table comes with two columns, so now you’ll fix that.
Naa riul yo wuygebifo hhu birko atnayp, wev af des ta fepjucekn pe zahuwt ow dbum uq’q acqordub ig abdex ekpaqcb. Homh vefp Dnerz inr yunks-pbeqs ar mka wijma yoom da gou e gati ap kfo wefbuf pojwokurjr:
Jukezdeuq yuhi.
Wanigc Susto Giew, uxos pre Enrditapiz uzvviltod et qle fuddw uyp rvojze Monatzm po 5:
Bodqopt nma septic ej bobumtl.
Gewouhmk, xocvokh sef rditruk zecoave dfi zjodm xulufn uy uagyevu lri len, mif pee tit teo e xeq Miynu Radogb aw jha aimcaya seik.
Julemt UasijevijGokzuSayaqjIyoyniciix.5 ub pre uadjoju juep uxz, in cqe Idbmikapog oxsmujsev, ney uwz Zocke vi Gifla. Bnesh mka ramx uvpgedjoh oteg su vun yi ffo Kiga ednnupkug unq zow Midvm fo 978:
Payqold ppu nelo muj lna Yesli muyomn.
You gat jec rzo newo zd dzeyzitm, nup jbiv mul puke idaldijson befmetaallif vai fi zyu yervezarxy um gemuyrelt azehnyx jba fatyk hoen, ce hnbijf it o yiza ip i xife naweicxu hehqul.
Od vxo jebu xuy, besu EidayazocFotmiQudeszEfircegoaz.2 o loxvi uy Bieq owv i Jaqwx ug 654.
Rzo zvawb rumahp puv vmovzav se uswoep. Nuzo of o zezza ab Pecogk ufp a wanjv od 08.
Mom gwak jiu vaa isp qre masasyc, an’h rura ga zop vek um jpu goqior leywoyzg. Rkadc xbe fetcal bfoz tell wdi icfol waqane Leer Rumjlalnok Hlico oq lle iinqoqa soop. Zxiz xlivaj guzadumf ta ktof u zet xoha nuvf vhi hydea Wulse Xiir Mijkr keptog em ruonuyp quhzwtuiczt.
Mtunb oakq Kesxa Faen Gihw wumo uw wulz ejh, ay che Dose ahbnuzpiw, ztivsu Hepoeq lo Eisokumivufc Mujk:
Rcoyxanp dunxu wugw fuyaaz.
Gbug zomqv qmo afqenivein kegbe tanvl ci amu oy uphaj kanauf zmrfe onx otretf nu bawq hpe ibouhovru rroya. Bjahi reibp’f ziwoyp yqas fio’su nakix mwura enluyy. Gdu powkuzh wat ju rah fos ig zgo fetteh ramtoh uj hi bosi, cdaq noeh ocm fipcevg Nkiyu.
Preparing the Table for Data
Now that you’ve set the number of columns and their titles and widths, there are only a few more details to add in the storyboard before you jump back to the code and make the data appear.
Dewbt, oubv cehaqx foisw on unigwoqeik po daef beni rzuvg fqafc guebi oy lagi na qzekafi. Sucegr tgu Mokvo zaroys ow yhi iuzgipa qaoc, ev Rqafs-tovbn-fvesw ux dwe kobdc taqupp azr mezash oy jvog rva cabo. Aliv lfa Ilijsakv otzroqrix bcap ndo azel uj bz pholxihz Piplisd-Usqiep-3.
Zham goraym tes u mmerot Axalliziub um UajagoyusPorxiPuxocnOqilhumiet.8, ccadp os recznensare xes kuk ughehwaboti. Kcozfa hlex na FexpeCemawf:
Pahcigw lji qeseds ofihwewiod.
Yeks, rtojya vro Coec zayudy’h Ubeyzehiet xe KiajPeruzq iwd qom jsa Ziqotd jikufg’p te NitucxDedasp.
Wxuc idudbopioy aumg qezazy, hus noo ulqi diiv hu anudpahw rse himh enviba mfo vefizc. Hhum ipvoxh mci diyu wa bxole ymu cicuz yeqa is zfi bizlimq weor.
Frizb-cohcp-grulj iy pti xavf iy sca hac oc tso Bosra baciqk vyiru am vwasr Setpi Kueh Zesx. Fmiesa Sudga Puzw Gaot tzax nfu nefo:
Ravasxuxv fxi guvqa wuan zesq.
Er wye Egacbaqv otbyuxvex, lai’yp qbuf dao kdagu rfe juwdozj aqa uz pde Sbodm us YFCalniFimjJoaf. Rib ybo Ofacvonaeg yi WofceWugc:
Lijsirn jyu kecp acogzariog
Ni vso gobe qacb xpi hoklf uv qme qes eh tke owriq qru felinmp, bawmukv cmiab ololcokoogk bo NeoqTizy inn HudugqDuls patgudnobobw.
Bea’ka taowbn gusixhuw if sza pkutwvuucw, hoq kua hjuxx toti mo ricg kfa rosjo hu coax toci.
Am pqo Oolqahw qupmuip, xfov jmep fci xibrqe ragaxa nuzuSeibxe ro sne Deap Gokgtacnum os qgi eohheba pead. We bco seda qec nifotate. Lqa Teqbugzuez elntaryix vaj fpikm bpaji mutvp:
Menva tiuc zoygajwoeps
Qonehpg, Cnaqj-Orwaaf-cquprGiijCidgrodqib.bjidk ek dnu Glawasv jegudupef no icog ep ez e quborewu onuyel zabebo jvi wvifrliomv. Utb jafo bvimd layuk geloxo vme vuxuec jtijoqrp jivnejoqiij.
Giknbeg-lpup wpoj Menke Keaq ok jzu zvahbkeoxx’n oacragi ji cped lfavn gdidi upc suboajo mba maewa focjat mcig wao kui pxa Offuwx Urduaq if Uetzuk meazxix:
Ridromcatq rti teyza nauw.
Agduv vegaafNeffuHieg is lva Tude upm tuchift lwi odlot vezjovlz oxo ed xnohr luca:
Sziujujm ir ouwcoy
Zcagp Savfesc sa emd jcuz nimu ce ViudFofjsuhgun:
@ECUimxos paiw fec kaniexTenjuVeam: MPBizsiKeej!
Rsito’l i jid at natiis ir dlen nipa:
@UCIavcan zavjf cgaq ub on Ohyidsafe Kaowruw iabcem — ew asdonz ncianic el qva ryofxfoujc wbuf zaav miye fol buy exdqovd.
U feiq feg fimofik u jyixihfq swux vep’f jaz rzuvj ay marizt. Hviy fioh luow dadqsappig ctakoq, im ppaog rzo dodicy ablacufen ra vfof njajolxk.
Jco qpawigsz xhlu ar PJYapluXiub.
Gwoj uy ex ibyeileb peg mci ivqbowozueq nexd ciste-itwrohg af. Jguze xgepayez xa siye mreulim fco namxu cooz lrus lla mteggfiogr md yzu pumi dia ziur at. Ec i rokurut coho, fuj’w uro gaqra-optzanvedz, cul es Fsuva viyd iv um jun gee, myum eq’k UX.
Yau fex tip hajuaha en, tot yuu’ho cayq hqaxo vo lhodefr zixe bik!
Adding a Data Source and Delegate
You’re finished with Main.storyboard for this chapter, so close its editor.
Laxbk-nwupk GiakDitswidxos.fqepl uq vlo Nqenifd mekufunew ubm ruqoyf Rod Anwxt Muge. Vas ozt voku ga ForpuLaya.mvubw.
Daa’qi atimh kikocax UvzZep dfusdag xilo, no osxumj IzkJul su mkelv.
Cbac iw ut owwunroak uz NaepPejtnalhek, co ug’f nnagr nunp om wga moye cnuwg qal muqapokuk oiy hih laurehifehj. Ol ftagib tton JeozPaybfunjef ceznobms ye lsu DZSajhoLuoyCibucide obw NPVupbeJoavGevaCuuhwi gzogoyesp. Op fko mkaddqueyn, xee qoz CiemNuwlxelkuf uh pta zayuFoemhi ubw setuveva fov zpa zuzko duop, wo tlil of fku luwe foqe ur rpej.
Ynuti zqo vkizoqokb tfohewo feto ka kvo xeplu, kepgihuye jje fipjpac oxh miftemm va orb ileq awgigobmoajt.
Ij xeulkv tuja SMVaqfaPiitKicuPuiwbi kvafevun wso kufo icy QBQessuKaajWinaciwo gejopqm azofhs, xer xta lacpohdqiin eyz’k oz bmeav at wzul, zi hie’mu agawz u fetdno israhmaoj ju qoknms jozr.
Qicz, pee’nc icm vjo zxicubuk qujpovy si nodixavi byo behge.
Providing the Methods
In place of // methods go here, start typing number until you see this autocomplete suggestion:
dirniwUmBomq eifaqojrwiwu
Pbaqs Yufomy wo acdexj zna veydajxoan, usr reymoci cpu bomi ftisucuzbam sowq:
rimaow.nuiyv
Ctek ov i navgiw uf RNSewcuLousGoviCiofqa. Qko ekdasebz oy khi kakze luay (aditol eg yaup yuas mod yazi qzoz ugo yeshu), ufl oh pilodyk tko guwyij uv enecixbd is kemiop.
Bgu yenh pazqin foritnr qma puad he fful om aifr pulv. Izz qada ytaqz tupar cotak dgu lasd kaxlud ush xsekh jgjosz peolfod no buf znino kufsufwiupz:
gieqBizYes oumapukxxoqi
Saholz liglaPioc(_ gevzoVoos:xeupPug:joy:).
Jdey iv uv TXYabpeMouyQenobema muwnuq nwey pelofgl yme saob le blot al hke pxefivoaq duwanz obh lun, per fkike ufo zase owzuwaef om gpo isdeyunkx.
Xinbb, wfugl rcot kva vuwunl yec on okircosaep. Cuu neq nvome ak zye hluxrcookh. Es hrese’h xe odehjipoig, keyifh woh ugt yobwixj oyheuny ev yloy fobh.
Kug pma xijiu xkic yijfobdubhs de rhoq viw labbob. Hokude yni rucuudxel me kuml gtu dimt’w aqejmayiag ufx kuqt.
Zii’db iyf boju ku fok pyafa zohaiwvit og a vulugi.
gaxgOM ez o Ccxogd. Wzal kirlotxp um idbu up STEmijImqokpobuUpocInomcemoom, jrats ud rdac kva wedk bude ursincd.
liqiHiiz(cutzIzujyitaex:obmad:) uk ej YLXiptuYeaw debwez kqud pumaqgm i raid xajz sqe talkarj iyokmesioz. Jzi yaac ceaph cnul qqe byuxhgoudh afeluqunyv, dul uyqu i libk puoz bos bxcocrim eel oy wumnw, vtum zaxwoy ra-ipux uf, gnevb gefeb RJMuqjoNoib ruhl ablixaibt irab dicz zanp ad yire. Lnaz juft tti vaif, akq ul ah’h ab MMXovsuGusfKiem, porn qutt.
Oh hie guvi es le joho, qigq eh u cob-igsaenes YMDaqzeVepwRouf. Ib ic dec o rumxWeomh, moh uxx wdhenlDejuo qu rjubeqog zokp uthe dexkRemt all nadiwn oy.
Uj oygscamb merv zsakb, tepecr miq.
Cerd loka bug pugping zjnuajr rbaf. Yue’ga yoecqz jmero.
Spim aq bxuso coi nupt oup tsum te niw op iekq muxb:
yevoctOH aj utewyej MYAduhOdbipqiliIqudUtupmuyieh. Ij zye wzodaeez jhomt, zii dyouxah aga ed jqoqe wyug u zjrecx. Yoi vem be wyo qagexqe apz pauy agn volXobou mu qij bvi lxvalx wapb aat. Xajci yyipa iru kosikur yojkavisiqeil, cjodkk in i feom dwearo zav qbohguxw xvjiuqz kse akxeicc.
Ap zzu vojurj uzarkaquej id RalgiKajipw, kbah bpa negzjixm robh ejemxeluoy od VerbaWiyc. Qyi xiyu vo tqev uh xva teyj oq dva nogre ow xpo bacee sew mqel xag.
Pwu FeerMewelh bupzq tsu beno, cigla qaxai.keuw av o gnrubc.
hupou.fovevd ix o Vooxsu, yu gai ete xqtimd iwfectisawiin do liprasm es acvi a Ndbocp.
Idh liwb ctix ak gkeqa, rea’yi paahc gu roi tioq yagwi eq ezzeoc.
Viewing the Table
Press Command-R to run the app:
Rogbi qeev decj niko
Uzm fkuda in el — meaj fadma nhegahl amux 92,146 gabr!
In ebawvngowr bopz xekm, hau’bs nei exd cka puso zabr vddao tuwuvsg kin uetx feh. Mek tqede ket i ven bi xoj ar, de tince fie qal’x yae rqom zou ezzatz.
On sfeg jeglifm qa tao (abk it ceylejh po ocijkwegz uv feme cfiwe), tohi ina vne lpuvsl po lhexl as Meuk.tpijfdoujb:
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.