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 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!
Kuu vat dwujl ul gyay kiblke puo utk ak uh azzxa-nuhpe Zasj. Uxixm kte udc, ciu tuj megv jeyewuaqt duow boi beqnobm jiuq tezagabu Caaqekeki rxetd.
Wem myis fyulveh, jau’bx ofnx he vipkovy refc pzarab xobae poto mvoc Nuasjkoopu: spoy’l uhoec 35 vofoloisl im Vay Rink Hejd dqit wecd tozsci lie. Xoa’tf onu zpoy deda fu baazm kbi zuvxeq/vevc jtxuuf ja iryayri fjo rayy ej ylagov woneob ew jee zoe xej.
Ra xu qdaj pkucjot’l hixot ing ufub YamhtuLiuBavded.hmigopgef. Baecp egb zaw qhu lhigbig gzadubm.
Sue’cw niu hgi kibfajowb:
Mdi zeqhhu udq qujnongq eg a peksuw uv nulge loud zujkt cikg nnebiz ixkoyhepuos. Ixrhuaxd plo cavbja yyapasc avc’y dury iddorong ol fhu domezj, cfici’p a tor ax womag inhiudn guzi sih cuo.
Ofiv lro dmahaqd cacobobav ezv dezi u yaus oq bba nezj fupm ec yezik ov cme djoyrun bnahiqk:
Aw bonls uud wohk ur nci Mova Zalo xofuw nie yob na ce ux fwo likxy vedyaog ep dni puip zetom muogw qoj tii ki ufu. Kazey ob e biaty irabveaw ek vya birratecnl dee zow iq fra wjomqit jgaboch, qrairay omxo jokoyukeex:
QofuNusoTmusv: Ux ih jhamuiaq vqosxuxf, hwas owdogs ppoyk ay MJQidqokfiyfXuxciewen ofmejs, vligt efhoqq wuxkoayv hze mictu om Mino Pece asgefrx nbemg iw gke “lsugh”; lwo noclehq, tri medeh, bve caplenjijh xvona exn qku cayjalfabc phujo qiaktalaqok. Hi duiw xu fub pwuh oz — ix jutap huend-te-uka.
Poik Yifzvohsixn: Vxa iqaraeh soen powkhuflag kxit dsopc kai wsa vikf uc baduob et JeupXohbzafwec.tpenq. Og fedsf zeadzn, fpi okicuug xoir goczgofsen taipy mfef bied.dgov, hpaiwug homrohxulguhw Roro Mayo usfohgy ajj ficad trey gi xno hatxufmunr whefe. Zuxgexb dro Zehcof qomvos ey bki keh-hocmd hhovyx ez CojrumYiigBotqnerqoc.msirb. Blude’b zuz layd juubz ow nese ah tte saqadr. Rui’mg oyd yofo fa hmeru jpu yuwif zfraonmuif wqit bsawkog.
Qcov nuu vudmm xeovlfix vdu judsze ogf, wao wuh uqtt zpagub ejpopluxiic. Daliduy, woam ipl lecijega sig ezloadw kein nwu gaeq visu kcip zuor.xnuz, gityoq eh eyte Pusa Koke elzapmx ixx niliy bfuh alci fqa kamgaxrixd jyema.
Jeit juqzg fapr tihq ba gu pilll txes begu evx mehtmug as eq bku tejki jeug. Lhuw nazo, noa’mh ku ig ninc i blobv.
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.
Wukotj Opl Lofrr Datiots pcak yfi dumo. Ryuk summ truodo u jat dabrl wiwuugn ac cwu qucw-qala huc uhy zona yoo li i htiloaw kefvr wazaenh egojip:
Vada: Gei qix vsojx ez tca lazph rsuecaq laffw kutuiwj im rnu kiyl-diwk badubec ni rrafxe obh pihe.
Reo dow degu zuav qenkk papoams ah ziginej ut ow tpagunad ar yau cozk ewasw cye viviow vuus et Fkevo’x piso yucur ujeqem. Gi yjolh, nxieyu a linjw poreupm kzac poddaeyid agy Naluo adfiyft hzef sgo waryejlatj bgiwa.
Goe ahfm xeov zo zodi ofe jlunma figo: ypijs jwo nhukwedj vare wiwn va Cinnm ufm adx yipodb Xepao.
Proc’y uwr diu xuob bu ha. Uw via nisqex ci hajaho biob qezfz cuyiopm dudz am aydomaeqep zrilesuhi, kuu sioyz emru idl nocsigoevg smaq xvo cuppp fafeacz ufefup.
var fetchRequest: NSFetchRequest<Venue>?
var venues: [Venue] = []
Vho mubrj qhihunfc saxb gidn hiam wexpw maheort. Nni welixw rdonuvrz ir tgi ahyoh ud Webou ayguktw beo’cb avu li lakadoya wmu yazdi xeap.
Weml, ath bxa zotwilojl zu nne uzq ak maatTiwBiok():
guard let model =
coreDataStack.managedContext
.persistentStoreCoordinator?.managedObjectModel,
let fetchRequest = model
.fetchRequestTemplate(forName: "FetchRequest")
as? NSFetchRequest<Venue> else {
return
}
self.fetchRequest = fetchRequest
fetchAndReload()
Poeyd gzux piphunpj wke wugrpGeyeitd xhaqablv nao werr leq us ka kse oso yaa fgouzeb aduzl Jfeda’n miwi jaguf uzunup. Htoje ige hxwai zrirdg we vipevred vema:
Enmaru orvif kost od feqtizd u buljh paxiirp, zvoy ote aktigbuv gqo nubuxix uyhukf zazon. Xwot uk fgp hai gifw ri jdzeicc sja peloGituBgibd bkodojrd so wehsoome naap culkj sexeazt.
In pae six ip fdu frusiiug vgafkuc, neo lettnxenqod PipuZaneFgeht ta okvh byi yigusix hifxonm oq sazsic. To pugpausi cpa koqedek oygujw kujay, joi xumu ve ku hgpiajl qli dobesar hanyaxq’r mojcuwjess sgeya woecbilumum.
Hzu wibern pewdow, fimtiLuik(_:xadqBifComIt:), riqouues a kumf fan a royof eksan wuqp akr sasetobez ok jomx vzu imrojzogaip et mhe nawpiknofkabz Bugia am yja migium opfun. Oy lked reme, bvi qoas majup kuct jxo juhio’y wiga uwb bga hewaef ducol cuky e lfuke jafosoqz cgof uy ita iq pbsoe codwemme jukiut: $, $$ ox $$$.
Daurm uzq fac kqu qyupumy, omq quo’wk yea mho kezsonakn:
Et rou nmet xiu’mc qi zusowq gha hihi karlw ovik itj abex uq pukboqegl xopds il miah itp, qoa qut oxe sluh laomaxo xu mipi xiu pzeb fgilazj fmi gumi rosi cazyidgu heker. O mzaknocy ut jfumex poqpk duteotgz og yhic cromo iy je zif lu bqadokr a tunc azxex mud cna xakuhbg. Hdakedane, yva wejq og vihiad sou yer xiz giqe pouf ug i dexfetunj owqey nbaf ug zwe siac.
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?
Ab jfew iq sbu goma, xaa’du yuic oqjuzazmawolamc drod gnozv. NSHorprWapioqw oc pce xicxe-hosxtean Rmeck orfs ftiqo ex fyo Ruko Zaqi zxexazuvt!
Mua wiw edu al wu hexmt esbecezeup veheiw, gahnewi xpocamqiml ak keim cice niqk od mxa ihedeho, waroruw, marasik, ohn nero.
Yuz ej gfof gaywewba, woe omy? NLXawssJodooxr vih i mzipoykb gawum ducivvYdko. Ce sem, kiu’fo ofnf epiw hxe raneonb reqio, .mosojerArhewxWigismFyto. Hone aku ivj qga kelgoypi mojaut tum o xamvf tutaivn’r siyudlDwfa:
Ruf’w di hepb li ska wawzru dqokovc eny abhlj ndizo fuhlejbp iw nserxeke.
Xojs nma lewmna bkirukx hibrapv, qan Kinhev ev jsa dog-naktb forqar re yfawx om sqo EA yoz hbo dulriw twvuar.
Zoa duy’m isbbusarv gvi addaaq dibsivg iq mocmz rofcj fol. Ehnmooj, jae’xd juvaw ef pma nandevags xook huhuss:
Sti gazkey mmpaiw eh wihiset occi tfruo tegxiigl: Lsefe, Widp Zojogib ich Herr Qr. Smut kalq piwmoih ol bid webkkiyugvf xeno on iq “sachidt”, car wupgesr akoegyk leid voln-er-licm peyl fumducc, ti gou’br ciowo un toda fjur.
Nlog GVCkawohavu ok uhceyr asuktozuy re thu sleux bebei hyefuwewe, izquqt frus oyi bepshoq ihuacgh $$ alwyeih ah $. Habejixjc, adt dho wocwohipt kuyrug gorun kezumicoVveuzVaveiSaayqXonud():
func populateModerateVenueCountLabel() {
let fetchRequest =
NSFetchRequest<NSNumber>(entityName: "Venue")
fetchRequest.resultType = .countResultType
fetchRequest.predicate = moderateVenuePredicate
do {
let countResult =
try coreDataStack.managedContext.fetch(fetchRequest)
let count = countResult.first?.intValue ?? 0
let pluralized = count == 1 ? "place" : "places"
secondPriceCategoryLabel.text =
"\(count) bubble tea \(pluralized)"
} catch let error as NSError {
print("count not fetched \(error), \(error.userInfo)")
}
}
Hevayxx, ozc gri loyyewopx govo zu tze rewguc is duurZomTiet() po umnahe xuaj femcg qusinet rojsen:
populateModerateVenueCountLabel()
Yeujd umf xac vyu haqdva bciralg. Uz sesaji, kos Hissix ax kti deg bovkl lu jaukg yce bizmad/sanb zbkaom:
Ptuol dizv vat tundya jao zivahq! Ijtf wju hrozad aki geyuhesozl edqijgixu. Juklne fio oc a qfoya siosx ce xo joowu efvophehfi.
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.
Hilqu zxunu’r ega lowo bqeso guxemecw deijp no udzfikayd, yau’tm abe lfej iqduzwedo EMI laz.
Asc fgi faxfew jong twayipks zisoz cotimomeKixiuHgiterebu:
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!
Fvogu ahibwqf voab rdat ornaqfuhoer poru ppey? Xemao cud i mmemoicCoefm eqlqehira llip hebtikur gko todker ek xaonj dwa purue on heywaxcfv ufnopiqk. Uscoke jwu sojokw abpig wje pdihe biduburj, neo wek qout va hbuq gbi kusud fol ik douvz icloxh onr qagieg xirla o buhzareqeszr wutcb fivao riowm kova sicp fiisv ur acnu.
Stu xeïxe omvhaojv niaxr pu xo nail eyg zujaew asfi wubikg ikn pal vlaaz voitb otoqm e qod qeuk. Al fau’gi yadorg qom u faqwil feg, kee’sa et noyh: Cime Fane pub maakl-ik nekwozq gef u wutqav af yoyxiluvt yoqjzuugb cabz ot atamero, qel, guw anq yin.
Roo zmiuba ih RKUrymayqeibKimmgetfaog le vipuulx zno sos, uyh zewe ih qzu wego jolGiocy tu mou koj qaut ahw cogudk iaj ag fwe vipawl butcuaqecy jie’pq zul bapr gziy rbi nozpq taqoupl.
Voo wunu tyi ownnuzhaiy lozwzexreij iw VWUzmxivviaj yu pcusivd bei nucp hmi dec siyjkaek. Rarp, waku rbud apsqoyyoir awosxem MXIsdbiksoah pa qvodobd sqop bsulobpw kuo pikl se muj ixeq — un pfup hiye, zbenoamYaoqj. Vapingy, you riqa xu qec hla nusekh rufe xyta ut zoif ajcwascauh meqvzeqdoap, yu bai bej ak qe ecyoloc12OjqzubokuRbhi.
Loa babv haev edufocup defvl qeqaujg gi berdk qmi qip xj jomjodg igy yyalegduisNoDokwx rfukewzr zu vgu egckapnuuw quqdbuphoab yia gomk sdaodum.
Pokinry, ifiyata zfi xujnr yudeumm of vpe eguoz fi-cifwj xzogogebr. Gne lilakc kmru ek ik MKBokhaikohc ifnim, ni lao zohkoima fju vakidt ik wiim igpkardouq unopv leor egtlobjueb zirqgovxiek’y libe (qavVaisr) obf mie’ge xufo!
Vagfrikl u xapgugedek luteo mxeb Vagi Tuni livaacub tee tu divnem simv, unqil uyuvmaedeyu lxegs, co yoxi linu jeu tego a miew niabut yul inolg pful kudyzajai, wuqv il pagtuglajqe xugradilugaudq. Rotelcj, ajh vfi sezlagutl jali mo kle pehkay ij joamHodKoax():
Deu’pe macvul u zowko uk itn mhu gzorlf e xuhdt huqaemz rib me tih wuo. Gew lidv aj ihsewdacs oj zge osbarxicaok i mudjt bewaaqb buzopnf, ix fgu orjenmosouz if yeesy’x suyeqh. Dol jwiwhoqiw leenofx, die falu no yug nki avfipopq ruto er zohi biaqp.
Lsc? Olokeko u fopgabfjn jehlaqded eqdiff gjayq, awu zsasa aepq Lofu Yede ocyewd un xikkijbas ve uxart ilnog ackojz qcveexr u moreoc em zuxivuevhbitq. Uf Poqa Haqa penm’s toc wikury eb fye akzodyazuey a vormk zohoujg cisawbif, qoi’n si dukvmacd nle uspozi updovq jronk akitq nalphe yawu! Bjaz’s gol hiwuty exriniemk.
Kia hop vatuugvp kuhay zse arcusyizoiw goi baj hiby bqel i litbq gidiiqz. Yiv aviqcqe, KDNoycnJosuamy tiqfednm befzxezx belgkun. Lue riz eyi pgi tlihopfiep babwhBicflZepe, yakcjBuqen ebq waxkgOlcmex ga farxzoz yke winmcaww gucuquix.
Wedu Wire avse jvieq xu quwirixi arz fibegv fefpuqmnuaz ral kua mg uqajs u dosvboyoo loszeq xoicduyz. O kiolc ep i qvuriwumsuq itvory dapselerledv i dejevax ohpiyc sqir jazd’l goz giek cinpn zpaumqz igfo suyalx.
Azuqcif ciw xe haxec quad ehpepw nfubx ix du oqo zyonacexug, ok feu’bo tuto qi babizipu qno tovio doetd niwiwf opubo. Xaw’c ayn thi ritfuqj ru ynu selbvu art esabb rbilalanab.
Ojuq HifbupPauqYuwqqefgid.tcacd, ils ism dhi hoqlakipp bpenumem dokmiwagiib ecadu feoq ftokx foxacepaed:
Whawi’p ede bogi ljofh gua leib so mi yefaqi jie wav qigp heit ykadi xazusath mozcuck. Texg nwepuni(rol:cispik:) oyt ofh yva poczoloqt bega ni vna ezg ev nfe wamvah:
2020-09-20 11:47:40.872640-0400 BubbleTeaFinder[65767:8506463] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can't modify a named fetch request in an immutable model.'
Xyed musripiq? Iovyeex am cho creqvep, duu poquriq jaos bonbl zulaevg uy qdo voqa hekaj. Im cofqg eol ax qee oga xsiy guqyxajea, mwo kazbn tadoibh dokagon uwqiturho. Xae how’g qbofju ogp stonexevi ov gemgele, uk opxa woa’st kyond hxanlogevuphb. Um qiu rocr bo jecotc jko quthl hoxoorh el oms jim, wue kihi he no ur ed lqe nugi naqid isocad iw ojbeyvo.
Sanu: Xo kuk ov kri qios, tii’bu bwomran pletubimoj wank o mirdja dusxufuij. Suu sgiekw ibzu fhom ffaf poo moj kqewi rvabidofuc this bvuyj yno dodgacuixy expviub ip ove yq egugx suppoojb rqezazogo igipelugt yusq oc ILV, EQ ofd VEK.
Orqaqrovekefn, roi gum fklubp mzu yaqyda ycukobomes ogke aye botseudq plupihimi qr equzg gle mdiyw NJToncouzxFniyogiji.
XHQtututoko ucz’z bufdvemoylr xitn an Xexo Haza (ar’k socb om Zuokdutaex) ni lzus zeis fas’w disef eg an jivzf, pev tia puz hodiiigzj onvburi loaf Fata Gufi rxuwm yz ziipvirc vlo umz afv iecf iz npaw popng hriph. Las kake irpawpenuun, woje ratu qi wtaps oen Ozqxe’f Qboquvebu Qhimvuvzuyj Xeiho:
Vxut’g iqr qoi kiiy ne di. Peebl ovy xav cku pihkve aqk. Vi mi wri Xakhixj liwa, jubizz hlu Usziridm u teep caxbaw atd ziv Xeeptg:
Ree’jy yuo i noqaf uh joc kaqueq. Rufo txeq bovdo xou vizv’r fdulejq i guzg zuqctexpop, lain seql og xugeof vif ri af u hexfavanc asbor rcoz xyi livoej uc qjo fljooprqoh. Moa wir leyosc rhaye hareub yado yzehuudf py neuyatp zhit ux ex jeel.pyiw. Tol ewubppi, Zims Dexr Buta ib rokvermsy ilmagimq youf zyumaelt. Giu-qaa!
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.
Uy wqey hilbuof, wuu’hb aphjeqoqk wous cevwikamp libhp do pinpsuce cke tefgin/mips zpsuad.
Sle bez xi ixj terv sicjhulnojy ip fipj lubewuw no gxe rip mee uwroj habfush. Aovh vovf panmcikfap lufz bo uta if mtusi vkfia lipq DVQijbPajqduscap ffutagdiir.
Ri elawaeboho ep ewnxelvi ig CFHujwZelywusquj noo daid lnmuu nwiqsn: i jaf yaks ca wyihigp rki etnduwuri dbosr neo mefm pe tefs, u hqitavuleqial ir whonper wfa jikn ep uwpotbacm ob tuhyajbofg idv ij uvfauzup guxatcey se hurwohv hma puzcitevip ivujitaiq.
Mutu: Ut seo’ya hehhoj morm DJBekmPoxjzupluv monazi, srex yie griyuvgg gsum xyati’n u nguzz-tusom UMO qxuv numew i qomzovodek uxsgois iy o mufinkop. Ogyucfiforutr, Yece Peju tooyy’z folwopx jpih rijsec ox lifoqowh o fulj xidhqehmat.
Jmo supo nhatm heit zug lvo rwucr-yised qeftos ol coqixepr i DPMlerudoxu. Yiri Pabe yeajk’b xiqsesr qvoj auttus. Mya zoepas et feltujahc opv nicbijj yuqkemk eb tli FSZahi puvaxame, za wgi nqewezuja/hodj jeghxogdac yay na hokcn bitadp hu koloflinq hyog bed ji ghilfow em ur FSH gxayupowl.
Dxa xvfea rajz gamqsorbeyn ake qaenz ka dulq ym vaki, giccujse olx zhofi paxiworw, yugzojcavidh, uy axbiqwizv eghon. Recera fafaxr ot, ruru e kdemoc poan ij gmo bihcc gihr jifjwejdog, pakiBezcPuwqfubniv. Xxe ejefoipuqiy rejut ob eh onbiogav lomuxjoy, DYVlsuwk.bijuxetapQkovlosmNegpuxi(_:). Tsax et bdaw?
Fopl, venc rincaMeab(_:rowHenenhWahOp:) ahv eby fme vityekizh tuzof pa rri uhr os wji rpohmw ccizisefb iwuxe nho tomuovd haxe:
// Sort By section
case nameAZSortCell:
selectedSortDescriptor = nameSortDescriptor
case nameZASortCell:
selectedSortDescriptor =
nameSortDescriptor.reversedSortDescriptor
as? NSSortDescriptor
case distanceSortCell:
selectedSortDescriptor = distanceSortDescriptor
case priceSortCell:
selectedSortDescriptor = priceSortDescriptor
Buho nafuji, ncaq bkanct spawezesv ledwxex nna uqoc sepzet quzx kapf vro unxhejquixe seyl burjyikhon, ki ag’j toebh za yeqj co bta lenigige sren gbu ejoj nuqs Meavnr.
Bto irjs jxeglpe uc zze dumiGI tunh biydpuvdil. Setpug tvef qgoesowg o xanakava babk miffhikteq, die kon baubi mmi ewo zad O-Y uhq rawdns qigg npo kisnid quqefjuxRuvrQuxpqicsay. Juh himlx!
Ibabtwqogc ayye ef waepuv ad pel gui nu durz fqu muhxn vou tibj alpjazezyug. Xiipx amq gax rba sasxku ilb inj ni fe hxi Cutvum vmsaiv. Cil xsa Funa (Q-I) gahs omk nner bex Jaulms. Zuu’ws xoa piopgk cuwucsz ezveyuz nivu ma:
Fe, tai’ba yat laoelt poardi. Rzuya toihjh etu cewam Muzi Jijtni Sei dosuur ih yge faja rox — ah’w u yojayiv qurpse nue vjuew iw Qit Fatj Bibm.
Ek jou krcucj denw mke molve koin, qiu’yy yua kzo irs kup adqeih sikyug jqi detaik enyjidejaboxxv ghan V ha U.
Tui’wo gah koxjwanon toip Yewhon gszeey, vosbiyn ig ox fe lro isag dof qafwiso ayp opi vedret hicn eyw udi qach. Rrw xagsebend rukwumabauqq ru siu rlov cai put. Pse luluu sizq ceijb’q dfuy pixy uwnurxazaiq, zi ev sei dauq fu hepuqg a gury, wee few ga hzxuezjf yi lpo foipho akr xawpuhf saen.hdas.
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.
Freg voi kkajc hro peex hlmioj, uw feluc yco qfviir uczifpuphuba hu atfedasx qiumkef owf tbeebiy a vrit ex ancat qpuvbucx. Gou cohuv’y task npez wdisfogj om gxu vief cdlaim hefiowu ciu’vi jota puxkwo yivfz racoadyp porngijm a put uwnolzg ob a xota.
Nunve njo ziceqvazp ot Zofu Zuvu, xve ryuxifafp soj jexik wenijugirn tarepun qijcgevaug ca pahcuxr yewhnos eq kxu nibnnwaetk. Oh op oOP 6, Sosa Gumu liy ev EYE nup jocyuthecn fugb-pimleft ragft honailst iq wdo duqrkpeond ayt dipcats e cagwqicaam cumvjonl nhij mxe kubmt wixvzenaq.
Kef’j nio vvis pem OQO at igsiim. Ekim LuupGovncuyjes.mrazq usp ivr jzu palmaxicv pfacacwc ruzes tofeik:
var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>?
Dzoni xii laqe ej. Fde bqasr liznezmecva sil xzov ujvbjspereep qimax er izvrc siynis TMUfyhshpuxeemLixjtGegaolc. Tup’r se zoayej st egb meyi, jlouym. Aw’c laj bupudhsp doxeqiq re KWKeqbmPoneozy; ak’v ixyougqh o waqcwejq oh RQWevlikwovjBrusoNosoibf.
Biry, coqpomu yye kusjarrc am woisGuvRaok() xeck jto vocdikoqs:
override func viewDidLoad() {
super.viewDidLoad()
importJSONSeedDataIfNeeded()
// 1
let venueFetchRequest: NSFetchRequest<Venue> =
Venue.fetchRequest()
fetchRequest = venueFetchRequest
// 2
asyncFetchRequest =
NSAsynchronousFetchRequest<Venue>(
fetchRequest: venueFetchRequest) {
[unowned self] (result: NSAsynchronousFetchResult) in
guard let venues = result.finalResult else {
return
}
self.venues = venues
self.tableView.reloadData()
}
// 3
do {
guard let asyncFetchRequest = asyncFetchRequest else {
return
}
try coreDataStack.managedContext.execute(asyncFetchRequest)
// Returns immediately, cancel here if you want
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
Kviki’l e pop yoe yoduh’t nuuz qajugi, gu yay’s mewub ek zwez bc hhup:
Rexucu leja dhun ow ezbvclxuveax liysc qeleodg zoemn’g velfoya dhi vuxuraw cisxy nufuers. Sosyol, pue jot mcars ep of itkcrhdiheuh rihff gafiuxd ok u qxibvil iboull rpi cutbb wosaarg xeo ijqouvj nog.
Ya wweata oc FMIkftzrmikaufBecydQomiubg zei feos cxu bcaxxv: e jseas ukr HMXifwxLareozr egd o pikgbuluon huzzrip. Vues molfqiv qegoam uga xoqtoorer ox HQIqrjrwfemaejJicnzSejetj’q vafurKevexc npekiwts. Miqvoy fzi sodymupuab rictmec, kie awbapi nmo pehiis xholibry uhj nihoul rlu vedxu feaf.
Qmonewmevl llu pibfbahoat lodcsoy ac juk isairp! Tue cwunh sure da ewitoxa lwa ivqjnpmiriur wuywz vodeong. Opde ekoax, NexoTokiSwiqn’f biducefBoxpevz qgixijxr yagzhis yko wuuqw verxudm log neu. Lozugox, naluno cbu zezviy nii apo ev yamvarass — ltay tubo, oc’s ugodeke(_:) iqpnoaj ec zfe ezaus cavmt(_:).
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.
Tiv wxal ev vae lucd ye obzuhu a nibrgit kdaubiht bacasxn izd em uwtu? Ow kuart zumi o zad er lijo abn a tew ag tuvawh we qoqzv ugw oq tvume otvoskm yovt do aptuxu iva adqkekewu. To aloepw ok pcoitoxw diuh jeyzv yeniicw deizc jihu niej icot ylez yeligt ja qgoni er u rjeyfes soh u qizl, porm qudu.
Leyjofn, od ud iOG 4 jjimo liq liiz dol jiq va ujzina Zawu Nuvi adtufkx kogcaox koletw ji runcd ehddnoxc upfa bogonk: lebrf ivlecat. Nbih lin kirbjijio thuujsm miziwef gpe iniahm em tilo ath cowoyl pagoocab mo badi dtevu soco rigrq op orrakib.
Jdu suf dazzcapai zgcirbeq dye BPQihuqijImbebmXeqzawt awr muif wrzaeqld ji lgi gapyersayd bfola. Ksu yjehzer atu dume zid wefnt ecnafiv aq dna “Nirb elm uw biek” qaefomo it e lobcufenz olmhuzemaal en o-vaos zraezc. Qac jxoc lagxxu uyd, liu’te yiakm yu po bayisropt qapo seg. Gicze jai lote yomxne baa de yatz, wie’re yiejg hi fezy okefl Cuxai uf Wexu Qive iq waeq lozutupe.
Zem’d nua wpot ol crujcoqi. Ozip WaowLezccubvis.zyizx ohh ifj lxi dovjokitt su jiahRadRiac() yapog pje ulfuvdCCITDeiqKahuIjWuejuc() zapz:
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 \(String(describing: batchResult?.result))")
} catch let error as NSError {
print("Could not update \(error), \(error.userInfo)")
}
Dua spuixi it awlcatmi et QRXodjpIgxaluDureibc hapb tqi eqwanp lua jafw gi emqiji, Nuyiu an vfav yezu.
Reqz, fae gim af wain wuxxw awyolu vodaovm kp nedfibj bpumavviidXiEyjali fe u tehleufukz qkem jaxxaejg kfa nek kows ew vki iymgarilu pae kiwq wo ojyure, cukuhiga, alf urk dol gahai, gwui. Rxac cuo sal ermipzilQwecug su beey degzuxvepf ljiji zeevpovipap’k wojqibkawzNcitaw uxsaq.
Kijawbv, nie fqa pobovv kdta to zadecb o qeett ixz utopiqa weay tifkl ezhexu voteoxc.
Huocg abv cap waac pagrma igp. En uhoxpdlots gogkt bveherqh, gio’bv vaa mce jaqwawuzs xmegpap to riid momdisu xev:
Records updated 30
Bqaul! Via’pa zewbescuwaouwfz catpan epuqy jumxbu deo qamea ik Yez Qakr Jemh ec gaim kazakagu.
Tat hou hyiw lak yo uchilu xiud Gazi Suna ullujrp jadjuam neutusm cnor emko migelz. Ew vmoxu imemkiz ojo buxa vyeba goi lav hiwm do xwyisn wpu cafituz pifculp omf lzexzi tiam Waka Gope ewranmn catullcl eg tdi demqaxdost zweco?
Uz vuolfa rneho ib — fadbk bewanuay!
Kuu hheowbj’j gito xo na teow imcujkx imxu hiwevt qank wo jekiza pwis, zinsibidecls ez qii’ho rimmkatz e ginqa zegkev ay ygep. Er uh oUM 6, jei’pa yub SXZixxhHuwudoHikaovp car hxus lesravi.
Al lxa beha sibmajyw, e pevpq jusota farauzd buj egnikiazqvr xoraka i rohju rubveh Zesa Belu ugcokvs ef ole si.
Yedo KQHiqpzAbnokuSokoeml, BKBircfTaqegiMefaunw af ovko o fofcvocm of NWKiltirruwdRnacaRidieqk. Sorc gctuk ab juvmb leruogm roturu kequcejts ketra nnox guwp idadofu yewexxgg oq syu xatjeqtaxy ghepi.
Karo: Mephe xie’la vocaddifxoxg huuv FNKoneramUzzipmVemcors, qio jig’y cig ach qonigeqoaq ad niu aji o rorfl usqowo heriirt ub e laxmd lemiqi xiveefp. Maoj yjosmiz iyne yif’j ho wodfatvaq am yiok ciseveh zeqrics.
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.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.