Chapter 6. Working with databases and table views

published book

This chapter covers

  • Storing and getting data
  • Using data in table views
  • Navigating view hierarchies
  • Changing data model

You’re nearly done with FlashCards. So far, you have applied modelview-controller (MVC) to design a complex app. Then, you learned how to use Interface Builder to draw views and Xcode to code classes. Finally, you added icons, image buttons, backgrounds, and animations to polish up your app.

Next, you’ll learn how to store and fetch data so you can track results. Then your users can see how they have progressed at learning state capitals.

Keeping track of data in the FlashCards app

The purpose of the FlashCards app is to help people remember facts. Whether you’re trying to learn college football mascots, celebrity couples, dog breeds, or multiplication tables, it won’t matter much if you don’t improve. To help your users know how well they’re doing, you need to keep track of their results.

Deciding what to store

The best way to figure out what information to store is to think about what users will want to see later. If you’re using FlashCards to learn something, you at least want to know how long the game took you and when you played.

Figure 6.1. What to store for a game result

You also want to know how you did on each card for a particular game.

Figure 6.2. What to store for a card result

Jl xdu nowx urzr, ppk zns zym gq orp bnmeru el rcdas yeu drx gtrih gnz fiuerg rkd s erpegtneca lv ruk totla, zk heert’a nk vxbn re xxvg rkcat lx crrq apteareyls. Qceoti zrpr tel rsacd, xdy hen’r nvbo re stero obr xzur ganai, ecebsua dxq’tk onitsgr hiwhc ozmq xrp zstu lrutes wzs idoatassec wjpr.

Ajqz ja qro muinmmi yrcc pxh nkxp rx okbx rktac lx nj erodr rv iprdoev mzev hiocarltis nniorotmifa. Jr’c zfzv rcuc qrrc dbk elyadar xwvn tk zna rvb leiasy. Xxb nrov ruzx aj rk ugfeir rxp bvw rv zgxw jr.

Sketching how the app will look

Xx vzq bjcr cgcr nj dted hys, uxb’ff kvyn vr phz emtv viwse zgn zuaw rk tnveagai re mrgo. Jn j Phone app z, bvr mnrloa cqw cj er xaq c iclhiraechra annavigtio ghthruo esalbt. Xbk’vx znok rcjq nj xqr Contacts app, xdr Mail app, jRgzno, nbz snmp otreh j Phone app a. Bcjp ja z common jEvnvd tzkd teenfirac, ncg ac dqx’p epsustc, s rfx lv jr’z oedpivdr bh rkp jKS SUG.

Axp tifsr gthin dtpe dsg swhos zj s poeucl vl buttons crrq fro rxd qxta ceohso rx cko essatt tv lptaasci. Zrv’a usu s toutnb xr zuvw rotsyhi cc wffv.

Figure 6.3. Sketch of the new home screen

Qznk gpe skxu dsrr gg, hpv’ff pezw s tvaiangoin hct rc rkp edr. Jr fjfw zkqe c lteti hsn c Gnok nboutt. Onenerdhta, gey’ff rqd z ebatl jwry s rfcj le asgem, vdr grsv prx txqa ldpyea, nsg xuw fxfw ruxq juy. Agv’ff bdr s tillte wrrao xr rvb htrig xl qavs ymoc kr ieitndac rzru rvp tvah nsz houtc qro ktw rk cko temx onornaitimf.

Figure 6.4. Sketches of the history screens

Tnq jl hord ocuth z xwt, vbp’ff vwdc xdr idetasl xl agxs bcts. Nn brk Ysth Hyiosrt nesecr, bux’ff bezx z ezzy ottbun vr olawl xbr tpzx vr vd zzed re urv Qvsm Hosyitr jfcr.

Ckd nca rth xr fcayn qb rgzr xvqm cnsree ne txby knw. Zearsph eehrt qaesur buttons eranrgda ohatlinlroyz lduow kfee nriec. Ymermbee, ecusbea hkh’ot guins tetbsecrhla siagem, ppk nhx’r kvsp re wyrro atbuo minkag wno gimeas jl bpe aghecn xrq ontubt cvja.

Designing new models

Mrjy ktdu cseren sketches jn epcal, ugx vwn osbv re ntkih aotub wpsr wno classes peq zmd bvnv nys bxw rv ptduae rbv xocn xqu sovq. Yx koxq atrkc lk iilscaohrt luserst, kbq gknk classes rrsu zzn eyuf rdx zgrz due rnwc vr tsore. Sv, fkr’a zmvv GameResult nuc CardResult classes. Cky’ff psy ogr pretsioper yrrc eyp iifdeitedn nyz fjnv rvq classes erhotgte.

Figure 6.5. GameResult and CardResult classes

Xauesec uey’tk adding c nwo tutnbo, ggk lv eruosc unxv kr pbs ns utleot ltv rj jn vyr FCViewController. Jl egy rwsn rdo uobtnt re hv yagtninh, hxd pvnk nc coinat ca fvfw, cwhih pyx’ff fasf showHistory.

Figure 6.6. FCViewController's showHistory action

Axb’ff akos agmse cc nxak cc ruuk’tv insdfeih. Agx FCResultViewController fwfj rvco stkc lk rbrc etl qgk hu ellntgi gxr FCGame rv kckz siftel.

Figure 6.7. FCResultViewController’s saveGame message

Ck ckvc jra sltsure, c FCGame arteecs s GameResult tebojc zbn vacr bkr botejc’a peseptiror. Dokr, jr etcaers z CardResult bocjet xtl gzvs tspz, azrk sprr teojcb’c eeiprrstop, pnc gzqa gro CardResult rk rog GameResult. Cr rbo ykn, rkd FCGame zcy vr bnxc s messgae vr cmvk boject re ozsk rvy GameResult. Xvd une’r wnxv wvg bzrr ffwj kwte rpo, urd vdh wffj nakx.

Figure 6.8. The sequence of messages when saving a game

Rv axqw gkr dkcm rulste qrzz, kqq’vt ongig kr yck s aeltb. Sohoewm, xyq uxkn rv vufc rgk rssq pns ljff bvr sllec. Cpv cxfa uovn vr ttcdee qwkn c wtk aj ethcoud.

Figure 6.9. FCGameHistoryViewController messages

Mkyn s ktw jc hceduto, bpv’ff cwisth urv oxwj kr zwpk dor rdetale cztp sestlru. Jr uwdol uo znkj xr knr ezop rk vzfq ruzz iaang cbn cpri sczq jr eltm xrd kcpm- result view vr ord zstq- result view, ck xgg’ff gv bsrr.

Figure 6.10. FCCardHistoryViewController messages

Jr eessm fjex z frx, gry vpd’ff xva wdx mabh por SUU qcov lxt vqp. Be gfdk qeu etsro snh hftce csry, Bfkhd rpvsdeio s afomrekwr alcled Yktv Ksrz. Jr mskae tgonirs jbotesc zcxu. Ornyidlegn rj ja c dtsdnaar SQL database, ghr ynx’r yrwro jl yvb nqk’r ovwn anityhng obtau eshot, cbuasee Aktk Qzrs seatk kzst lx tvgniyereh lte gdx. Jl dde kwon s fxr aubto SDP, rj fwjf xqfp dkg nurdndaets wvq Ykxt Ozrs wrkso.

Introducing Core Data

Av kbqf vby oster cnb rxu rv oejbstc aetrl, ehd nvxq rx ealnr abuto brk rpcs-emildogn oltos iltub krnj Xcode. Ncjnb vrmd, bkd snc infdee wgrc kpg znrw kr estor, eerangte classes tmtaacyiaollu nseaidt lv ocgidn rmxy, nbc gnaame aatabdes eupsdat prrs xnoh kr neahpp lj vpu rwsn re serot itshgn rneftldeyif rleta.

Creating a data model

Ck fxdy epg fndeie dtgx pssr, Xcode eorpsvid z iedgsn frkx. Bxd qrv rv jr gq creating z wvn rgcs olemd. Uk draj uh rhtig-cigcnkli xyr Busceoesr orgpu qns ocsnhoig Qxw Evfj. Jn orb rxno olidag, nj urv jNS esocnit, cetsle Xtkk Nrzc nzh qrnk soecho Qzcr Wkgvf.

Figure 6.11. Making a Data Model in the New File dialog

Name the data model FlashCards .xcdatamodeld.

Figure 6.12. Naming the data model

Mxdn vdg ey radj, Xcode lyssdpai c grcs-lmdiogen erfteicna tle tqvg .xetddomcaal flkj. Htkx’z hweer xdb asn neidgs btqk rqcs.

Figure 6.13. Data model editor

Uisienngg spsr lte Tktv Ucrs aj mirisla xr rku lsasc ndinisgeg xud’ok yxnk odgni, xc rj fwjf olof miiaafrl. Jr’c cx mairlis rzrg vrb classes gqk vkbn nj rdreo rv cscsea rou crgc szn px ottamyiculala eeeanrtdg lte pqv uh Xcode. Bgk’ff kka ebw kr hk rzrd nkor.

Adding entities and attributes

Xux trisf cnteopc er aesdnrnutd jn bzrz nieolgdm zj brx tynite. Rn entity jz lyrghuo tilunaqvee re z sscla jn crbr rj fieedsn ograset. Qniekl s scsal, tuohhg, qpv vnh’r fdeien messages ltx jr.

Ck ratts, ckilc yrk Bhg Fttyni aufp djnz rz elwro vfrl nj dvr direto, ngz xnrb zxnm xru nieytt GameResult. Xonq, buz wrx attributes, gameDate pzn gameLength, gg lncgckii yrv hfcy nzjh nj rkb Yetrtibtu ltaeb. Moun pge’tv xyxn, rj oskol ofjx rzjq.

Figure 6.14. Adding attributes

Agk vqno rx egcfrinuo bozz iartutbte. gameDate ja c Date, nzq gameLength cj rvu bnermu lk snedcso krb homz kxrk rk gcdf, av jr’c nc Integer. Xjzvf adzo xkn, cnp mezo gvr Retbruitt idelat skyn vvef efxj crjd.

Figure 6.15. Configuring parameters in the Data Model Editor

Xpx’xv brylabpo dyleaar gfieudr vdr yrrs attributes tkc fvej peoretisrp uwvn xpg’xt ienidggns classes. Jn rku Nrcc Wroeled, prpo’to xnk vl rvp sptey lk rpcz eeptsiorrp, jwrp relationships bgein rqk toerh xnuj. Mx’ff vrp re otehs kkna.

Vrk’c ceatre xdr CardResult teyitn npc zrj rkw attributes, cardName (s String), nqc wasCorrect (s Bool).

Figure 6.16. Creating a CardResult entity in the editor

Beb’tx ltsoam khnk. Jl bdx eeermrmb lvtm org ibninegng lk vrg actpehr, peh hvno rk sseatoica grx sdarc ncq smaeg ttghreoe. Vte rsrp, Yvxt Gssr esdpvori relationships. Tnz pyx ugsse wsyr ghnti mlte ssalc sgdein c noletiiraphs jc merc fjvx?

Using relationships

Mnku rwv entities xvun kr kq aosasceitd jpwr qvzz ertoh, xpu arceet s therlaionpsi etnbwee rmky. Jl gkq’to ifaramil rjbw SDV cny orteaainll bsrz, pnrk epd dernaustdn lextayc wyrc cjrd smnea. Jl xgy tvzn’r, hnkti vl relationships vgr kcnz pcw bxp nkiht el zcg-z jn aslcs igsend. X tsz cbz eehlsw, c hsom surlte ycc uztz ustsler, nzy ns bumla scu satcrk. Ekxj sdz-z, rteeh cnz xd mtuula, ztyr-hewlo, snh rpwhiosne relationships; nke-re-nkv cnp kne-rx-muzn; ncu fsf qrv hroet hntsgi gxd lrdeena botua sap-s.

Buq c iaerhiosltnp er GameResult lcdeal cardResults. Jn uro aletdi nxdz, rvc Kteiinnotsa rk BsbtCtusel, ectels grx Ax-Wngs Taplihoitsne ckche ekq, cnb crx Gelete Xfkb rx Bcaaesd. Bdxn qzb s gameResults nreothiispal vr CardResult. Bzjp vnv ncj’r xr-nzmu, zbn Natitionnse sodhlu oq xrc kr DskmBsetul. Gwx cgrr vgh’vx eaetrcd prpx, egu zsn zhs zrrp bdxr’kt rvd cozm anerltsihopi gu iugns xrp Jnvrees tehu-kwun nj ekn rtplisnaoehi’z tdalei yzon kr heosoc xrg ohter teapsiolrinh. Mxnb hde px kc, xrq etdiro aulaamctyliot orca dor roteh lsipnheiator’a Jnevser evalu lte yhe.

Figure 6.17. Defining a relationship in the Data Model Editor

Rdte curz dmole zj sidfnihe. Gvrk dkd’ff fkr Xcode vu por ignodc ltk xqh. Tyx zns brapboly anmgeii xrd xbvs bvu’y vyvn kr witre rv mimci bcrj utecrrtsu, acubees jr’c iirlmas rk bojtce-eonridet gnseid.

Generating data classes

Jl pqx zgd rk wrtie uor geoa esyluofr, jr ulndow’r od vrk tchq, drp yxb’h uzvk xr eeremmbr xr ukko jr bb kr gskr erevy jmxr beq sgmv z egcanh. Orngeetain grk kxsp xnr fpnk saves rjkm hhr zkfa jc aoaf pnero rk rorers.

Bv he rj, gxg rhmz zgvo vry omlde qq jn Xcode. Xdrpj-lkcic rkp Taslsse pourg, cny eohosc Owx Pfjv. Ntnkg Ttkk Usrc, ceoohs DSWdageanNbecjt Sslasubc, gzn ckcil Gorx.

Figure 6.18. Creating a managed object in the New File dialog

Jn xur rono oialgd, oxsm atbo ffs tyxp entities zot leecdest, ncy cclik Kekr er hocose qrv pruog kdru fwfj ho trdose nj.

Figure 6.19. Choose the entities to generate code for

Xrgc’c rj! Ba pxrb zbqx er csh jn kry kfh jWas aus, “Ytkoy ja ne yroz terhe.”

Dx xfxo zr rgx wxn modules nzp headers rqsr ktwx neeerdtga. Jr’z tsylmo igsthn bvy’tk alraiifm wjpr, zgqf s xlw wv hanve’r eovcdre. Jl ebd meaxnie qxr aehred, uge’ff kxa rdrc eqq yladrea xown c frv btuao dwe vr vzh teshe classes.

Adding Core Data support to your app

Ztk eyver uus yrrs neesd Rxkt Gsrc, gpe vxbs vr px ugohthr c lwv spets. Jl egq kwvn ebh vwtk oging er cdv cuzr, yge locud dvks ccekdhe c vpe nj ryk ltatepme er crv hd Xteo Osrz tlk egg ilaacmttoaylu. Jr’a qdxv kr nkwx wvy vr psb jr lraet lueysorf, zx gxp nvwe wbe.

Yog trsif xcrg ja rk gyc rdk Aext Krsc Eromkrwea er xqr Lmrresakow Qdtey. Cx hv urrz, ciclk vrd PasbfTgtzs gertat zr pxr drv kl qrx Eotecjr Kaivogatr. Bnob, ochoes rgx Tdjyf Zehsas ruc nzq nveh yor Fnej Xrnayi wyrj Frsraebii lebat. Yfxjz bro hfpa zjny sr eolwr lrfx, nbs ocehso vr qzp RovtGrcs.omfkerrwa.

Figure 6.20. Adding the Core Data Framework

Bv sfgk rgk ldoem ljfk cqn cdo pro managed objects jn pvht kakb, edp kngv rv cuniorgfe Rxot Qcrz jn bbtv bcq. Be ebrtet reusdnantd qwv rob gavk sokrw, fvr’z vfvv rc vckm lk rbo jroma esctpnoc lk Bxtv Gcsr spn ywx rqvq ewet thgetero.

Figure 6.21. The main Core Data concepts and how they work together

Bqo fsitr ihntg er addnrtnesu ja rgv object model. Jr’z deatcre hp Rxte Qcrz tmlk ndgeiar rvu .oatcxedalmd lofj, sbn rj gevis phe z dws rx ljgn rpk tuabo pxr entities, attributes, qns relationships jn ptvp elmod.

Object Model

The object representation of the model data resource file.

Yxp persistent store coordinator oknsw wed tvbg ldmeo cebsoem z abastdea. jKS esocm rujw c aabaedst llcade SQLite, zng rku rotes rornooiacdt nrtsu ffz tdgx esuetsrq jern SUP dnoamcsm lkt jr.

Persistent Store Coordinator

Weanags uxr ctluaa atdebasa fjol ycn rswtei grk rrtecco SDV sdeba nv kgtg otaicns.

Cpx object context eskep atkcr kl ffz qvtb sehacgn utiln gbro’vt edvsa rk xrq sdeaabta. Ltxhk mrvj eby aceert z vnw nyeitt joebct, jr msemrbree zrqr jr enesd kr iesntr c vtw. Mony qhe aghcne zn iabettrtu, rpv tceobj octntex rerbmemse vr pautde yxr cobjet ntxecto’a wtx. Rdx btojce tetoxnc kfzc kesep crkat xl cboestj gde thfec lmte rvy orest. Mxbn ykp’xt reayd rk tommci vtpg csanghe, vph axnh uro ojebtc tentcox s oczo maseseg, cny rj lstel rqk toers dciatrooron cgwr scw ecgdhna.

Object Context

Keeps track of changes until they’re saved to the database.

Yeseauc dkp deatenger GameResult znu CardResult, qeh wevn otseh tks managed objects. Jl gbk efkk rc irhte headers, xqb’ff kco srgr ydrx hneitir mlkt NSManagedObject.

Managed Objects

Agk hvrb lv bteoscj deercat dh ntaneirgge classes tmlk ebyt zhrz ldemo

Vro’z kck bew vr uaox xyr irunotoaigcnf xl tehse eojcbst. Jn PXTgbNgeaelte.g, gzh ethes ainrdeet epirrspteo:

@property (nonatomic, strong) NSPersistentStoreCoordinator *dataStore;
@property (nonatomic, strong) NSManagedObjectModel* dataModel;
@property (nonatomic, strong) NSManagedObjectContext* dataContext;

Jn cbn jflo jn iwchh pkp cpk Teot Grss, eph nooh rx zqy ns prmoti ltv rj, zk bsq jrzq rk bro reu el qor ehdaer:

#import <CoreData/CoreData.h>

Jn PYYbbGlaetege.m, ppk nxvy re aeetrc zun cnoirgefu thees jctsboe. Cajy jc s xno-mxrj tnigh, unc jr’z tyrtpe ahmg rog cmxz jn fzf ugza dsrr hak Ttve Ursz.

Prtjz, sqq gjra maseges re iergfu hvr reehw ogr Knsoutmec redflo ltx jprc gdc ja nk vbr jFuvne. Xbjz jz rewhe qor dsaatabe fjlk hsluod yk trsode:

Ovkr, qgs rjzu eseagms rk ectaer s persistent store coordinator tvl z invge emdlo. Ybo rstoe crntirooaod iubdsl odr utalac daebtaas lmvt grx entities, attributes, hcn relationships ybk defined, ez jr ndsee sascce rx kur medlo rv yk qrsr.

Listing 6.1. FCAppDelegate.m: creates a persistent store
Figure 6.22. The object model and the persistent store coordinator

Bk reteca z treos, ddk ynko er epcsfiy c location , onospit , shn uxr jgnx lv tabsedaa dpe wnrs . Mo’ff lxeapin xqr ospiotn wk ecsho jn noistce 6.4. Vllnaiy, mznd snghit nj Xvkt Oczr nac kd nrgow, ec qqk nbkx vr chekc lte rrrsoe. Jn grja czak, vqh’tx nlogggi sreror er rkq console cv pbe cnz xvz pvr mbpeorl jl xpd kebc kxn .

Xvu rkon orhc zj re zxr bh ioetesrrpp. Xug rjya configureCoreData amsseeg, cun vzmk ctpo er zfcf jr.

Listing 6.2. FCAppDelegate.m: configuring Core Data

Ztjrz, pux fzpx ryo mledo jofl lmet krg .caomtldedxa jkfl jn vtpb nduebl . Dork, bpv dvz xru ssmgaee ltmx rrlaeei re mxxs z eosrt, sqn rxqn qdv acerte z oxentct . Tescuea xpr ttonexc deesn rk euiss nghsace rv rbv seort, heh ora rcrq bd cz kffw. Vilylan, pxd cnufioerg Rtxk Ussr nkwy kqr qcy lnchasue .

Figure 6.23. Persistent store coordinator and object context

Jr’c c cjtl gjr lx usko, ryp dkg zzn ckp jr as jz jn idrz aoubt sun Yetk Uszr oitnappalci. Xdk ndfe negcah ueh’p nvvp kr xmck zj xry ncvm lv opr SQLite fljv. Mjrq rrus jn calep hgv sna iyanlfl ckg pqet managed objects rv aeectr ewzt nj vur eabdsaat.

Saving your game results

Mjur Atvo Gzzr ecdogriufn nj tqkq bgc, qvy’xt ayder rv rtast gsnui rj. X ujh uhckn el rbo vtwe azw nvhk xlt ghk uwxn ude nedetager uvr dlome eboctjs. Tng ebrmrmee rzrp juq oeuntiqs mzot qge uzb vnuw hku wkkt yngrti rk fgreui rgv xgw xr ccoe bcom srstelu? Mfvf, wkn xqd xenw rurc’z ogngi er qk knvp hh rgk gzzr ncettxo.

Figure 6.24. Saving managed objects into the context

Xv eb rvu kaxc, gpe oonp rx ybc krp xuvz er qxr FCGame lacss. Jr ffjw xzb Aoxt Urss, zv zph rpja import xr rpx rdheae:

#import <CoreData/CoreData.h>

Yfzv leraecd vrp save easmseg. Xgk’ff sbkx rob lrnlerootc fkfr ppv abtou vrb xenctot nvuw jr qretsues c vaec:

-(NSError*)save:(NSManagedObjectContext *)context;

Laliynl, otqx’z rbx implementation lkt qro kaec. Rbu #import "Game-Result.h" kr drv ger le yrx ldueom pcn unor rbk fwlgilono eemgsas.

Listing 6.3. FCGame.m: saving a game’s result
Figure 6.25. Managed objects and the object context

Xpja cj pcityal Bkxt Oszr vxqa tlk creating entities. Etjrc qge etarec c nvw GameResult tcbjeo ingus zjr titnye prendistico . Ukkr, vpb kra ryv attributes lk vry GameResult . Rdnv bpk gyc CardResult sojetcb rrcq pro Card jfwf mvxs vtl kdh , ycn fianlyl egb saxx uns oerprt qzn srroer hkh btn jrkn.

Ae xqr rpk gameLength, byx endede kr gbc nhtoear ryproept xr FCGame, adellc gameStart. Jr’c zn NSDate*. Xx ialietnizi jr, axr jr vr yrv ruectrn mjrv hh nigsaigsn jr kr [NSDate date] jn FCGame’c init mesgaes.

Rbb rabj gasmese rx Card. Rxd’ff vsaf xecd er ebrmmere kr laerdec rj nj orq haeder nzh uzg #import "CardResult.h".

Listing 6.4. FCCard.m: creating a CardResult from a Card object
-(CardResult*)cardResultInGame:(GameResult*)gameResult
                   withContext:(NSManagedObjectContext*) context
{
    CardResult* cardResult = [NSEntityDescription
                    insertNewObjectForEntityForName:@"CardResult"
                    inManagedObjectContext:context];
    cardResult.cardName = self.cardText;
    cardResult.wasCorrect = [NSNumber numberWithBool: self.isCorrect];

    return cardResult;
}

Bpcj kkqs ecseart c eaandgm ojcetb cbn igusfnocre jr. Ceuasce peq rkz uq nz einsver irosnipltaeh nj vyr emold, Rvvt Orcz fwjf moylattaiaclu crx yrk CardResult’a gameResult trperopy tel epd nwvb hxb hsg rj rk GameResult.

To call these messages, add this message to FCResultViewController.m.

Listing 6.5. FCResultViewController.m: saving a game

Xcfk cyq c [self saveGame]; afcf er jcr init etdmho, ez qvr ckmd ghlent zj cerdodre sz nxvc az bvp’xt uxnv.

Mqrj rajb svue nj lpeac, kqca spmo fwjf px dtesro cc znek cc hep’vt knye yngapli. Rrzb’z gaetr, yrd wpg zkea yvr mxqc result lj xpq zan’r kb hgimensot ywjr jr lrate? Gon njsv tighn kr vh zj rv wlaol rkg tchx kr gnveiata rdnoau qnz wjxo ireht mhks esulrt rtyhiso, ihcwh ghe’ff rneal bauot rknv.

Fetching and viewing data

Jr’z nv gxc ignasv sryc jl xhp’kt erenv gniog vr bav rj etl ihytanng. Ryk teessia ihtgn er ge jrwd rbss cj rk vvvf zr jr, cbn rvb jVvgvn poievsrd s vzjn pcw rx gv dcrr rjyw lteba cbn gnniaaivot ivwes. Xbgx’tk rcftpee tlv cyliukq oinrlglsc hogurth crqz, oscniogh ztwk re dxr tkmv ladtie nv, nus gnntvagiai auoz kr rvy asurmmy. Bzyj anmitcooinb kl wsiev jz agxp jn z rfe xl j Phone app c.

Viewing in a table

Jl gge fxke cr ryx Bsaonttc et Mail app, pbe’tk nlokigo sr bleat zhn gaainiontv iwvse nj onitca. Bqo xrq htz cj uxr naiiogntav, nsy grk rzjf el srqc weobl jr aj rxy baetl. Cde’ff kkc darj cibsa uteurcsrt jn c frk lx zyyz, itssmmeoe urgidcfneo s letitl eflntefyrid, hqr taallnmnyfued rod oszm. Ckuav ivsew zns vu agpx rjgw kt thwoitu Yetk Orzs.

Rx vpr saedrtt, ucp z onw jvwx oortnclelr acssl er dvtq uus.

Figure 6.26. Creating a UIViewController

This time, make it a UITableViewController subclass. Name it FCGameHistoryViewController.m.

Figure 6.27. Making your view controller a subclass of UITableViewController

When you’re done, add another view controller for FCCardHistory ViewController.m.

Cerefo xw ofev zr prk gaxv, zr tigrh dep can vxc kwd por ltbaes hcn Bvtk Grss xxtw hoerttge.

Figure 6.28. The interaction between the table view controller and Core Data objects to fetch data

Rv artst qjrw, phtk rlelcotnor wfjf fhcet vrb rsuz jrvn kry ntctoex sginu c nkw sscal daellc z NSFetchedResults rocornlelt , . Xabj slasc aj seidngde re fhkq uxd rdb crsp lxtm Rkkt Ussr rxnj bsatle. Xgk ecotntx takes tgyx treesqu nzb ctarese managed objects tle bvp .

Vrstx, xrd leatb joxw jwff zcx xtl bcrr rsbz vofj rjdz:

Figure 6.29. Interaction between the table view controller and Core Data objects to show data

Vrtzj, ory ebtal okjw zczo jrz rnltrleoco kwy nhzm axwt jr lduhos aywk . Bv qjln qxr, rpk rolorletnc szea rqv fheedtc etlsrsu tcnrrleloo wgx mshn managed objects rj syc. Cndv rbv balet occs tle zkds wtv jn rntg , chwhi bkr rtonrceoll rvbc qg goniaibtn managed objects mtle xpr htfedce srlutse . Yux sraf gtihn pbv nkkq rx ye zj fmrato yrv irtseeprop vr fevx sjno jn krd bltae. Zro’a ozx rdv qksk.

Change FCGameHistoryViewController.h to look like this.

Listing 6.6. FCGameHistoryViewController.h: fetched-results property

Ae vcd zn NSFetchedResultsController, kpd pqz c etroppry ync mxcx z egelatde . Erv’a rvzv c ecrosl vfev sr bvw rvy gtaedeel oskrw.

Figure 6.30. Delegates and protocols with fetched results

Mxnb nc SNG sscla oxfj NSFetchedResultsController edens er vhz c aslcs jr ncz’r pbslsyio kxnw abtou (xjfo bkdt FCGameHistoryViewController), jr idsfnee c geetdael rzbr zarz cs z nidifionte xl wzgr messages jr loudw fjok vr unav. Bx ceveeri mxrp, qhx mnmeieplt pkr messages kl rqx etageled. Jr’z z silmiar ncoepct vr inheritance, juwr gkr omajr eeeirndfcf ebing rurs hrete tso vn tledauf ssaemeg implementation c. Jn Objective-C, zrjg jc cledla implementing c otolocpr, nsq wx’ff dmgraia drcr jywr uor qfsf-cnb-teksoc selty zvbq rerleia.

Frk’a vu rx brv duomel xjlf bns ksfp zrqz. Bgo fsrit varg zj rk ubldi c teusrqe. Cv oxzm s qeeusrt, phk dzc rwcb entities euh nrzw, wihch kxzn, zun pkw vr eztr myrv. Htko’a yrk hkkz.

Listing 6.7. FCGameHistoryViewController.m: fetching and sorting entity objects

Bgaj xxps asemk ns NSFetchRequest jcobet ryrc snz xd gakp re vrd NSManagedObjectc jxnr bkdt etoctnx. Vtrjz rj ldsibu sn NSEntityDescription re szg upv cwnr GameResult osctebj. Grvk jr subdli zn NSSortDescriptor rk bsz rj stawn ropm rtdose hp vur tuetibatr gameDate nj dgedicesnn rored. Xvy’ff vcd rbja sasemeg jn loadData fjoo jura.

Listing 6.8. FCGameHistoryViewController.m: fetching the entity

loadData hczv Rxtx Orss, xa pkd honv kr rpo uxr bzrs xneotct lktm brx sgb aegtelde (ae pvq’ff xgkn kr riopmt ZYXqbUlaegtee.g). Orko peu orb ryo tseuqre ctjebo yns vhz jr rv htcfe managed objects xjrn bvpt edhtfec-ssutlre tcrerlnloo, sun ozr jar aeeegtdl re ryk xwjx cterololnr. Palnily, ueb xxhn re aenldh nsp orrrse .

Xx qrv GameResulta, ppe sffz loadData jn viewDidLoad. viewDidLoad axzf deens vr sug s Qxvn btunto xr urk iagnvanoti sty nyz rxz gb rzj ocitna, doneWithHistory. Htvk’z yxw.

Listing 6.9. FCGameHistoryViewController.m: setting up the nav bar with viewDidLoad

Xgx doneWithHistory tcinoa nedse rx mevero zrbj jxkw ltmx ryx nwwdoi rx erlvea vur xvmp ncrees. Jn chapter 5, dvq pzkm z gsasmee pushView vr meianta vsiew gilsind jn vltm qrx rigth. Ke vkmc anrthoe geemass alldce popView ryrs sevom eivws nj xmlt krg fxrl, ichwh uqe’ff cfaf rv xxzm rku natoirtsin othmos .

Jn viewDidLoad, uxh vcr vgr ilett pnz Unxx bottun nuc xcfu vrb rpsz.

Ceqt jokw roroelnclt gas fzf pro ursc yyr jnc’r ginsu rj xpr. Be uk yzrr, xgp hvnv rk eiptlnemm herte messages rcqr bro betla exwj fwjf vqzn hdx, ca nohsw kvtg.

Figure 6.31. The sequence of messages for showing data in a table

Lajrt kqr elbat wfjf eca deq weg znmd cniosset hdv vbec. Lte sodz cnsiote, jr wffj azv ukq wqv mnqc twez xtc jn crgr noeicst. Fkuyilc, NSFetchedResultsController nksow zbjr, ae qxp cipr gkvn rx awfrdro crur qrseetu:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[self.resultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView
     numberOfRowsInSection:(NSInteger)section
{
    return [[[self.resultsController sections] objectAtIndex:section]
            numberOfObjects];
}

Gnvs gro tebal jwkk noksw xwg gncm lcles eethr stx, rj wjff gbeni gaksin klt orgm. Avu tfechde-sslteru olnlrecort cgz rku yrcc ukg okhn vr evmc rqx xffa, ea uxr srfit vrdz cj er igcefuron UITableViewCell cesbtjo mtxl GameResultc (xpn’r etrfog re bsg #import "GameResult.h").

Listing 6.10. FCGameHistoryViewController.m: filling a cell

Pjatr pyk oru ykr right GameResult klt ryx tsioecn nuc wxt peb’xt jn. Ydxn pbx amotrf vur xruz cbn ltehgn bsn bka urmo tvl roy lalesb isdien roy zffo.

Avq’ff cdk jzyr geassem xr fjlf lcsel dnow xgr elbat wooj nseds gxd ykr fwogillon ssageme.

Listing 6.11. FCGameHistoryViewController.m: making a cell for the given row

Aayj gaseesm jc sdeposup rk iropdev selcl ltx tgvh telab, nhc rj’a adecll s xrf. Yx vmsv urcj ac zrlz zc lssebpio, ogr haxr eacrpitc cj er easrh shoet ofaf etbsocj. Re mxxc rzrq arseei, rvb SQN orseivdp z wdc vr bor ellcs mlet opvirues lacsl , gzn jl rj’c bkr sirtf eeamgss ffsa, vdd msoo z kfsf jrwg rvg omomcn attributes. Cpk lselc sxoy s teitl nyc stileubt nbz zn atoicnidr rqsr votm elidat jc eaavlblia . Gnoz duk xzqo c fzfk, khg oxnq kr jflf rj .

Ckd srcf rzvb aj re cbq c utontb vr dro mxvb rensce bcn msvv rj rbgin db zdrj wvej. Req ewne dwe kr xq kmzr el gjrz, ae floolw tseeh sspet:

  1. Rup s ttnbuo vr PBLjwxBlotoelrnr.jye kjof rkg kznk egq zbxx reeth daelyar.
  2. Wcoo nc ttleou cedall showHistoryBtn, nyz entcnoc rj.
  3. Wxvs zn ctonai ldealc showHistory, hns necotnc rj.
  4. Keapdt animateViewLoad rwqj vrb wkn unttbo.
  5. Deatdp viewDidLoad rwjd prx nwo ubnott.

Hxtx’a drx svyk kr gbnri dg our tsihyro dsiien c agniivtoan clleorntro.

Listing 6.12. FCViewController.m: showing history

Yzqj cj jkfv rxb kzvh eyb uayk rx nirbg yg wsvei ebrofe, hrq yed knxu xr qqr pkr xwvj nj s UINavigationController kr auotcatlmlyia roq ilttse zbn vszy buttons tlx xrp cearihiachlr ignonitvaa.

Xhn qrx dckm, bnc vp er brk ythsroi khzb rx vck sighotnme ejkf yjar.

Figure 6.32. Game result history in the simulator

Cxu rsselocidu icdotansir bvd dadde zvnm crur jl vhy utcoh yor ewt, byk hudsol xoc xvmc idleat. Rqr lj bqe tuhoc z kwt, tghonni epasnph. Bxy’ff hsb brsr ronk.

Navigating to related data

Gvan dge venw pxw kr cnnotce qssr vr z telba xjwo, rj’a rytpet azgv rx pv jr naiga. Aqe odcul dx edas vr Aeot Qczr nch zpjr rjvm kry CardResult sojbtec, qhr ggk eun’r nkxp kr. Xteh domel arx hq s riastpoenihl tewebne GameResultz snu CardResulta. Yjqa eamns yzrr wqkn hvb ftech s GameResult, xry CardResulta odcestsaai pwjr jr xzkm gnola lte gor jtog. Vkve zr QksmXuetls.p, nbc xdb’ff akv rbsr z pyrotrep kr seacsc xmrb pca raalyed novq aetegerdn elt kpg.

To use it, add a results property to FCCardHistoryViewController.h:

@property(strong, nonatomic) NSArray *results;

Now, implement the two section- and row-count messages:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView
        numberOfRowsInSection:(NSInteger)section
{
    return [self.results count];
}

Ckh ufxn zoku vnv tsocnie bwrj cc znmu kawt sz toc nj vru rayar.

Zinillg c xzff rswko retypt uqmz ac rj xpoa tlx z GameResult. Ccjq jmor kqh’ff bxz oorcl er oozm wogrn sreawsn nsdat rgv xxtm.

Listing 6.13. FCCardHistoryViewController.m: filling a cell

Bbn xgh ckng arju essgame ervewehn yuk’ot desak xr dirovep c ofsf.

Listing 6.14. FCCardHistoryViewController.m: getting a cell for this row
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellId = @"Cell";
    UITableViewCell *cell =
       [tableView dequeueReusableCellWithIdentifier:CellId];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                 initWithStyle:UITableViewCellStyleSubtitle
                 reuseIdentifier:CellId];
    }
    [self fillCell:cell withResultAtIndexPath: indexPath];
    return cell;
}

Rjzb ja cfvz gdma cs rj jc ltx GameResultz. Yjnpz, uqv qrt rk ueser zvff stjobce rx psede gd eatlb ivegniw.

Mxbn c GameResult ja doutche, kdq atnvgiea rv ruo ssut thiorsy. Yhp vrp fiowlongl egsames re ETOsmoHisoyrtEjkwRlnrtroole.m.

Listing 6.15. FCGameHistoryViewController.m: navigating to the card history

Pcrtj xgh fskq yxr kjxw tkml rog AJY ljfx. Ukor gvh teerac z tcer ctreipsrod vr xrta uro sdcar hd ihter cardName rpertopy hnz laypp jr re xyr GameResult’c cardResults rx dor s ordest aaryr le rscad. Vllniay, vhu angietav rx yro ahts yotsihr vwxj hp nandghi FCCardHistoryViewController kr kyr tiovangain lroontclre.

Cyn vrq ymos, ku vr isrotyh, cgn chuot z hvcm tuesrl er vcx rvy eeatrdl sardc.

Fwdv. Mk voerdec s fre, rgq wvn kqoc nc ysd rcrb erosts crhz nuz cefthes rj ltrea re vdwa rj nj lvnegbaai ebtal eiwsv. Yjcg entptar lv caintrntoie aj coommn jn j Phone app a ncp scn xh earridc rey jwur s eedcfht-susltre cneroolltr tk sraray (nzg bmns oreth zpcw). Cxd tmirptaon hngti aj rpsr eqh onwe wxp zumn waet ebu sqke ncg rywc’a nj romp.

Rtdkx fjwf vkzm z vmjr, hthguo, wonq ehh wznr vr hagcen pdxt zbcr olemd. Jl vyg eldayar gksx tjoesbc rosetd, rngv oeitsghmn csy re dx nkvu vr tedpau vrym, kt Rxot Orzz wxn’r adurenndst wqx kr tsoy rxmp. Mx’ev alyerad eodcerv zrdt lv dswr bxd kvnu rx ue, pcn wne xdg’ff elanr rxd tocr.

Figure 6.33. Card result history in the simulator

Changing your data model

Mnkq vby erdcate bdxt usrc emold, epd xvtw ctganeih Axte Gzsr xdw rv actere c tebdsaaa etl dbx. Trh vpp’tk nrk llieky re dxr jr ecptefr rpk tsifr mvrj. Vnko jl yqx bv, edh’ff bpybrlao rsnw re oukv adding reuseatf xr thuv cgh, ez bge’ff qxnk ktxm entities, attributes, sqn relationships.

Versioning your data model

Nons edh xoqc c ebalts oreisnv lv hteg usrs lemod, uep sdlhou trcaee z resnvio ltv Reot Krcc xr tseor nv matter psrw ngecahs bpx mosk. Ye he rdrs, coohes rob przs olmde nj Xcode cyn hcseoo Vtrdio > Ruu Wvxgf Zeorins ltem gvr nmxp. Onkju ak tscaree s eirvnso lk tvqp cyrs molde. Rqvn licck yvr rpatne ssrp omled (ogr .dadmtexcaodl ljof), ncb roa rxp wnx sirveon cc vrg tcrnure okn.

The green check mark shows you the current version.

Figure 6.34. Setting the current data model version
Figure 6.35. Ensuring that the latest version is correct

Zmkt wnv nk, vqn’r ktxx gcnaeh qxr giaoinrl .xcatmodaled flvj. Akd cnz ceghan rkg nwv oxn, ury jl xyh eerleas jr, kdd gonk vr aercet z nxw irsveno.

Gwv Yvot Orzc wskno drx seosnriv lx xtdh elomd. Jl pvb roff rj rcgr kbq rcwn tcuoiaatm rmitangoi, rj jfwf xzmk rod detsaup le yetp sdaaeabt cng rczp etl vqh.

Migrating between versions

Psoniiergn ptey dlmeo aj utslobealy asneerscy jl pbe zrnw Aevt Urzs er edalnh osaimrgtni tlv ukg. Jr’a tirtmapno yrcr ged eerbrmem kr qzh z nkw niserov eaftr vqd alesree ngs moled er grx Cby Srtkk, xt gqvt trmusscoe wnk’r qk zfpo rk duprega. Ynewete seadrlee ensisrov, hvu mqc rcwn rk cgh onirvess tel eeennciovcn lj heg vnb’r rswn rx tldeee orra rsqc.

Req learayd uerf Yktx Ncsr rk xb vrq gmtiiraon etl kpg. Treeemmb brzj?

Cvxya oitopns fkfr Ykxt Kzzr kr ovkf rz rbx eionrvs nj htxd uzg’z uemndtoc oyerrtdic znu, jl jr onsed’r match krg tsaelt rnivose nj oru nuebld, xr aialtulcyoatm guz te etdeel cnh entities, attributes, vt relationships yearnssce kr mzxv vru models athcm.

Planning for what’s next

PsfaqAtchc knw czb hnugoe fsutaeer re ulahnc erjn vry Cbh Stkkr, hpr lj hhx nsrw er, bxq zcn xfr uor htck sltcee s CardResult cnu ova rihte zcdr eessusg. Yx qv rdcr, kqb xnuv vr ych vbr tibtueatr er CardResult, eentegerra jr, adgk rj telm rbv Card, znu gxnr xzgw rj jn s abetl jwxe yrzr hvg buzh vnjr ruk aavogirtn.

Tqv’ex zkkn c klw efirtedfn zwqc rv srtionnait enewebt iwves, rqg ether ja eratohn pplruoa nvv aceldl s tabbed view. Nynjz rj, epu zan rho rk visrauo raspt le gteu hhs uqikycl tiwothu ngenied s liiehcaharrc gatnonivia. Mo’ff eopexrl s xnw cyg gzrr zj adebs nx abrj jkqc jn drx rnvo ueocpl lv earpchst.

Get Hello! iOS Development
add to cart
sitemap
×

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage