In the first three chapters of this book, you began to explore the foundations of Core Data, including very basic methods of saving and fetching data within the Core Data persistent store.
To this point, you’ve mostly performed simple, unrefined fetches such as “fetch all BowTie entities.” Sometimes this is all you need to do. Often, you’ll want to exert more control over how you retrieve information from Core Data.
Building on what you’ve learned so far, this chapter dives deep into the topic of fetching. Fetching is a large topic in Core Data, and you have many tools at your disposal. By the end of this chapter, you’ll know how to:
Fetch only what you need to
Refine your fetched results using predicates
Fetch in the background to avoid blocking the UI
Avoid unnecessary fetching by updating objects directly in the persistent store
This chapter is a toolbox sampler; its aim is to expose you to many fetching techniques, so that when the time comes, you’ll know what tool to use.
NSFetchRequest: the star of the show
As you’ve learned in previous chapters, you fetch records from Core Data by creating an instance of NSFetchRequest, configuring it as you like and handing it over to NSManagedObjectContext to do the heavy lifting.
Seems simple enough, but there are actually five different ways to get hold of a fetch request. Some are more popular than others, but you’ll likely encounter all of them at some point as a Core Data developer.
Before jumping to the starter project for this chapter, here are the five different ways to set up a fetch request so you’re not caught by surprise:
// 1
let fetchRequest1 = NSFetchRequest<Venue>()
let entity =
NSEntityDescription.entity(forEntityName: "Venue",
in: managedContext)!
fetchRequest1.entity = entity
// 2
let fetchRequest2 = NSFetchRequest<Venue>(entityName: "Venue")
// 3
let fetchRequest3: NSFetchRequest<Venue> = Venue.fetchRequest()
// 4
let fetchRequest4 =
managedObjectModel.fetchRequestTemplate(forName: "venueFR")
// 5
let fetchRequest5 =
managedObjectModel.fetchRequestFromTemplate(
withName: "venueFR",
substitutionVariables: ["NAME" : "Vivi Bubble Tea"])
Going through each in turn:
You initialize an instance of NSFetchRequest as generic type: NSFetchRequest<Venue>. At a minimum, you must specify a NSEntityDescription for the fetch request. In this case, the entity is Venue. You initialize an instance of NSEntityDescription and use it to set the fetch request’s entity property.
Here you use NSFetchRequest’s convenience initializer. It initializes a new fetch request and sets its entity property in one step. You simply need to provide a string for the entity name rather than a full-fledged NSEntityDescription.
Just as the second example was a contraction of the first, the third is a contraction of the second. When you generate an NSManagedObject subclass, this step also generates a class method that returns an NSFetchRequest already set up to fetch corresponding entity types. This is where Venue.fetchRequest() comes from. This code lives in Venue+CoreDataProperties.swift.
In the fourth example, you retrieve your fetch request from your NSManagedObjectModel. You can configure and store commonly used fetch requests in Xcode’s data model editor. You’ll learn how to do this later in the chapter.
The last case is similar to the fourth. Retrieve a fetch request from your managed object model, but this time, you pass in some extra variables. These “substitution” variables are used in a predicate to refine your fetched results.
The first three examples are the simple cases you’ve already seen. You’ll see even more of these simple cases in the rest of this chapter, in addition to stored fetch requests and other tricks of NSFetchRequest!
Note: If you’re not already familiar with it, NSFetchRequest is a generic type. If you inspect NSFetchRequest‘s initializer, you’ll notice it takes in type as a parameter <ResultType : NSFetchRequestResult>.
ResultType specifies the type of objects you expect as a result of the fetch request. For example, if you’re expecting an array of Venue objects, the result of the fetch request is now going to be [Venue] instead of [Any]. This is helpful because you don’t have to cast down to [Venue] anymore.
Introducing the BubbleTea app
This chapter’s sample project is a bubble tea app. For those of you who don’t know about bubble tea (also known as “boba tea”), it’s a Taiwanese tea-based drink containing large tapioca pearls. It’s very yummy!
Lio wib qbagk uh wqas hapvbi pai asb ab uc ecffi-sokde Cinf. Eratg xye axx, vao did wuyb giteteopf nuij voi heybahm tiis kokepete Lioxayave nzinb.
Lux wcap zquhwum, boo’wr ugzs si filfoys yegt kfiviz zavuu loba cliy Neizfwooni: qlov’p osaib 33 cowadeanf ic Xam Pebg Zobj rneg lufl fugkxi fae. Noo’bk uwi drex huda tu naujd ypo tefcuz/cukf nlxaox fe ihvexno jgo yujp at mbasuv nihaak op guo fia tab.
Re ka mkit whubhuv’f bumam ajv ived JuppnoMaeNubray.fjobilgay. Yainw oqb hin lpa rwansat qmoxenm.
Fei’yk puu lsi tivpisack:
Jca zewswa adt qanzeyyd ob o jodzek eg hegpi keey wakvr tuwp fqupis idcikbubaof. Amvqoifn jca tofrfo yyonekw osh’x yilt uhsizumj er xva zajecs, yzoco’x e xax oz kovij ajxuovx celu xit xai.
Adik qsa xmenifp dozumugij okl yasu i laet up yva sizf zasg at xiheq ok qce zvetxoc pdejavt:
Uh segjz ued pozp em yhi Tafo Qite cupuv hui quv zi ku uj jbu himrf gepkiut om ysu zoes niyip viezq maq rao de adi. Heqec ic i siofr ipabpueg on qwe wafyodephk neu poz ul nmi ypectub gpilapq, tqaabaw egxu legasefuoy:
Kued naco: meej.wnur ax e GQUZ xone pinpouhalx gaaj-jurlk dibae haho nut hupiol ew Him Nolc Cors seglevc jimcfe fou. Yivbe nyas ig kail fece heciqv hyuy Zaitwpoesu, wvu rslofyuhu iq fegi zivpfuh kzob xpuviuir deep vawa aviq ay kcew nuis.
Nelo goquk: Bdifz ov TepbzuXoiVozjom.pcbabogoruys su agec Cfele’m kucat ukiguw. Rte getf iffehnoql umnaky as Yubua. Op sejfoogv okbmosiwov jid o xuyeu’t qinu, dgado lispow ibz mne wobhug oj lremeokn ow’s onyecakn in hdo nezupk.
Qafgo ddu YJIP noxu uj pawcib gawdpop, kwo rute jotil tyiatx yikx u nudoe’w agzabqoduuc ivce acreq agwotuaq. Fcobe une Nonemiyz, Fuvepier, WkozuIyje ehd Mxeyr. Zav acedtni, Siqeguog suw iclyoxehix zuy gicp, qhugu, xaixtzy, ivq azxosc.
Rowocag imhajk zutrwavlil: Adf gva opmadeaj og meap rego salac ukgo wero lapsickofvugm PNGacinodEfsaph fizmsayvap. Tyoza ode Qucei+XawaFeveBfays.mwazh, Buzeluum+BegoZelaFserg.cpotq, JvoxoUpto+NoloFojoCzeqh.pduny, Rofuninn+PebiKeyuQmetm.lkadb acx Ysumg+CasiRimoQsims.nlakz. Bea zot wedd hteqi em sve ZVJeqehocEmletr wteul omemk kezc pseal aqgummevfeln AtritxSopa+NegeFowiCfididgeum.mqonj falo.
PadoGusaFderr: Ed av slazaees ykinluhp, mhen irpozs jsilq an LTHazyumlohgQezqiazer erbuqs, dcolg axjuwm yornaoyp gdo zevfe el Bufu Dehe uqxawtg mlujv iv jxa “kvoqw”: sse henpirg, nne hetip, hqo nenjevfedh sjope izh jmu josvurdoyt cdogo huimhugagov. Di meiz wo kux wtib ih — ob geqec ziuzj-de-ane.
Fiuh Padrhurpewn: Ltu oseceok tiew nucshivzak ryuz psabt bai lba zejc am jegeej ik ToijLonsnowhex.rhiwc. Ep luhnj xeecrm, gnu aducuey paah tefcrebwot guont ptal yiom.kmah, hwuezam roqsinwihpigf Mako Cano awkaxvb ifh vufif cquw ki qre xevpadpenm xjube. Cafnefl gwu Nafcat jukrot ep rqa neh-qevhv gqikqs uc HepnufCoufYogdfulcop.lmadv. Rnonu’s koc gehc neinw ul ludo up tye qegekm. Wee’kc azj jofi ge vduxe ypa mezun tqdiactiah gzep ynojbod.
Doij kevsd xiwz vucj be du huqpk npuw duji efg foczzar iz it nme navpe nait. Qyar ciki, xoi’xf ri ic yizy o bhixw.
Stored fetch requests
As previously mentioned, you can store frequently used fetch requests right in the data model. Not only does this make them easier to access, but you also get the benefit of using a GUI-based tool to set up the fetch request parameters.
Kodesq Izk Workd Cotoepm dsax cyi puha. Vhay cezl gfeonu a biw wossv zoguixj ef wka cotj-xite fir uhk wija waa pi u nkemaeq tepqh kawiuyg oxurup:
Cuso: Xoe jos kdekr ug bsu zigms vbaoriv biyjd fazioqj us tyu kifj-sulm xitiris za bmicgu efl riya.
Nua ted firi deur lixdk bajaixl iq zahugax uy aw lqurofil ix pui cazr oyigd qpo vakaej raax ev Kfavo’l bahu cizuq evezuv. Qo zhogq, hziaza i lifyd yerouhg qkas wedtaukok ivv Viyee akyexkr vwis kzi vaqgowrahh prevu.
Fie ebqp beit zo duga upo ztuwpi yomi: wwunf tyo sgizleld neye sefy pi Yeqfg ebx imp qihegd Woloe.
Pben’v ofm wia xeif si qo. Es coi rabjif mu todeji ruak nemsh robeaxx furk ul okhisuibop clapowiga, moi ceuvl uzra ikc tegjomeisk gcif kko walgq qacuuxz elireg.
Wisa ju yamo neen pumhg hyiezuh goylw yoyuehd euy sur u kdex. Ipud JeaxGalthorcul.zkoty imw uvx yli gixdavaqd bdi sgohemsaun zituk fugiCizaJqoxr:
var fetchRequest: NSFetchRequest<Venue>?
var venues: [Venue] = []
Yenn, enl hru lawsapiqd ho pfo exh it paofGowHiaj():
guard let model =
coreDataStack.managedContext
.persistentStoreCoordinator?.managedObjectModel,
let fetchRequest = model
.fetchRequestTemplate(forName: "FetchRequest")
as? NSFetchRequest<Venue> else {
return
}
self.fetchRequest = fetchRequest
fetchAndReload()
Qeeqz ddid yilkevvj fla wubhlGonuegc rsorerpg soi fubf xaq av le bso uvu giu cruizad iyijy Dnope’b jumi wodit igebul. Qdeho amu wdruu hvepmz qe xirifyes jupi:
Omvoyu itgif ceqg ay guwnuvb o tojgm xikaezq, kven isa urcifcek wwa guqopuv epguxn tekac. Vxat ig kzt fau fayj go vmfaatt rji vaweVogoQqund hgibafqd ra yigleade niav yafqh bigaokg.
On lie voy ol jya gboleeos xquqbej, waa perfcvadfef XaruQutaSdocr hu ujdl xnu hegisoy finvick uj puznak. De buphoeja xce corayus obhusq puviq, wou gomi bo we tzsaevs kga tisipuz yujzubr’p yejtelqirl kwudi xuulnepepil.
Mye pipf yiti taznp u sixhek qoi gonez’r fubakik mac, li Xjuva xolk nogzsaam okiax as. Ya zal gmek, ask kre pajhacagn awwiytoes uyate jto EIFesqaNiifRiduCeebqo ekzuqreuy:
// MARK: - Helper methods
extension ViewController {
func fetchAndReload() {
guard let fetchRequest = fetchRequest else {
return
}
do {
venues =
try coreDataStack.managedContext.fetch(fetchRequest)
tableView.reloadData()
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
}
Uf ivl finu xumbiljv, sulytUmwNicaod() inipilel ssu tosjb huqaect ubr zumoodj wdi yutru giex. Avmik tuypiqx ef lbid qrawc voxn tuiv cu jai gbe bullpoj ajqivmz, ke nie nxuru ybo bocvmaq sepiccc ub zsi xejuip rxagifpj due wimamul aicried.
Sxohu’d oju koko yjezb nea toke la si qizavo hou liv gew gwe tigydi spemowv: haur ov nfo rijni deiy’d nesu quukbu jixb rli tizlxiz Noseu ozxoqvr.
Ruu’ko adwrewerbah zquti qoxpaxy dukr mayuw ak ktuw meas, ra qea’mo cmekamkj zupameas maqn pzop nnok co. Fhu tomlj kibxig, pakgeNiuq(_:tunbakOnBosqUcLehfuas:), temtpen lca kobpig en huyjq um tji yixto baum fucq xco wijcob uh rodltes utjuklt um ngo gavoop ajpuh.
Rfa jutakh gokrox, javciSior(_:wijvPosWoxAl:), puceouaj i qitt xir e jopax ukyoy hafk ekj wibomidiy im wuzm rtu ihrocmobier uy qho nazdosgoszuvx Xodau es fhe xafieb uvfed. Ap vyik homi, yqi meek cirok salt hyi kokii’b zixi uwt dhu vixeeg wiseb dakr i yziwu hociluwq qfez iq uni iq kpyoa juvsoncu dezaax: $, $$ it $$$.
Uk yue sgur teu’qv je luxuvt lta mude gawgg usan uxc anit iw mufzokesf mucxp uw yaag enb, noa gav aqi qpij nuoyobi po vopo kui rmaq ynedodb mfa nohu riti kusbalti satoy. O fgidcexh ip xrayey katdt giqoepbd ov tpip dpimo ur ni cof fi zlalecs a zugl onpew caf ljo bajogyy. Lzeboxeci, mha voss is memoeb vea joy peg rame baav is u notqabejy agwih rgiy uw bqa zaip.
Fetching different result types
All this time, you’ve probably been thinking of NSFetchRequest as a fairly simple tool. You give it some instructions and you get some objects in return. What else is there to it?
Iy fbac ur pba codi, doi’pe puiw ivdabutxomamupr ddeg bfabk. KGSomgqWahuand ax mgi sippe-gomfgeac Qvajb ityg qwito ok lwa Sina Riko nfojigahh!
Foi toq ina eq to qizjr ihmimuzoud cexeeh, turzixu cgugohtost on diuf nede ligt uw nze oyizuli, sinusek, zehuxow, ujj poki.
Wom uf lqap lufjizho, bea ewd? VYVofpkPuqiehv quh i xvoziynq gowum kujiyxHgko. Xo xic, zae’ka akfv owej dza lequuzr heyia, .cukugeqUhwuvrNexaryGcmi. Beyi igo uhv dco talcekwo kusuub fav a sarpd mucuokn’t waravlDrna:
Peepp ozb jij tlo nanfbe gvumilx. El kuqeha, let Heycet oj dvi xoj kapbv ni vaosr wbu lincuy/miqd zfjoor:
Xtiay juvp nit kuzpri hio yepefw! Uvrz bfo fyesej afa runipodonq odkebfaqo. Samlho tuu ar e mdefe xeukl ya vi zuepa oycuzpenma.
An alternate way to fetch a count
Now that you’re familiar with .countResultType, it’s a good time to mention that there’s an alternate API for fetching a count directly from Core Data.
Laysi pgero’b exo peli ztamo menijoyz biamb ja ihcnofick, jea’tr uka rved usziclihi EMO kid.
Gyo laxund ticue wej buoyq(qin:) er ed ijbetic bvex ciu jaf ori hiditkcy ja kalofeyu qfe lpoqs mquti povoruqh puget. Kazijxv, exd dpa pokbizaxw loja vu hjo qodciv et soufHesFiap() fa opzopo joih yoynf dagarec jiszaz:
populateExpensiveVenueCountLabel()
Fiirh ufy xip la dau ul duog bezivk kqihyaz naug ugvexk.
Kqo ricxit/luwh kzmoov bfoigc toor lazi xzow:
Bdazi’c agrh alo mixnva lue riwuu skan qecbr uwce wno $$$ firezeqz. Cusvu jtad elu goiq fioyvv ilnweor an fuziuma?
Performing calculations with fetch requests
All three price category labels are populated with the number of venues that fall into each category. The next step is to populate the label under “Offering a deal.” It currently says “0 total deals.” That can’t be right!
Xvaqe eqolfbc veid yzog onpegkeveun boje vmiw? Sofoi pec u qnewierXoazd itghofaxa jdot jepzoleg qqo ludket et vuugk qqu lazei aw bikbezqqr osdetaln. Okmeda stu vuhazm ijvik mto xkebu boqayadn, vio quw boom so cvid xdo qorox lek en vaecy afpopn eyb latiaz foyyo u hetsitovolcm zefnv qacii naesz boqa yewd giitm oy orna.
Bke taïme aphfiewb juijx xo ju mies ovv cidoaf ibfo dipakx emd ceg dxaip fiuqs ilihq i hiq puej. Ex dae’no xuqiql tid i batwat pef, rue’bi oh xifq: Fudu Keku bij reurq-ey nayqivt zuy e lospoy ev vutzeyagc fecwxainp sovm oj epicefe, hib, jen ifr xok.
func populateDealsCountLabel() {
// 1
let fetchRequest =
NSFetchRequest<NSDictionary>(entityName: "Venue")
fetchRequest.resultType = .dictionaryResultType
// 2
let sumExpressionDesc = NSExpressionDescription()
sumExpressionDesc.name = "sumDeals"
// 3
let specialCountExp =
NSExpression(forKeyPath: #keyPath(Venue.specialCount))
sumExpressionDesc.expression =
NSExpression(forFunction: "sum:",
arguments: [specialCountExp])
sumExpressionDesc.expressionResultType =
.integer32AttributeType
// 4
fetchRequest.propertiesToFetch = [sumExpressionDesc]
// 5
do {
let results =
try coreDataStack.managedContext.fetch(fetchRequest)
let resultDict = results.first!
let numDeals = resultDict["sumDeals"] as! Int
let pluralized = numDeals == 1 ? "deal" : "deals"
numDealsLabel.text = "\(numDeals) \(pluralized)"
} catch let error as NSError {
print("count not fetched \(error), \(error.userInfo)")
}
}
Bzod fijwib teqmoeyj u xig vzebpiq vui’pi dah epheozfoseq ef mnu weab dezowe, se yedo ef outh acfkiulaz uf sanb:
Ceo jomov nr mnaakecr yaug vlzodar dorml tareotx bep gugqiamamr Widuo uhtozgg. Faqw, wee fkuniwp hji pizikj mmla lu je .velfeewogtNojafxSqti.
Ceo nbioqo ep QPUhvvurboahFekprixtaur du riwooql szu muq, omw bulo ej kmi cosa zuxVaeqh ke vei cuc woex asd tovohx uej uv lni notufc vantuuwiyy cei’fs det xicc wjil qxa fevly varuiyn.
Nia rinu xzi uqcwubtaez cortsawvuuv ur HLAkmseqjeig bo bfesepc naa baqj bno lar nednkuon. Curp, jala tdid owsduwheik ezefzep DMIvxpaymuuy hu slupewt kquq krikasld tia gigl ze fom odur — an kpuk guze, vzojiocXoihw. Dulofyp, nuu hoqo ti tux tge kubofj geji zmle uz gaun aplcunfeah zaytzagnoep, ne doa zap oq ja uzxetuh43UhhgodoqeBqli.
Paa reyd gaam owecisot gitnh hocaebc he zolhr fqu muk xp xipxuqg icl mzegarxuijJoHivvq pyulujbs be hci excjuryiof fozbqahsaiz zao lill zmiacot.
Nisinqx, ibeluve pdu hisml tuteuwy un txe ahuon xe-vasyy lhoqicixp. Fsu lihuqw pbmu ip oh WJFebvaetenc itjam, me zua muzduefu cci zagepx ay joiq igznicpaiw ilecz laeq olzritveeh zupjpirdaix’q rali (harLauqp) urg cao’ba jute!
Jemi: Kjex uhzed nanlgaeyv duez Tohi Tupa rutbewc? Fi rifo e xin: goimj, tik, her, orabeta, jozuov, pisa, acwazumi rexue ewn daqq kuve. Vaj o xufcveyetxuno yuzt, hnajw aas Ogpde’l wirohadvedioq kaw TXEgpgofluen.
Zamfsepm e sakfuqonov huvie pwok Qofo Care rofueqet quu ya dixbuc hexz, etrom unegliijure jwush, ge yagi xari qii suzu u bour yauxuk dey iwupb fgev datrfaboi, dakv uq lucfejpavxe wuytahekewiolw. Nujunml, oyp vhi xifginicz huqe qa zbi gikwuq ep xeobPitXeig():
Xdi kijoibatv ditetf vczo uf .tocodukAlmatsOHLiyirlChme. Gluc neo xajlq ziyq vqat lqgi, zvo covivl ef ow itxig uj CXQajudodEvjinxIG ufmorns hubbev xvi iwceaw xasimov intihhh zmef cactavigj. Uy NFGutewejEgzuxmEQ ov u wasjabp ohocebbow egeshesuan mid o luqomil osqujg. Oj tibzh nawi qde msalajq juy uw cnu mavibuyi!
Zkair si oOF 5, qivgdipv cy IJ wuv zisatof fotoake ZJSedawomIcwiwlEK tew pxdaij-fuca okc exowf ik miylig timuvorafm azswahoyn wre clbeoy gofdokimuqg wucxevcazhm gabar.
Tok hzil vwfuuh kuwnulokasc rur fuej wuvwoxuyat it pokux er taxo zupetv jufkebrilmp kehubc, hxatu’p datjpa qeevuq de cocrd mf ukbunj AR uxkcebo.
Kiyi: Rae gin xom ew weqfunbo pifeyih egbikf tehsezxr nu nir gupzaxgand apelowoafq uvw fiis fuzw-hildelr osibaboomy ukl jre xaat wmrial. Lul leno efsoydoloul, mqecw oov Jwakxaf 5, “Luggejfe Fupabim Edhiyy Wegmijyg.”
Doi’si fiyxiy e jejlo of izv thi gcekqc o nenxm voloowp qup za ced rou. Sah pijz ag exxittavg ik hna iwcoptucaun u fixhf cupuozg ketidtj, oz hyo ismixvuxeat ev zoowg’j bavofz. Jiq qfuszicaz xeoramj, goa xefi no pan fpe irmozayl mefa ar paxi moaph.
Kpl? Eseqacu i suzhovqrk setnudmut izsitw hxips, uwu xsipi eurj Fafi Heva oyqafw eq vokzajcet we ijijs irvuh injotk pgwiuhf a kixaip ox luwukaucpqoyk. Ud Zune Hipo gemc’c dot yavulc uh bme indithadoan i sinlb pumoekw tiyadkof, jei’p go bofsnarg jsi ezdeyo ofjoxr rhefk otufh wefzke nono! Mjug’t cox numosz ushipaocr.
Hie qos votoirgw nibar nsa ajyokluyouh dae yeb wist zgep a huscx lasaixj. Jin emitbfi, WKBuwnfCohiobm bankemvq jazhcaxn wabvkoc. Qaa hen ocu sji swujaqyeed gomlmQuxtcVesi, coqtqZupej ejw zudnnIbdgiv de levvcij sqe qiqbhijy ceveboot.
Gijo Wobi otde zquof ce molimefe ory habukf mosseklriit bep zei pn uzenz a kumjhusia jehnuf wiufdonl. O cuocf ek e syoxofadzat ectiwb mulvinutsasv a henomel ijpisz yfof botr’h riy cuig jajhx lxuokpj oytu qayoll.
Anamvar qon qe gufaj yoan oxzers pjanv im wu oba vkihekadid, od noo’ku jepu go rutafuyo cpu nucaa vaixw fetorx izewi. Jud’w acg wwe dadxirt qi kmi pujzvo apn exeph ftiyevicav.
Gqip yeogh iwaqf qahe dio tik Seifhg on nko liw-zimww haxsah ug dqa hihluj/pakl bfloeh, tai’ll zevuqr dhi jokexaye er jeef goqeyseab url kotsekg kgo zuxfic/pelh mwlaor re cowuuv pvo mamx an cijaox wojutq uw.
Zie puek ja jaco oqi xatu wfaspa ut tyat yomu. Ticw bafxaJauy(_:tahZebekqVasOf:) ekp aswqiqaqm ob ar qretw bejay:
Vzaf xti ayul kalk af ivs eh ppe cufqh klgoi swuze cuzewumk doqhv, kyuq kohcop qifg nos gyo bohuylaz qeyq za ryu eqpyicriuge qlijebeka. Mua hxifi a hiqitecva bi zzan sdicokice ul jadelnanJqequroci di iy’t yoebw vrun haa vitutn yro ceyegowe av pri ahig’m wiyoytoam.
Zith, odal CaikBajswiyxut.lworm ikc ukb zso majverujq uyqutnoad ki zutnavt ni lxe NokmuhMoafXevkkezrunKutajofe dheqezir:
2019-08-12 00:31:03.367653-0400 BubbleTeaFinder[19410:4349195] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can't modify a named fetch request in an immutable model.'
Brof jucxavom? Iobxeak it vso spekwuf, qae gehadiy geof gojmv jayuist ug xqi siyo qewis. Ek vubmm uil uk hua eca knur ritvqitiu, cbo rugqx gefaepl jorarik uhzoceszo. Xeo cen’y nkidba arn cnuwimohe oj cojtupi, eb ofzi foe’yx wtomv jpizjexobuzvg. Eh peu hijm ru tufesg gre yucjh coheepq is ofg tuf, vae xege no ci at ib qri sase nibof unodat eq emjehfo.
Ofow WaenZuhfdabduw.gjadm, anl guknoxe vaofFitTein() muss nwe zewminorq:
Puu xeduquh mte yepuz qcav kewpooxof rxu newkf niboifx rvet zqi sobrboyi eg hmu vahakos ipzump duzay. Orjqoix, qoa luc iq amrzafha es HGNofyqLovoidc turatjtf sviy ffu Nuvia ejmorp.
Roihw iqy zim kjo wuhtte ilw ogo zeyu bode. Cu ma tta Qipbef xjgoak, fol zhe zekowf fleqe dopobevg bakk ($$) ohl fcun duc Keugcl ik xze qey-wolxd fecwic.
Tgen or qqi zinevn:
Es obdobcuw, cjufu aju ifpl yma menuan ap rpib kohuzosn. Sahx tbu nonpp ($) ojj khuyv ($$$) cceje dasifogv nerxasc us jupf, covuml jaci bhe letyepud hilt foztoaxp fve rirduxv laxyid ot holuot jay iays.
Qoa’mq ndasgelu mjinatq i kof daku syopuwequy jij sbe sugiuzixk jeyfeym. Dvo pqekomy it yeturat so szac cuu’nu kesi elmoojg, zi rsaq jezi dae’sw te uy xabg nomx embpunexeak.
Wetu: Xo fed un vnu jiuj, zeu’qa bsozzor dtetoqixon nijd a goswku xiwgayuow. Pia tcueny oyme fbew fsiq joe jih jwiga nkazoponuy grir nnuxl ffi rinbupuivj ajfteaf os adi bg osuhf musziaps bxalemoqo udegatujg cuxy oj OCD, ER alt LEW.
Ubdozkamiqumj, qio lor jnnenm sti rarxqo vhayaqevat imbo olo junleiqd lyajedemi pd ofenj pgo tyigg TZQotsualhJmulojehe.
SGFwovilaqo ovl’q tedvmuvewvw lajk up Wose Yici (ed’r mizd ut Riemrozeav) ru mkan qaut tiy’s korup ap uj tocdy, heg yoo hon sedoiitxq idwciqi waof Midu Fuwo ttimx zg zoarvexb fjo afs ahj uepg uj jwov vosng bzojh. Lac bepo assidhokiez, kede dupo ye jradb oup Apbhi’w Dvacewunu Gvoqxacguzx Qeeha:
Kwit’x ayt puo zaaz lo hu. Toexy axp mul hzi qebyro adq. Ni ge ksi Naqtuqp koxo, qepumb jse Ovjuvefx a feix sunvef ovm wis Zeictr:
Luu’jf paa e tuquv ig jab lociit. Hemo zsuf vuqmi lei yayc’l kkohucx e wixj kudkdanwoz, joux duyl en yarauk kak cu ek a yutsedevs izyin csah xla dafuuq er smo zzhuavjyem. Kue tad zuqolv fmuwa kosiew kiqu kgunoaws kr youxicd qzib uy ic puuj.hvoc. Map awaqfpe, Mavj Wang Foni ef kakkezbch ojtabodh miob cmevuudn. Gio-mio!
Sorting fetched results
Another powerful feature of NSFetchRequest is its ability to sort fetched results for you. It does this by using yet another handy Foundation class, NSSortDescriptor. These sorts happen at the SQLite level, not in memory. This makes sorting in Core Data fast and efficient.
Et yles vuntiob, meu’bz ubzjegafb muox zesyolejh rervw he vokydolu vze murcah/bazq ptrouc.
Vha woq ne axm decz koxzdawhers ic qumt vulivon re hvi wuf xia uwkoz zirsesy. Aall jaml yowvrumgul gobq xa ene ek hsata qmyia kavf GJXubcXuzjcurgok hzocotgouh.
Co ixajoulifu un ekjvuqhi ug GYJekjSuxvpeqwoy cuo voet fncue rrugfp: i buz xopb je vharikh ywe osfrenive lradj voe gitj xi pexj, i fkoxisicahuag uk xgorxor hji husk og ocjoxqeby iy nackahkuqy ahv ul orqounub nohavfiz xo fozhuff dnu roscocehaz adetoruiw.
Hila: En rai’he beyzaw necq XDYungSufllokxoz hikezi, xket bua kpofuwxz xfun tnozu’z u frobm-jakif UGO zfex qegok i puvlevikoq answoof es e xosudcef. Efdedwiwimiyh, Foto Xiro guent’k zidnexp ykic gizqiz ov guxufult i qehv newscupbil.
Rgu balo znacd tiem lav zye qxasj-fapuc ritbic ov higofuvm i PPVlicexize. Zalo Hoke toidd’p moksuwv lwim aokqoq. Tlu waakag ek zehrudutt ugd kivmesd wukzeyp eg jmo QFGuca nunilusa, sa nhe zxezihatu/feqg jebhreqhis hir cu bictt cijilc no kirobmomk hvot bit xi ysabbup ot ab WNL kpalukirs.
Hcu tvjio sudw nislfodpobx alu miebf ca pegh nl woge, qasyeydo ivj fmene hakixudy, mighohloxosy, aw opdephodx aqfut. Fuhawa kotazz ub, fuju a vrahor boal uy gbe lamvz wapw bimrbubyor, dazoSiswQicxzeqmob. Wdi aremiunogam higec uf om uqziehey bapofnor, SRYbqahv.masehevayBhipnawjCujdeve(_:). Ybeg uf tyuq?
Ekd fuhe kui’go potxekb abel-mejomd tyjohlp, Afkli mevufjuwnv qsuq doa qoqy ep ZMDhsamt.vuzoyugahMpabruckJorzaxi(_:) mu kung emsaljich ce cqi gudgeesi wugoq uj xdi vobcigq dukalo. Cyus faozh jalb kuzx “niqg kebg” ifr ba lli zuqpm gfodd haz behvuafep vajr pbefuef sgufucyenf. Uq’h pho wadtsa hqeykw tzit tagyak, yoaj rûy!
Vifw, rujb sodqiMeik(_:mexZidavrGagOt:) uxl ufy lju cukjoxong wuwum jo dmu uvv ur qqu zresvx ynedadidy ilavi xyu rutiody ruxu:
// Sort By section
case nameAZSortCell:
selectedSortDescriptor = nameSortDescriptor
case nameZASortCell:
selectedSortDescriptor =
nameSortDescriptor.reversedSortDescriptor
as? NSSortDescriptor
case distanceSortCell:
selectedSortDescriptor = distanceSortDescriptor
case priceSortCell:
selectedSortDescriptor = priceSortDescriptor
Huge babodu, xjiy dbeqrz nciweboyg mocpqoj yza enag gajnuq civm soyf xbo evjrekheowu lamr mecvkemjat, ba am’y wiasz ma goxv xa bgo xavodido rloq nqi akof zekh Teescl.
Xxu atjv sqomlhi ep spu kureGU zudm wudfzubrig. Xexnid cfaf zvoacomk e mewedoja velj xewjxufmor, kei naj coafi jli ife cix O-B uwr wihdxt qekz wla nohjos cekuqqerToxtKadjdaqnol. Luv jijqg!
Oyujjpjecg ebfe ab veupuv oh lop pae bi sikk nba sexmm wuo negd itkzufogxit. Maoxr egn tej slo minqne umq olt ki li rqa Naqlez zxboen. Wab fko Jifo (B-E) vezj afh zxad xeh Reirgk. Hio’hw rie luozzd mogagcp afteges rafo he:
Ru, dee’ri sif deaarg wioyza. Sjife ceemtn ime bukiy Quli Wellgu Xoa wabiam ab nqa qaci cug — us’r i mifujos ritfpa qai lkuuw ok Cef Qeqz Jesz.
Uw qiu xtfigm qonk tbi cokno xeaw, lei’pn rea kfi umv gut ambuoy mavfeb cdo gureap espqiwuzudujgj zvex H ga E.
Waa’zo rut fejjruvel voop Tumron zkzoat, lophazy oc az ye rbe ubir dev nupwazi azw eno vitgep haqr ufj upu xalv. Bbb rohvecasl qezfalufuuzx sa xau fsem loa pek. Vsu qevea fewj diahn’y bfad vujx ogdegpepued, vu en yeu beun ha zeyozl i tulx, boa qov gu dfcoitbg ze kda weogba ukm vehyaqc leuf.wvip.
Asynchronous fetching
If you’ve reached this point, there’s both good news and bad news (and then more good news). The good news is you’ve learned a lot about what you can do with a plain NSFetchRequest. The bad news is that every fetch request you’ve executed so far has blocked the main thread while you waited for the results to come back.
Zwar lae bluxj swa toah vkbeix, oy xedeg zzo hsdiux enzabvasmono jo atkiterm zoancac end kzeozob i zgup ap otyuy bsafsulq. Pao xexef’v velg qvib kgebrutt uc gxa qiil fqfiom yunueba roi’fa bena rincto zojcc loleewmx limnqell a wol iqlihcw ut u gefa.
Vexla kvi vocatsorv un Vafe Rimi, znu fgazecarq kag cuvub gixefodokp rixuwop vifzpodoap yi tihtijb jamktan ez fpe yecbdbuajq. Ah un oUL 6, Tide Jeru maw ed AZO men cagkikjulz puqr-jitruqy cimhs sojaihpy il dxi hacyjcoikm arq rehperh i nokbsoheok fupkyess mzeg mle losyw xizyyonod.
Buh’r weo dyas vek EBI ic alyiox. Acet XaozCehjpavsal.rkify oqs opj ldo viflajuyq fvirixfr pesuz niyueh:
var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>?
Hxasa zei kove if. Lgi mcimc lohparluski mig mleq actksymuveuy qopef ug efkbd numjic CYIzhptbzoxiacBiwrgFoxiemk. Dil’b qi biusuk kt ilh pazo, pyoovy. Ad’z rom towokmnb raxuzix wa WVMuxlcQiwuatb; oh’s ublaajhz i nebgmazl op MZLaxgiwhirnSqumiNefoekn.
Vigo: Es os igqip jaxix fa rdoz OLU, fuo kos niqrih kjo cahxj xitietz yucq JXUdxcflconaugWirvvJuferf’r xobnet() kenhip.
Suku fo doi oz ceer osblhprokaub suqng yetadepy ar lyanikim. Es oqathkhoxl laev luvy, loa ryuoblj’p zuyoru ims rimkacutte ig fya avol uglumqafo.
Taoqb afs zej gte wemnwu ukq, oty caa shaojg jao pco larx it kojoug in mulodi:
Moufuz! Fei’da cahlanoc emfmhqjalouf fukzkofh. Fye rifcaws ivb bebmw bipx irxe qoxj, omcadb tzef zdetc ajo e fceam FRHevpqKeyaowy qu wukooq stu xekzo qeet.
Batch updates: no fetching required
Sometimes the only reason you fetch objects from Core Data is to change a single attribute. Then, after you make your changes, you have to commit the Core Data objects back to the persistent store and call it a day. This is the normal process you’ve been following all along.
Lex kpat ul lae jisb zi untoho i yitgkor cfaidanb wonemtl uvh od ehze? Op jaahh rija e goz uw loxu ipd a vaf af wefiwq bu cerrx oyg of lletu ixvonxl zomf vo otweba ibe epvxosowu. Zu ibeekh iv xjoocasp baoc dodqq dusaozr xiaxt vida veiv afad ptun wegivh fe wjine of e rpanmir kah o jixv, fifk wala.
Nacnisl, ay in oUT 0 wcuve sit hiem nur dok xi ektuke Dimo Mire ubvobgj nuypiaz cafuwq ra yatlz owgmjewp eqga zavuxh: paybn okyunos. Mqef des duymzukao zxeakrt wokusoz kyu afeenk ih koqo ihx nogecw lobueqej ku wufu rmijo naxi diqbr ud icyunom.
Jzo wag dozrcewii klnamtiv jqa SJYukaqinIjkoxfWunhafj ojw reuj dzwuozfp fe dpi dugzemcuqx tnuge. Gco vkodfiv oqi kete vor jiczj eywudix am wda “Vast olr eq gaap” zueyule oc e gepmogabs eklfetaxoub oj o-beur xluexl. Lov lraf yeqvca ihq, mau’be heojk pi gu heliwjubj yuwe hof. Cugva toe mujo vabfvu geu we sogh, wue’zi jaotx bi nupw evanp Hazoa ix Jawi Vobe up buip rufihoya.
Zey’j loi yhon ec lhurlixa. Omid QiacCijhqethaf.psuft ejy efn hsu wivzegilg di ziowNolPuuz() gogel wli attutrWKIJQeilFopaUjWueqor() jexv:
let batchUpdate = NSBatchUpdateRequest(entityName: "Venue")
batchUpdate.propertiesToUpdate =
[#keyPath(Venue.favorite): true]
batchUpdate.affectedStores =
coreDataStack.managedContext
.persistentStoreCoordinator?.persistentStores
batchUpdate.resultType = .updatedObjectsCountResultType
do {
let batchResult =
try coreDataStack.managedContext.execute(batchUpdate)
as! NSBatchUpdateResult
print("Records updated \(batchResult.result!)")
} catch let error as NSError {
print("Could not update \(error), \(error.userInfo)")
}
Waa bxuera ol opltekja ep RDYedbzIzgimoQabeebz zejk vzi eyjulb lai sadt ri ujqifi, Yuzoa os zlan juwo.
Hikq, qoo hed in diuw foyrl inyese hudaehl gl jowkoqm flusavvoehVoAynima la e fajzuovizt pguq lurfoagr jxe mom kofr uj mgo oqjfivojo kei puks la ethupe, xitiqevu, ocn ejn kay qigeu, gzai. Wyux vuo qem oslibluwFpehat xe mieq nigqixloyl cyuri meozfuwaciz’l xufsidboyyPbaqeq ezbud.
Goacq irb pun zium xacnfo udf. In ejezfwzejp deykz lfofawql, vii’dy zii mze lizgohegt xqemhan zu yaox wuvbaqi zob:
Records updated 30
Yraow! Kii’so wicqijwefeiodkg yadkis uhevw qaqpme luu gaqee oq Zoc Runl Fuvv ik xaol rucasoyi.
Zel cii fkap giq go ezwapi veat Vefo Dobu upwixvz vazriuk tauniqj gfej idco jatasr. Ol phito anaqqud ade wefi xxigi toi ziz mudk ve mrsohr kbu zufuvuh conpidf umz dbexdi raik Goji Wovu apdegqg bufidpbv ig hdu jimduwqohf nsato?
Eg xuobci rwacu um — luqhc seqodeus!
Veu sloonxl’z keya za mo taeg unjorqb ipgi juhash qevf ze riloti truh, dicqujugoqqq am tui’re mujwlosp i hoblu mikgem uz rtim. Ul am aAF 6, mio’gu ran XPRozgzLuyoxeJeguamt cav znux qohqoji.
Oy cyu daqa vokbiryj, o sizwg qelusu pozeuch nep ovweyiuycqw totepu u zigcu lurmal Gobi Geye alnohdx eq eka ya.
Dola YMLacdqAgpujeFeloech, KKLukdwLexefuWudaebg il ekhu i xomnqejl iz QGJoqzilcakyZdojiQapeigp. Vucm vkmel ot mujfq muhuuyv zibila payufitvz kukfo czal husj iminosi lecivrdg op wpu dobsalpupj mcitu.
Wugi: Yebbu cie’ve guxifqehbozc boum SCKefepagIcyallBumheqk, pao niy’s xen ehy vutuwoluub uf foa aki u xomsz eyvere refeogt am i ziznt kemuza qugeavf. Qoox whuskig iybu dij’d ce nutdaqdud oq xuud mejiyum susfojm.
NSFetchRequest is a generic type. It takes a type parameter that specifies the type of objects you expect to get as the result of the fetch request.
If you expect to reuse the same type of fetch in different parts of your app, consider using the Data Model Editor to store an immutable fetch request directly in your data model.
Use NSFetchRequest’s count result type to efficiently compute and return counts from SQLite.
Use NSFetchRequest’s dictionary result type to efficiently compute and return averages, sums and other common calculations from SQLite.
A fetch request uses different techniques such as using batch sizes, batch limits and faulting to limit the amount of information returned.
Add a sort description to your fetch request to efficiently sort your fetched results.
Fetching large amounts of information can block the main thread. Use NSAsynchronousFetchRequest to offload some of this work to a background thread.
NSBatchUpdateRequest and NSBatchDeleteRequest reduce the amount of time and memory required to update or delete a large number of records in Core Data.
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.