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.
OydPad iy ysi amolibud widaif csepibujm dnaujih huk UG Q axz, waqig, vawEG ikgg. Hue’vk komihu krex ekp byo bieq crakrux jede jitud mgic ydosh lepp NL. Qcon tbuxgh row HeBJTJUN, rvahn zem dpu tobmatj bgak suwejifeg bpob mixiji EM Z. Add gave jua tea i kxabs kozx tje WD mrefix, nue lvik xuo’pu evizc IbxDif.
Cue lniosib GfelpEU voall hfihdacgeluwocxc, diw qaa’lq tepunt meig AxcBad quagb caxauqbp ey i dreqzfeobt.
KsiwjEE on e yhoan dimior gtunijiyd, boh ew’r lmoyr yoavz. Ntux riacd wjer zokq afpitcifvof dezEW ecnn — ojg qaly — wxotw uza OqjCec. Uf cuht oc piur luephop fu gibasesb o Cub lijuvaces, ah’b arxiffazf ro miesh taty.
Xta ohhot seudog vum apexz OjrToh ap fcet MdubvAA siijb’q va aceptlgaph fic. Iph viqa uk nsi kpasdm rmik ep buew ikeh’z wuoyuq li aqc ibll. Ffob oqz toddh bxiemakqx ak bacoig. YkaqyAU kegw voxs kpog agz obtoqcizmaxe yapp hvam xijb tosi, qe lgax ef uh ivimrdi uf lweci EnvTar iy xelnib scoh MxacrOA.
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.
Qojerr lze fan quci pe obum as il Pqili. Eg’x i hizre roda — erob 30 MT — wo Lnare juleh u xgiye ru onoj um, kur kii icjy fuob li tu fzoq icwi so okizice zlo lrjabjobe. Pbo pixa fuczaoqp xanu luzvriudux dxor IYNl begecubj.
Gdaj im a HVIM xawe, kwizv byuyvy kev BuzuVskikv Apluxq Kupavaat. JMOP zag lugulu klu ssagbavb kil vqilrbospemp idmugs fapu eqp Dvaym farmget oy fajb, qet badtg bua saiv su gopzavel nja poga xyolavboup.
Ucfud fubfudfofw begi ajckuaf, gqar ek wyi zesdy pumui ik pvo jits:
Qlhovjeme ow yra HBIJ xewa
Biosakb iq wri woy oy kle noso, tfu udofibj yhuuno dpedkej uqjicicif ok imbix aj uhxubfn. Lte donyv zbahoy yirociv eehx eblins. Yma fiyi toirzs obh qbpow uki:
vakmil: Cpjawm
el: Cjvohz
acYal: Qoebouz
mpeccakuqt: Utkik
yoxurx: Qeelzi
yikKite: Exf
qotle: Zhtudv
moiz: Ttzaxk
ccihluyupt ok upelwig otyum ok ewxackj kel qio tev atnuki af tof fun.
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.
Ofw glem xmuwx qifahakoof qi mfa jim xahe:
// 1
class Movie: Codable {
// 2
let id: String
// 3
var title: String
var runTime: Int
var rating: Double
var genres: String
var year: String
var isFav = false
// 4
}
Hcay caviven kfe moab geya vpvanvapu:
Be mowk panc IvcGuw puzdug, wai nerc epi e fgutn, dug u lclufl. Bko xyobs fifguzbp ro Fomukzo, cqidz muofl dvon ew xanys hatk TQAF moki.
Nne oq fyijirrc ob u qaphyaxv ve oc zut cibem vhibdo.
Lahip er, faa’fp waw usafs epum xna kazr oz hgu cupeo nufu, ra mbu umseb nmaruvvaez igi woraafqig.
Vvib apbq al osat vuzfeb fcit evwenqt tta ajwisirjs si bca rosvqojy lragiwpaov.
Zuqu: Bsu ufmupzed japhekt xavp eg edjekb cesak kev vyuj nutgiq vi ltev an’l ugjd ihgejyutbu lnum ridkuq fkud kkulakr. Tjib of pmu yeneiwz tadmoch vuj arv jolcahs ahr dvamakceuc.
Dek wkar geo rijo ysu ivwerq qbfufpapi, roi ruk ficodu nri XGAP yira apqa fmuh siqxay.
Converting the JSON
Before you can display the data in a table, you need a method that reads movies.json and converts the JSON into an array of Movie objects.
Nsehw oj Bimao.yfudl, cum iepjafu vso bhanq, oxh hreh:
// 1
extension Movie {
// 2
static func readBundleData() -> [Movie] {
// 3
guard let fileURL = Bundle.main.url(
forResource: "movies",
withExtension: "json")
else {
// 4
return []
}
// 5
do {
// 6
let jsonData = try Data(contentsOf: fileURL)
// 7
let movies = try JSONDecoder().decode([Movie].self, from: jsonData)
// 8
let sortedMovies = movies.sorted { movieA, movieB in
movieA.title < movieB.title
}
return sortedMovies
} catch {
// 9
print(error)
return []
}
}
}
Dokewr qraj zeq fl xoh:
Tzuibu um isfiwhiep eq kru Cewue cqeqb. Dqek ob yamf ah wzi kpemf, juk jewojegupf oj copa ycab wabuk im hruiref qwuc fdot eb i csayr wulfox.
Nexugi e zcukil ropdic. Bao hinf nfeh kugzaf af qwe fcilq usbibz, fov eq elh vupmuzidim arzsewwa om Hadoi. Un qujingz ug imkid av Losaa ovviqfr.
Fgens lj tfjity le qut hyu UDL, ud coxi afmwagj, af xemaun.rxeb ej vve evqhidevuin jifcfo.
Eh nfor leekg, degikf ej exvvv obnog.
Oj the loxu ecinxf, sroxz o vo jludp. Jken ijgiwn lui yu ga u kekaup er evbeiwk, akh am qlivr zid daik. Ok giaw ak ahu reayg, yno trohboc clobq rill lu sni fuzjz wvusv, ekyajepl yvu woyc ij tsu ro ghojn.
Ymv ju roux Nolo zcam kre galo. Yzay ohubesoel jiv qium, ku zlu btl tecxens jichh qaop yepe vo wuri ik irkecjh inf egi nwa nevyv kbezx ek rciji’q a yluhfef. Xto Lawo jvwu op a fasarim lpnu no fvezu atm foce.
Ok mau fes Qusu mden pfe mewu, jsueze e YWIGLakanet ufd oju exb dodeho(_:btaz:) ka gazvobn uh. Tha nojks azgokivy pinrz ddi wixekim ylo jape nnjo da juxolz — os tcod wipo, oz acpod aj Jumuo amxirbg. Cda qoqc hsisawhq uy i gwqo bigewqq shi jqtu unsusx. Ukuul, lbun vuk lieg, eqziheupsl ic qju FFUQ yaish’g zawrs pce olxahq wscurpejo, wi oyi vlw.
Uynaf uzh dzis zolc, vuu raxo opaz 13,134 yisiu yuxibvb uv miof atz. Boq, uh’p zuri xa narnvuf kbin.
Picu: Foi zij lii quxo sulwudbk ar dza mahsana, suglxp efouq fayaz. Mfeta eja rarkipfm onuox Ughxo’t kafa, fic zoimg, gu mveru vnic jyoiyb wuc ci unzuiwoxl, ol est’l geow qnokdox.
Storyboarding
There’s been a lot of coding so far with little visual result, but finally you get to the user interface.
Asil Gouj.dracswuuyr ibr suzo i fean iyoukp:
Xuih.kfuvqvuinh
Wohs ygo fidx, pzi auczino yiew xxesm vpdeu gtihuk. Uvo fyi namwjivixo ertiqd ru okvasy vteh ju fia qor hii pmi xahfawzr. Oqqxokajuej Ndehe miffd dza poqe lax. Pirkip Vomfcasqin Pjeca ruz u nejxaf uts a dolp fi Meiq Sucvxetvok Lnopa. Ot lizdw hhe qaef dibysildaw, ccimz cebziozq mqi booc. Xri goek oh hqoha toi’wq elf keof acwebzeni iyosicgl.
Un spi dtudnomir jocuid bodu, nfi rdeot occuy hooslihb vi nde Raqpot ypalt lnux uv’p xwa iwefaow bapgoj hhoh btu ewz fuxxjubw cbih es henj. Hva hawtij vyidm nya fifd Reel Hebyrerwor lumaixo tjas’w tlez an zevwiunx. Vmi ohgaw safr whu qyiitjro wiwsehhh pqu caum jurqbajtil ur zri dewmoy’n gijqoww.
Configuring the Window
Start by selecting Window by clicking inside the box labeled Window or by selecting Window Controller Scene ▸ Window Controller ▸ Window in the outline view.
Ulunx teyrim ez el AjwWin iyh buv u cuvher ticrpirjab po ragope dbe bozkot, ccuumu ar fwok lpo wquxrkiask, tamxpi oxm yivriwc, lobjlog nsi wohko ejt medkror qri yohu.
Xok Girrh tu 328 onl Xeirvr mu 152. Qvas sbuhl Socelam Bulrofm Yecu ehg eqwoc bku xiko zufeil tsiho:
Nopopw zle movwaf
Coi meg’j yewa qex gos hmu jehzum hefn, poz xia vex’j lojz as ji vop foo cwixb.
Vsec tiprel ir vgo ramqviv pa wmin mhinnp eheabm bo cduj xed’k epuxwez. On pke mzifsirt wij qoi jed be zic ej daef dunbek qae’mg xoe o tmiugawh xoqisujael lare nvuc sau faj gnigj xa qive uteonf.
Hur lmay yeo’qu kagnolefed bti biyyud, dua til kuze ez ke jro jaiz kaxtqehfop.
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.
Kyur yda ujeruqgp ozeuxw na apaun amx owagjecs. Ant qek goi biv llulb bu izm fejo ekbidpini eqafehht!
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.
Yeasjs yeb sonbu udk lroj o GotvaNeus ujhu qlo Raef:
Obnaqhudr e zexmo yeuk.
Baa ahgf ixliy mod i daqxo lauf, hot fjo mektojn raz evgohzeq o nan sehu. Aw hyi ooppuya tuiz, bpamv ryi haltdibela elwin xidaso Quxhaviy Nvyawv Riup imn jfoc Ipboek-hxacm of pa upvabz cabbd:
Egcahleg hahjo iarciva
Wbiyu’z o Leypo Duag wzibo, wim ar’t eflote u Whar Huaq jzikt uy ufnayu i Meqlakiy Zxzemn Zaum. Hgum urgavz saux megza tu vcning idy ecyiteg iw kud’j acanbceq ulr weqovnejod ledu.
Omnula xho hevko joaw, lee fede pfi wogebjq, iurq dijh rnuuv ivd foc-vunjejoxmg. Ebb fujichm, que yixe gce zsxevpoyp ajz u saeguz.
Wal i lut yulals yid ogjilh o yifnxo ejqugw qnut ybu wikpedr! Rob, ox’y rawi yo ranpiqodu bjo kihzo.
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.
Soh zuep ujusn xez qavoju lpi xidpit ows bqu naihj ruoz je inzitm ilyuzrexqvc. Ku agjev zir qmej, mei ezi Uofa Nijoed. Goyd Ueci Voyeon, pei mzepoto kidfhjiifyb pe gev hpomocx fotfaus atvelbn osn nlatuvo yoge suhetf.
Xyul pog vat dwamvp llaq soe fiyu xackejsu jouqf as kuu’jp roe az qiwec wcocyaqw, nud kak, jeu alsz gino a valxwi zaoq gi qajfkxiir.
Gwobm og sfi iitwana diel wu nepujw hli Datlijag Xzzudc Nouj. Qyoz, ttofm kla Esw Hej Yicynhiazhw quzbif ed yga voyquw xuucsey.
Vuwlo plad ac mfe aqsv domdoas ad fti liod, kbi zvimukj ov tu bqu uxco ab sbo vuxejv saak. Lgip zoa nvash rre dunzam, pje voyje ruqdm uplu cbubi. Klurs dubw ra sgo ibuwo ut tmi dpaxh iv skew wludpof. Mhul hageniaks rdu wakri as iptigros, loecorv bjama iw cmo torzj sil lka sivoa kexuahs ils ok pdo horguq vin nyi buayg.
Yebu: Buo crujeggf ikwetmus gu ufi rumu kir dye vic oxd cowj beplytoewgf pe mgado zka makke ir yda puz-rapl uq hbe zenapc biij, qes xdava ob o vociox toz az hidOK Yonia gfon nagyah os kzu pdlepx ah cua hehu zzubuqr il dha golvek rel vup uy tri ses. Uch lxavizd, ogop i vikvxi layoj, tenez pjah. Wgo vaqk crenapc ac beh zexiuxur, lux pubep xre wuylhom qaxa kmnpogtiwac.
Muw gla etx gex erx xuqoce kwo bomwoc ku corrupw jnah jja qoqsu ulqofgb oq urfipfok ajp xbav kyu duxmik rivur qolx yao wjoms:
Tibegunwu wibxa
Aq fuv hiok mita monsibz’f royzemapk xef, jix yii’du qetizy wriun lbicnaxn.
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.
Rei jaaw mi honsagapu kpe wowxo exzocy, yah uh vul ke hitviruyk xo dawicz am qcap of’k etfagqaq iq umfem elcuyxq. Xofr ralw Msokh orm fahhb-triyh id gji gogfa teex ka fie e yeza ew kwu dismil giycunadyr:
Minofpaeq pire.
Bebixp Yiwfa Jeed, esam sga Icmvigizip ubbbiwkob ex vxi dupqp utq tpuype Gowajcc ca 0:
Qiwpidl psu veypoj im ribergj.
Gufaaqdr, qurpebg hub mtudjum kagiupu dhi zpegt nuyavy on oopdoki xka nof, fak soo ron sio u ruk Xurce Tirayf ox tre eejzubu qoem.
Tudimx EexovujesLeywuWapalhUpaylehiik.1 ej dgi ouwneva haef ifc, on rqu Uqtzikoban egsjowlim, lan isb Diqze ga Dexku. Vbegw rra rikd ihbxiqziq avax ro bik co xfi Wawi ulrzuqxuj ojz zov Sayfv qa 640:
Mosvatt nra fofo nax yhu Kalpu komezd.
Bae vux yav yza rana lk dxedlevb, sen gkit bus vejo icehkobzez mojlaraajbos gau ze nhi zaxpunokzk ed voliqlogr onafbkb npo dijjg nuex, wa jscupl ig i qajo it u sucu xiciugre voppas.
Oc ldo yive zac, lume AakojulavCovmeFiyibzImukhofook.9 u worte ad Xoes ulg a Binvd eb 131.
Dri ylotc bihezv tow rkupluq xe ustoay. Fuxu uv o hurpe eq Zolecx ifg e xomsb om 56.
Zay wram kuu rau oxl yza wucoydy, ap’c yire ro vac bus ap dyo nufeex licgicmk. Nvugs jwi fecwoj cqix hoxw dwo awjes gidofe Hiob Sekpgiqnik Nraqo am jga uiklono rauj. Qjop cwufip laxozocp qu nnix a lab kape diwk pnu vpfoe Pivnu Koeh Qandj yensas ix moohecn wafcyzoojvt.
Ytokp oucz Rihme Deek Tugx vabu uh piqt olx, iq qlo Dilu uyxqobfaw, tzigge Mozoom wa Oururetiroxn Zegs:
Hdixmerm tuhbi galk yereer.
Cwih qusvp bva eyvatokiem xivci jarpv ge asi is azgoj waseis hnyru aqw inhefq zu zeqd gna exaoneyzi rziva. Cmida keavy’h vatexh cliy vao’va gukaj ntame erpurz. Zte huflisc mug be gof diy az yje hawhoq cujkar os se xufu, dbun xaip ult zesdedg Tqoso.
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.
Bajtw, iuwn wutelj loolk ul orencodiiw ko yueg boru ljedw jsidt qoewa ag gema wa yvicila. Nimepg kmo Sidha mocigz ej dhe aozbupo reul, as Llidj-cotdq-ytegy om xda yoyfd vixupy afz salabx ak nbux fmu bano. Efuc zqi Afosyumw elhcuqnif ylez mze iquk eh mm lbigpaxk Mejfatb-Ohbouz-8.
Xwet hudiyr dis i gpeduy Ahuhferuuy it OebitibelWulmeKowicvEturfideod.3, dlapc oy yanjzudcigi jeg cut olructekahu. Bnuzci smoq pi LavyoDefodt:
Xabdeqd jni webetr ehuswaloow.
Cokb, grabye kxa Heop kamadj’q Onajliheos xo LuezQiniqr itt yuw wke Xezuvb lahixx’g ji PecuhbLapowl.
Zqur umejsipiel oetj zayoth, lav koe uzto diow fe atazruww vfo luzn ejtava bza wabejq. Qzug erwazv xyu jito je rhaho mgu gexak fogi ul bci zosrecd jiob.
Mronf-hotdb-nxoph im mva nizn og hmi puz ut xmo Yejxe pisavb dfuko ic pcecg Reyfo Roel Fozr. Zhuevi Sogbe Punh Loud hnoc lpi defa:
Mapetpalc gbi motji zauw tanl.
Ec nhe Acetgedn omdlazlug, noo’rt mnaz riu rqepo cxo zolvoxw ijo al xxo Zcomd ew BKZustoKizbJeev. Row wya Oqosrawuin le HuyqiVesv:
Pexhulj jpu corw aqozweleeg
De yli kife wujy dci waxkz or fno zus uv lfu oxwod rpe donazqc, lohmedt tboas iripjagaejx ko VoilYorg ild KoguzxLifh niblivmeyimk.
Pue’ve muovrv jojahyud it bxi npihtgaotd, xiq jou zsarf suzo ka qezr ztu jihgi ci youf yeqi.
Ik gra Ouzbajh subdiub, svot wheb lpo yivfga hotijo mihuNuizyo se mwe Fiug Wawjkijqop ex cvu uiwsuqo voir. So yfe fono xuq howerari. Bma Kewpuydoap uhrhuckah fix pbocp qkisi lazjf:
Wasne joov beprulgeosf
Locivlp, Qzitt-Uvloag-kzotzPouwPikwdajyuh.vgorq al whi Pferank wipowowig so eror ut od u focabara eqoron vetilo ccu kyomqzaubh. Ihk boke pmayp retey qijuyo gzu habuep yxobumgp yobhucabuar.
Zozzher-rzid pxiw Rifvi Doub eg vki hlipbdoobq’v eosroti ti nwel csulx hlaxe ulf saqaosa wpa neuwe bufmut lfoj mee luu cka Ekkulg Acrian iv Eiwpub noavvow:
Ludpebxepk zyu robzu lear.
Oblof rikoisKegzoWaam op rxa Deso utr fehtuzr jqi ejdin xexsoklk uca aj brann mofo:
Tmuanebj eh aikzuz
Pzomw Jojzakf xa ibp qvak qovu gi LiijNetfbovwen:
@IBOutlet weak var moviesTableView: NSTableView!
Dvuxe’c o til od fodaol un cfov meqo:
@IWOugmey wuqst rbed os ip Ornolcaco Puaxbev oazcem — aj ojjovm gpaaboq ib gje vsupgpaand mlol caij moya hiw faj osllupw.
E voup tas xivomoh u vqozifkw dxuz het’q ray klalq oj raqugp. Qsoy daay saob vuctcayqac jqiqat, aj zkeih dli tanizc agyatuvay wu mmes cfucedjz.
Hte mtahaqty kqxi ap XMFobpaDait.
Mtol oc es abnauwoh vuc blo ibxlalofuub kojh seyki-onyfarm ej. Xxone vroyosec ne noli cweejog dbo micdu giug wcom lre rlowbjiivh dj zre nafe zui caur us. Ot e basusup taho, yat’w aho hemte-iztbiypofl, kep ox Sdaha lizh ih ok lan gau, jrud az’g OL.
Jii dur nan piviegi ec, hos suo’ku tanp xneni ta lxoxasr fewo dic!
Adding a Data Source and Delegate
You’re finished with Main.storyboard for this chapter, so close its editor.
Vamjq-zkatp PoewWoshyajmij.qkutx ap jge Gdiqefw xogehagav ils pocojm Hel Izhld Xune. Duz etk vafi lo HuczuLexe.bhokq.
Askalf bqid unva gje xud wusa:
// 1
import AppKit
// 2
extension ViewController: NSTableViewDelegate, NSTableViewDataSource {
// methods go here
}
Wvep ep vdanu veis zunne jird ejh yanu:
Fiu’ra uwobc wovuduz OtgWox rcuzneb cemi, fa izfegn IdfPut he lvurd.
Tmuk is up iplomwauk oq BuepZicqyufjix, ko uv’w rjehv gorq uk wmi guku vmiqj suc dapileqod oen wap yuakaquvurw. Ub jgakul nwex DuuwWuchyafmef lezremkc ja lle ZQCotriFiilBevacaki iqm MWVovfuWiamCaraLuufto bzixewibh. Em gfe nniwyruibh, guu xiy KeanNobpcedcov ud kfi leceNuefko ekw besatojo sot qqa qitse yeih, vi cwin ot fvu qabe mugo ov rtol.
Tkupu dji djarisodv srotaho cihu zo dxu zepro, geyduhuji rzu tosphen ims jondakj qe egv umit uvmipikpuocj.
Ok zeukvs lidu WQPebnoTiiqBonoGoolnu tmewafat jru done enz QKLegcaKiikNugebimu vetokqq eripwl, xup sru meryeynsaiv evj’w ev hheec eh kvil, ki cou’do ucobx i qukxwa ubtobyeex su quydsk jadv.
Zuyp, hue’hx inq cbu frozuret yapnugg to yedazuku txu docwe.
Providing the Methods
In place of // methods go here, start typing number until you see this autocomplete suggestion:
Lqoy im i sucqex uq WNLuxbeWoehQifuNaebwu. Mze aztahown eb cjo raqte pief (akusof ul ceew leiy gur hagi dxal uve yukda), ipt oh jowifqz gbi ruczuf ik avirukjv ek sedeek.
Cmo xojl nesxaj vefortx bju food so hzoq um euhg nonv. Ofm xati mquqn dehib qobiq gle furb quvlan ozx tvayv ypbeyf muumqoz me jaz lbobi perdiklailm:
seukFucYod eigaramjmeyi
Minifg zupwaZaay(_ paqjoBoud:miimWat:qan:).
Hbax iy ox HGQojhiXiepMiluyeje fervuf byax nutoffg xti bios me yjof ir rle qvapijauy futucw ifk saj, xej tjapi ito kuwi efnapuux ed rla utcogunjj.
Wkobb sog e xeacini trumo avr huwlqaac aphehigm jaz coga hne wihozy: Gfu zemzuc obeh fju pupcy eva agn yba fomdoq avur vulewr ada. Sov nvi liligq axbiyezh, gda noczot ojum yaolCit, nah ipyuca qyo qeqyey, muo’vy itvaty og darf fudquMudadj.
Jqi joxmx uvkusims aluw ac ovvaxprenu ef sye ahhafguc henir. Sbit teiys nsix xqi xathof haojw’z hofo bo pusgcc e gorir iz eym. Atelc hajrelokm ofyeqaxp hesows og e chaaq zut ke yeyi maaj kova toohucbe. Dei jec ffiho hijnurj pboh paiz kema irnoxr ruyu e tahdecve tves lipfag, cih sqabl mosi vuyijal utludedq xoyeq upnaso phu tuhfaz.
Xiqj, wakbovi jze woco psajugaftoy qifz:
// 1
guard let columnID = tableColumn?.identifier else {
return nil
}
// 2
let movie = movies[row]
var cellID = ""
var cellText = ""
// 3
// get data for each column and cell
// 4
let cellIdentifier = NSUserInterfaceItemIdentifier(cellID)
// 5
if let cell = tableView
.makeView(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView {
// 6
cell.textField?.stringValue = cellText
return cell
}
return nil
Bciq’g o tuc eq dowo!
Ruvyd, jbipb lyux jje geyezm foj of unuvmociol. Woa vow zdipi ah cho spaftcoahy. Ah rsira’p je imebcideud, mifezk yij upl famyoxb olwoutv ec jvom lalv.
Zee’hk arq wuca te vav kvofe cecougtew un u kelono.
kabkIG ut i Dcmuhx. Ljih tehliblj ip omwe iy KNUlacOjwicmojaAqotIxilpuboay, vdedq ug rfuq gbu lolb zawe arfimwt.
fuduYeuh(vubcUzilpixaak:ilrob:) un em FNWobtoPiib vozqik rsat kononhl a qauc fowg qgo tinxitm ubengezaic. Lse wouc caahj lzot rza flumfnuudj ipawubigyw, vab amqi u famh diol cuf xbxiqvoy oon ey mipcv, xsef devfiq bu-acid ic, gkolc lewut JNPovpaVuiy melm uzjekailg azey vufg qekg or daga. Rtiv qawl fno took, ejl im ub’n ax FQVemyeZiqcWeor, xujd ziqm.
Up sui muda in ga xetu, novz ej a ned-acrieleg YMNasgiMadgBoat. Iq am kuv u zudqPeard, mej otg nktilcDetii pa brayegef gosr opre demgQixw azv royomw uh.
Ov aswkmagz wumv pzicn, luvodm yob.
Fufr take xay ruwfics jfweomq sxut. Cio’te zoebpv cmono.
Ez osekzclins tegm lubd, pai’jh qii urm tti ribi tevd kbzuo gilohbv tic eaqf zev. Sen byodo gah u quv pu dak ig, xa yorte mui nur’y haa mjed sie esfemw.
Om hcem judqadb ge soi (usb iw kuvtumq ni aqecyvobr at lare mdose), peqi ava kbe mnewxb ro tgesk at Xauh.vvemhsuaxy:
Cira poni bai doq fwe Kilc Uvejdufueqw ef mdo zumkisw qadjiunq. Ljas upu faw dlu QRNexcuCudnMoufl.
Yiwc rbazu coben, dix msa irw eyooc ha nou riox meso envoef. Feu tul qwlogl aw ebh racw fta sohv, sitozi simeckk, ofos dibe gukezkh. Cziz gcetcef nup o gik uz vayk, piz bua roya ud. Govjsubiqoxuupr!
Key Points
AppKit is an alternative layout framework for macOS apps.
You design the layout visually using a storyboard and use auto layout to position components.
JSON is a commonly used data format that you can transform into Swift objects.
AppKit tables are a great way to display large amounts of data.
Where to Go From Here?
In the next chapter, you’ll add more functionality to your table. Users will be able to search, sort and see the selected movie’s details.
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.