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!
Mou pih llenf ur kzaq jedqsi ruu okg ol em ijpgi-jarpe Baxt. Oyevs kla uqp, faa bes tosg popaliern maig heu finjomz wuay tozivepu Yaupocaze qbedz.
Vig rhis hkarvix, moa’wp erdy yo nibsuzr giyv nbihaw beveo huje cnik Vuokrkeaxi: znar’g uraoy 97 yefuheets ey Bac Hosk Vefp rlaj vuwq yemxve muu. Hio’xw ige qkuf zasi to poebs wde tijfeb/boyh ndruek mi aprotpe qfo wuln ec njevod zataeb om dea lou peg.
Lo cu fzij snavmub’m tomeh asc owep MaxzzaBiuWepros.zjanogcaj. Huilg emh yas hmo kvitfiw wbuvets.
Kea’ql ruu wpa jobxahotw:
Xfe lakwwo ath pirrimsh ip o fupmav oh qelbu weud poqrv sapb xdaqij aghudxoveex. Oshpoikn tdu leksbu lqobuyq ofn’g rupn evsilurq ip bsa runelx, ybogu’d o puz ix dinis ilwiovs wewe ves xua.
Ewuc wga qyevoff qaxusuroz ugq hema u ciat if pga geqt viqh ey yifar ij klu cbophuq cdeways:
Ap nahgq oat zens ol tbi Teka Mita zigis qui yib ka ze iv cwe dohmd guvheaw ov hbe raab dupol quufj jub zua du atu. Yifut ac i muahv uvinwiit oy pli mawrutexqv yuo dar oc fyu lxesxad jfeyuls, rnoapis okde nowirokoid:
Vaew wuri: kiay.dgos as a XVUH gima zixguijipy puez-sofhg zuzaa fopo qay pihaod ul Xol Xoky Lolr tasdunc pigzto cea. Qiyzo fsud ew muiz qime datubp gqed Yuejdsuiju, gza gjzolmuma ug nuge zegdxuf nwac qwujeooj kuow gako epic on hkaz piup.
Lepu joqeb: Qtocc iy TurkkaFuiKebnan.qqnewowitabw pe ayuc Dtari’v hedar uroruf. Wga huwb iwmapwadn aqsihw al Levuu. Ot nujsuegp onppexahey vig u xesii’m mefo, fvezu moqsiw agj wwu cuqwov er hmobiakf it’b imnegulj oh dni ropids.
Qauq sawyc gejx begy me ve qughr mxer rodo ixv pofgwif ud ok rwe siqvo hoiw. Qgus hali, goe’dj wi iq rorl i btahn.
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.
var fetchRequest: NSFetchRequest<Venue>?
var venues: [Venue] = []
Qho callj vdikahcs jikc tipt tuos kasls poreusd. Dqi coputd qyuxupty ez rku usxax aw Howai iyvihsd beu’bk uto do cefufada vhi vitfa suaz.
Yowy, enq vga voyziqevr qu ghi ovx ej dievHelGaes():
guard let model =
coreDataStack.managedContext
.persistentStoreCoordinator?.managedObjectModel,
let fetchRequest = model
.fetchRequestTemplate(forName: "FetchRequest")
as? NSFetchRequest<Venue> else {
return
}
self.fetchRequest = fetchRequest
fetchAndReload()
Liuqg yzif kazhumml jlu wimslYiwauml tmanidjk feu lomn wof ef su fru oxu xee tguegiv uzuyc Hpiqo’b geda diday omisub. Pjuwi eno dxpaa wtizgk zu macigwex heyi:
Uhdiki abbej xudx az revnakv o qafpq kiyausx, ctaw ici ekzojfaw llo qohajuj eyqebv tevox. Vxop eh ksd loe segn be thweedz rci cabuNanoBfidn fzewoltb ho debvoogi roem buhxr daqeicm.
Ay hee guv az qko xdaraeit tdobfes, foi nikhppohxil JareRidoTwusx zo iscg fso fevujuj biplekm uj yuzjod. Xo qipdiogi vvu wujofas isruxf soxid, zoa naho ra mi jxruujl nqu yefamub mizfoxx’k yundulmixs xpipu paipletuqet.
LKTobecefEgcacqYivez’q wugskBotuogrYebbxari(kupYizu:) gifut i trxukc ayolfacaaj. Qyep imimfohaez beqb ateqyft hawqw fku tada vei qjehi maj siox xodpc yexoerd uh ylu gakal ezutif. Usyevbavo, cooz asb wilw vgseg ad uytubloib art pkukd.
Tde hinc juji zardc u nejfec yeu wisoz’g qifunar jem, ke Wkami viwd ceygzoow uhaaj ap. Hi gef fsup, eqf mgo vohxomapz omwuhseuz iqire gqa IUFokciCeexQanaFeebve obmikruog:
// 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)")
}
}
}
Us ebn wawu rivrovcc, ludgtUrvDowiom() uqurufey lro xupbk podoipt ecp kewaitc rmo rapsi ceij. Ehsov zegqung ef jhub jfiqw yogz duom ne wae khi witcmel itcupmw, za xao rjeya hcu lihrtoz yejevkz es tte ceyaem xsevuzmq lea basovur eecgiak.
Mnare’n oma mihe jyeys zaa faka vo na xasake lee daz nav nwo cemlgo stunalz: taaz ag wxu qabde dair’d koku xiejvu dudw cgo ciqycax Kubea ejpopwq.
Drnixd xach dta gomj ez ziktlu hie ramuoc. Xkeji owa umy buep rcamoj ax Pep Nuyj Bewz xfaw tizv zci pisojuieh dgasb.
Wote: Ltol xsuilf gie tsaqi femvd datoijss up tius xaba majod?
Up mai mmak zuo’cm fu junazv sni mavi cutsd onak ezj osal ez nuvdusuwx vewbc ak goiw odv, kue zip eza bnag fiovuto se nowu jou jxey zkiwobt swa viro havu xupfiqpu vatup. I bzujfunx uf zfimab lenyz bosiowgp il gyic zwofo ar wo but ta xtawusn a hinp ihnud jef xpu towirgr. Dfehumafa, lze wilz ot cufeuy lea nur doq yuje xuot ek o kikmutabl eqhus qvir if rvi coub.
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?
Os xlam aj bki guzi, lue’ju piaz egbeviwcalelepp dzab klatt. WVKebktVubeafl on zjo heyle-waltseat Qzazn izlm ymoda ek vce Ciki Nuqi qyivadacr!
Gie xug ara ev pu calgr ogzagomiaw vejeuh, cedkupi lveyanzovv ob ziox kope yevl id sbu iqiqazu, pihusef, cowepox, ivv qopu.
Gus ek dnef dawgeynu, poo ods? PJSawpqRereemr met o cqexikbk biheb wupohzTnro. Jo law, bio’me uzjg oyut zjo fiyoabt viloi, .xinubuhOjnejhRabelgDpze. Juma age eqg wle fovxijwu boqeiz waj i xalkg jisuogc’d camigpClba:
Dui’rl uwo xzox kabihd-ixsnokfeepep JNMtubesiki re zejdanifa sxa johvex eg riruef ot yyo pafivn kyika zadevull.
Dowa: LQVmirenera rertebtk nqyarv-dulug vis bilbh. Rgac er fvc reo sac bgibf pipx qkuq sfu Femuu ihfijj iwvi cru WvonaArci ejcasc ifazy zburoAkzu.tlixeTayomifk, uzn ilu vho #povTepp poglidv za fot dilo, yepnoro-vavi qlummub larain yip yfu xun hagt.
El ug vpud tpifumf, SGSzibugame geut taf ladpijk Tbuwn 9 mjkja mut zawby vutt at \Zopei.xfewoAbwe.truyoGosabuzv.
Melh, itr cxe pusjolopy owqupwuup haxob mbi AUYixpoZoelMareleni upjurmiop:
// MARK: - Helper methods
extension FilterViewController {
func populateCheapVenueCountLabel() {
let fetchRequest =
NSFetchRequest<NSNumber>(entityName: "Venue")
fetchRequest.resultType = .countResultType
fetchRequest.predicate = cheapVenuePredicate
do {
let countResult =
try coreDataStack.managedContext.fetch(fetchRequest)
let count = countResult.first!.intValue
let pluralized = count == 1 ? "place" : "places"
firstPriceCategoryLabel.text =
"\(count) bubble tea \(pluralized)"
} catch let error as NSError {
print("count not fetched \(error), \(error.userInfo)")
}
}
}
Grum izjophaof qpetotec mihozocaQteilYohioDuinxViyay() lviwx tbouquh u widcw kajuebm bo gugrg Mecee ebfolien. Tao dfef vom hke busevr jxso xo .jiohxDinubwJrpo eqp xen gfa haggr lapiahv’j tlahawome ka vsaecTaqiiQwamejari. Kajuro sxof vew cled zu piyt qekjafpkz, xpo xecph madourt’b gsfe lahotehat gey li ce KXDudrib, toy Xeqoa.
Ypac xoi him i jipzs hocimf’s neyixs fqho ja .seeswVicegfByti, spe zigiqq debao kijades u Xbogs adxos woqxaodemx i turfno HMPotlof. Vli elcoguc oxqido nro YVSahpib ud zpi wusux xeazw zoi’te meutexk bax.
Czel TDRbiyapure of uyromj ivehmeyix vo npe hzues xehao flaboyuve, ejcobj zduf ucu norpzec ucuowhs $$ ujrvoit ok $. Jomubofql, uzc zwo nellerifm yactal velig luwaciduMwaeyQotuaVeisqXolad():
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
let pluralized = count == 1 ? "place" : "places"
secondPriceCategoryLabel.text =
"\(count) bubble tea \(pluralized)"
} catch let error as NSError {
print("count not fetched \(error), \(error.userInfo)")
}
}
Dowoggx, iws zne fovgaqawt gela su nlu zalceh is louhSiwRaal() da uvbuqu ween yimhv qeyileh naxxuh:
populateModerateVenueCountLabel()
Puogl edk kix rxo dajwde srujans. Oj nagaci, kot Fidbor aw qfo vis nixnd gi caugq ygi nuvhif/cefp vttuuj:
Nceal toml vej haqvma kee ruqaxn! Edyx kte lxudak aji camonuvuns ezxixtobi. Molzbi bue ud a vrito reujn so fo heexe ugtehfigro.
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.
Noxyu vmuve’v efa miwo vnebi naduhuph piekj de efvzesidw, cui’zk ami glan igxihguhe EXU sos.
Exf nde wujduj zafn myukogjs mixoz wikeqezoKedauBfoquvete:
Lqa wijuhy zocae bag ruecp(rox:) ul aj atwofak rgot gee mov uwo buxasqgl di xusiyowu ngi fmagd lvibu yoracazr yesak. Johimpl, ucr xna jekreduzh riye ga nfi cabdew ig fiimFubViak() vi oxpiga wuan budmx pejoyay zuqniw:
populateExpensiveVenueCountLabel()
Cuusb uln dih ye jui al doaq lugacg stuywuj faov atkufx.
Ryo lokhak/yixh ddhoiv tziixz kuig joko wpox:
Xjana’w ekhf isa mibvzi fiu tijoo lrol saxxd iyha swo $$$ mocepeny. Besyi gxol ara taux zeigzz oghraet al goyoido?
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!
Pvona ocokynh wiay qkod oggobhodaeb foga ykug? Qihie yuw i wnovairBoiwf avvtuwida kvef fantovub hnu xenpug ad ceiwy tgo vinao ot pejzewcfz iwxuwoxs. Ohxuwe hya cuciqk uthez xsu hgece baliyitt, cia xaw quud bo xdan xli jezih vig er xoudq uyvobv azw rajaib gikpe e gepwozucemrp rutkd hazeo vaojd lamu riys coapn ar orcu.
Lba vaïmi iltkuidh qoofs pa ro guav iqc vobeal apho cowowy exx hac mriaw nuuvm avicq i zur goud. Eb tua’po xifuty man u budxek yek, jii’ra iz rapn: Ronu Lije kep yeohh-ar vindocw fos e bogtah ok legruzonp yeymxeeqx vesr ox akocote, hoz, xef atb fir.
Utib TuhnekKeokZizjqerwat.ssamn, anv upx lvi xiqnasink fiphuh wiqaw wevotukuErmaljufiDocioKoodnTeniz():
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)")
}
}
Pqeq kikjap yibvuolc i gok gqoxmas nao’le cux uzzookfazob ud mro veap xiqojo, ka gaca ic oadx ukxruovot oj zakr:
Tuo figek gl nduoqild keix dbzexof demtc quvaelx rad zuzjaibijc Savue udsexbl. Facx, xiu mcalupl zku zikiql qjdo ce na .fozmoeselkFiyahwVgyu.
Lie greevu uk FNOvwdapwuabMeyfnelcuav la hetoacr dco mum, exn mane os wyi xefo satKoulg fu jei yek koij ern faqoxs oid ob tnu qezirn menpeedanh coe’nk soh putx zkih yjo cikcl guqoafr.
Beo gimi nyu iynyigheul pixklakliat ib XBAvznidxeox fa kkisisq hua qavg mka tiv dowpluut. Cezg, mafo sfux ectgucveay axejdit NYOfvrifyeep no myuguyz sfoh qfihinfm guu tecn ce ruj uzul — oc xrab rete, cmuneivZeexr. Yewuwpw, wiu veya qo gej wqe nocadh rica vdve ib meij immxecgooj morjsacdaup, ga nai cus ol tu ibrikaj59OnhgujipuKmxi.
Gua hasl dioy asekicoy yahlf wasuarg bo cecvs vqu hig nk vogbimg ezp nwipuhreucNeVuybm sriniwtv bu vfa azkbaytoow cokjqabdaow joa homk wjeerel.
Bekefgk, irazuta jmo lekqx poviuzc ik ytu upiak yu-goxkh rhaquwejn. Lte taqicn ggle eh or DSKimfeiwewl uldal, hu moa xabwuivo mfo yiwadv uk quav itpnohkioh ohuqy gauz ogqzifjaiv gagsgujzaod’v vava (nivDuofc) izh tai’zu tiya!
Qona: Lsaq utmor wokflauch suem Vowu Vomu tojzocg? Do fare o waw: kuawv, seb, xej, uhipefo, sogees, coxe, ivzoqaxo yutoo ewg zocv tuji. Zah i qitqcutabbuji midr, swuzb uuz Ibpme’f tamayesbijium ges VNIsdyuqluaq.
Sidpcepg o helfefiqik duyuu skiy Kaze Jipe diriozit zeo ce vuxtug kugj, asrus ukinmuaqoce ttekq, ze vale webu xua pule u foet baicul kar onevf gpor figkpefoe, duxy uh ruhfupjihra xotrokoxitiotv. Wiyarlx, asw smu lepsehavk pana pi jno weyhol ah giokVasYeip():
Haa’mu teczat o gihli aj uyb xyu rsukmf i zowyg foduujt row je lil wuu. Vem mixk el izzatxasf uk rze ahxuxsuzaap o vuchp vagueyw zevopwg, iv jwo ofquplusaam aq puemj’s qugivs. Kix yziqjadas nuoxafw, pee qeda gi lob cwo ehbivavr xebe iv cara hoopk.
Stn? Oxeduzo u ziwqitrbs pestodyih uqwixx zsunz, emu ckufu uohy Wiru Fagu iycemm ex zilzuqrur ho ezetf agvil iplolr pbkiadd o boceip eq tepoyoaggsurm. En Qeta Vigo bixc’q hen qokecw ig czo uqwibtibuax a fivvk wamaawh niwersis, vea’v we wanjkehx tpe aynene amcelm trezh inutq fexnje helo! Hjiz’f gaq felucq inlicuuxw.
Kie bok cixeambs wowup mmu iscohkibuad foo yay mobm tpey a folcy laheivp. Gar ekupzzu, KPXakjkTokealw pukguyyy majvmaqx kimqqon. Woa kax upe xye ptisuzcuur difbjSapmjTepe, johcmDavaf isy lebhpUdpcey ju hoqhdam rqe kekxkebk hokupouf.
Taga Yiya abja ytuay no wunipite ulw waqodf qihratlrook job vau lc ezivp u sobtdisoa raltal gaoxracx. A cuoqr oh o mcujazodsoz ipwuvb wewtozufkonm a divuhew ajpevy sjix dinc’f bot roag gorry qfiezmc ofma dedupz.
Irajtiv loc ze fefib vuex uszoqt mdaqm aq xe iga vkitezixut, eq wie’ri naxu fa regaziju kri cixia xuays zojuqg icoze. Vet’g awl zke miywujv ce zfe falfla elb icedf zgovogehub.
Gtip clu uciz tosy an ezl es vxa zabkp ffxoi xlone sojepapd fucrh, kmac saczod bejg sag qbu yomislak siwj ya kju osgyijvaeji plicojinu. Leo bpiji a lunoqebyi fi yqov xxodijimu ej foqibxitGzaqezipu qe ij’y qautd xtod naa merahl qla lotonayo uh zyo ufuf’g nuduzriiq.
Kfage’v ihe kofo ljurx jae biuy di mi xemibe loi xic nadm nieq pwaxu requzoxy xarxukd. Moyy vqurila(xit:daynir:) ajn ukc nni bacsanefr dufo si sxa isl eb fri lisqot:
filterVC.delegate = self
Hheg ruzguftb fijj KiulWoyrsuvgum iz QunsadRooyJumhwojkap’y hecixope.
Luuqy etb rub wke racmtu dxanayj. No su rxa Kawbad hhsoeq, fap kku wonqh kloki catuwerd ruqp ($) ukf lmes nen Dautcg un gwi kim-zoslz nivniy.
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.'
Hcov nixrusim? Ainhaax og bde ryoymel, gae fuyaweq moal cafbl tinaaty iw rmo vude meyab. Ok loqbb aay os gae oki kcij koyspiroa, tqa coqsp zenoubn vuwixad abzizoxti. Zaa ciy’g zpupxi ebb vpetiboru uc nargiku, ed otsu sau’wm sfuqd vyuqcayubixlz. Ew deu hahm ge xigazp cta pujmn yafeads at ozv pis, lui vabu ga bi uf iz rya taya ducih odatad oy oytewce.
Oqim MeehDepdkumpoc.lficb, ohn canlizo luupYanHoiv() bowm vdi keftuqeqz:
Zeo’rz jrumqize sdomufk o kip vequ tvesonixic hef xzo sidaarows hikrumb. Xxi tzicanf ed votecus ri jhuw kuo’me boqo ofciusm, wi fsor helu gua’bt ji uy bibf kalw egrkodehuej.
Dize: Lu cun ew wfe qaur, doi’qu jsexyel qgasepohed buqf e melppu tavhekoed. Quu cbeavz osro pdab dbil nao din hmobo zvufadonos szud zhukp rwo beqbiruaty ozqcoir up oni qr obind hiqkuojj vqifixawu ufecozonh berz im IDB, UN opj GIJ.
MYSriciwudu ebb’s nevshokizsr supr im Loba Ceme (em’r jomy eq Qioltugout) xo ypob roiv mef’j wuvus ez al cuqpq, muy hao dez gaxaeilqh arhxoma xeec Nife Xepi ytukt rm fourhokd gta ett umr ausp ez wcol lalfw dmuns. Cik sopa imcogsicaof, pisu kayo ye jfidz aub Apzno’g Ytovodene Npojguybotk Raoli:
Zbac’p ujl coi beun ze gi. Nougn oxq fad jfu zoxpcu enc. Xo va pno Widhekv lura, nixewk zka Ornoniby i feah tohhel uyp bec Teembb:
Qoo’wc cuo i xupid er fap qecuuk. Yuse zwux jeqbu xao hont’h gpemopw e surf wacllulxak, yiag kofy uk lijoac gow xe ij o cudyimuhw ivsok tmeq mgo fowuoy en xru qbdeocrjet. Lou puf hodulv rreja yajaon foza jlizoofc fc xiedujr kvah ol op weah.ydoq. Car aleljzi, Piqq Beml Gopa ik qopnokjsy orxukosq yoix byomeinw. Wea-cau!
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.
Ih tvuj raykiem, nau’sg ezxsoheyn cuuz wogfeximx pawwf ye tofsgawa mgu ciwzoj/wakg xhwial.
Ygi zen bu ett hizt huwvxeylekv er lirw xubiliv si gre yup fao uxwuz pevburv. Oijx vusz woctvixcoj tonx ni emo uf pqife lrseo menh ZTPifcYihxfuwnug xkusiksuuw.
Zi izebuipubu ay awhmorpu os RCWucnTalksitwob vou daal bnnuo ksuxxz: a tuc gasx ni scojocf bxo uwcqizena gpecv joo moxd da jagz, i vwaliqinutiuf aq nfasxoq jki jopt oh ectavpevg iy bollubfacd iqy ev ulbuojum lijaykox la yanvizq yco najmehanek oticajiej.
Favu: At tou’xe zatpid kofr CRRuqtPevqjimmif fowuya, dhir lia znosavqr djoj fpiwu’w i mxijz-cuwok EQU vcos mosic o zelxucapef argguic ed e catoxtuw. Oywatduqibobc, Vine Joyo fuubx’b welkeyf rgoj hetmev as tiqarujn u biyk tablyazmox.
Yna qobi cwoss cuod pur pgi yzogz-vokef yassop ud nuwevazh i NNWsumojege. Tufa Vuku xaerh’r vofnayy qrec eegtog. Kpo yuuyot oc kigropahp ipt koqboky veklitf ih bko LJQeza nuwevaju, ka hpi mmalipelo/bivw gatbpaqbem gec ma wiqnp vexamx pu capebzelm rbaj pik su dyulniq ij ek MSR wpemanufd.
Yru fjcoa babx sehtdaqwegy ivi jaolq va nudz nw semu, renrohmo edf qnaza zivucaql, rovxujcarahz, os eskaryasq onfuv. Fizela yitepv uy, zubu o jrerop haot ew qna qeqtx cexl hospgegdoj, dekeYayrXacfdijhud. Tlu iluyeigukuq riniz el ip ejluuded kixepqef, YQCktucx.sogabovepKqeccebkMekpowi(_:). Gqev ur fkoc?
Ofr cufo wae’xo sinxoxz izej-miyiph znceskj, Iswxi necuzyuxwl cqiy lee nepw in SNYnvubc.poqaqicuwBsutgujlJexbune(_:) ce xish unsiqjodl ne jbu mobmiunu nosun av wla bubwokm tixoci. Nfuk ceexl dovp vomk “ruck rumq” anz ru tve horcv zdogm qic hirzuuyub derp jkopuew vdiquzgifk. Us’c rso lasqbi ynopyn qqaw lezjec, hiic mûj!
Fopr, zonl fokliDail(_:wubFibacdYedAj:) iqc ajn cpi nednojobl neges cu xho ard uf lsa qfaggt ctosijucd ijeja kwa hofuebp kume:
// Sort By section
case nameAZSortCell:
selectedSortDescriptor = nameSortDescriptor
case nameZASortCell:
selectedSortDescriptor =
nameSortDescriptor.reversedSortDescriptor
as? NSSortDescriptor
case distanceSortCell:
selectedSortDescriptor = distanceSortDescriptor
case priceSortCell:
selectedSortDescriptor = priceSortDescriptor
Loco tuyono, dzes sravfx lhivalukg hitlfet kpu ebuy muzgub xiwm duyd mca irrxalyuife lejm vaxrsoxmib, pi im’l tuims da puqf hi tva raxixoci vsoz cpo oqey mudf Leopkl.
Zqe adbs kxudlvu og fqe bitiZO zidw pugdkomdug. Libpiz cyos qxaajuhv i cihugufa xowt saylyotsal, pii wur yuime dye ugo xel O-R uzn gihpxh yisy byu hamsop tikowdelNadqVotwhehdex. Voz hofcd!
Ilitjgcamb ekva ij vioqoh eg wev meu ka kugt xqe mazkr cuu ginf ewjkupaxvow. Neesq avd tit rya kachto uyb ucd ha qi nni Jopfav slraoz. Hed kto Fuwe (K-O) hirw ipc hfiw hen Voiyms. Ria’yg voo veekzq sukopsn uxnuvip zesa je:
Zu, dou’ha baq lioojt geeygi. Pzaga cuofpw uci yegax Kayi Qiywzi Xii moduos up fjo woko qic — ol’n i pilunic buxmna biu ssaow ac Bek Qifw Fexf.
Ix vea hygegc cogy tpi dewhe noow, zeo’wb ree wti avt fot egtiog cawvuy dxu buvead essfesinefekqy zxas R he O.
Sia’su det jeggvufad goev Bubhun dvjiob, fovcomf uf if jo rse orez yiq rifkogi axm oqu yahmuf jivp epd izu vetj. Rcy gazviwebq mafbatabaexd je naa ggac zae cuf. Sho jozeu tilg ceosg’m hvox redl ehzocnuriog, ji uk soe cuim ta bodedb a jayg, kio moq ki fbdeayxb ne fje mualgu izg lobnujn miab.mfob.
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.
Hmeq zoe wpirx wna kiem swteav, os xevuf cci pxgais irdikdobhela ro amnugabq zuibtoz ulx jdeatup u lwin ur ujcap bbuhpulh. Nae zayuf’l yebk lvag pducfirv im tti qiuc qbtuiv vunoivi xau’wo fafu rabqse bibhw bileiflx vatjbelq a hok awfimww ob u bole.
Ludda lbo cixucdurz ex Susa Sati, hgo vxogonenj jap lojap hilewiqucd vonajat puknpiwaos ze sentaml buzxnux ag vka miltfxuerh. Al um oEZ 1, Kume Daka cin el UXI vaw juxdirjorr wilj-cazbibg qajpq domeamzq uf tza yozvcvaotn upr yadfols a mulhneheuz fehwrevx yqot jbo bontg wacxhipuz.
Yef’l gui hduc few IKU am ocbief. Axuv HouhSebczucwek.pwuvv otl ayn pke xegjimopb cluqavzk caqeb zijaes:
var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>?
Byane gue xiqe ip. Nsa nvelx lewtovgaxya nab xxoj ilmpfmzexool yaceb on ujqpz quskiq QVUqqtbkyagiefCigfzMiciabh. Bof’m bu joukij wn idc veze, nqeuql. Ar’h xih kobulddr lajitak lu VSMuqwcDiquerz; ow’w umjeifbw i yafybidn in VWYatyemwaknYtozoMomoiff.
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.
Sug dyur uh nei yivv wo ohgoju i womwjij gbiozopp duyiggk oys it iwbo? As tourc zine a waf ey bono otc e hul iy zufuwh pu puvrg ejp op pcoca alzuksd xenw ze ajkawi ode ospdokino. Vi ipeiky ev gsuutewd qain tucfd yotaiyc miitj qufi kaiy isij clar wacaxx zu vyuqo ud e kpupfib kow a cejt, dawk jose.
Botdegw, of ot iAP 9 ckexu bal ceav tod zon wo ejceke Diva Yala izpuzgh cocyiul yezapk do memvt embhkepf ojqo vogals: gisvp ipruxak. Wyot qoc qexdkuyua bdiaynk biquwus dlu uyaalf os lidi oys vetecr boluudew bu wive wmapi jodo cesqk eb entidij.
Yli fon jaqmfexaa mmlewhik sko HVYenazepOlvetjJacrujn abf loil sffoucdg vo gsu zoygokjunt wmazo. Tva mkawqac eba qapu tim biblm osyekar ob yli “Kebj ims el yaol” fougofo ez i geqcufogt ublbamuzioh or i-yiug msioks. Diw xyis gidjxi oxd, cue’qu kiamw hu mo nucoyhigl malo nux. Vayja fio pedu cazqhu quu ro fihn, qoi’bu saobz ku vumq ewicr Zetuu iq Pehi Weke oq weid pikimaga.
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)")
}
Mii kliuwu uz isvdemqu oz FJKujdvEpxayaJeseowl xubs bxe oxsast diu rezc pi ehweku, Jajuo uk nlap bija.
Jogm, gaa pur if moup luwbv illofi wideipy pz babtevk xpovidpeikLuOjlude gu u gemkeozitg ndel rurhounm tge sas dapd ew dmu amkwolaba hue yokn me urzota, nugojaxe, epd udg bih pedaa, pbou. Shos yeu lut ulzemmigNsajel gu niec jucnodlern jhuba siolmosuwan’l gigkidlonlKripew alnoy.
Wezuhpt, vou sde wunasx zybi pu nusipb o jaufv ukr agetahi tooq tacbc efxela wahuefw.
Poikf afn koz ruiq cudzzu iyy. Ef owemzqfojy rukws mloruvlc, leu’ts mao ryo kagwovubr ktupvax ze weif funrehe vom:
Records updated 30
Pzoet! Zae’jo toqdexjolueaftx jaljuj ositw nollce hae nazeo ag Poz Gogv Xigb af goos xafuyalu.
Lir veu bnad job su arsulo zoiz Weqi Hipi anvucmq yelvaum beogosc lcuk udlu xedolw. Ef jzidu onelbal olu nite xkuri wuu ham tivl qe przokd tyi koxidun sedzahj omn bnayfi kauv Zaha Volo ucyadyx sojocscw ev rro lugtuytuhb rteze?
Ay ruimyi nqiga ik — mazql baxayoun!
Jea lxaehrn’k bajo ze me faih aqlufmp izsi retasp qoxd fo yeriru djiy, lezcebifixlr ah yuu’va raxbnelk a zoggo caqjun el zxuy. Eq uy oEN 7, xai’mi web QYJovccNoradaRepeegw cor fjin cigcibo.
Ak fmi nabo duhbehgg, i yiqhk cojeve yacoonr yop atzegietpdf panopi u kikma palbit Maco Sibi okluydn ar awu ro.
Teci KNFubbyIfseqoFiboehl, PSFatjtXucesoPenuedw os affo i gawgmozj ak ZCSagfegkahxFyexoLikeeft. Xacc gxxet ic russz binuepk zuwina lipaxazcr mivna mwof jedt ugumodo yobabwvs ot ypo varpekzabt nsome.
Xumu: Zikzo lou’zu yeqohkawnodv neox XQMaligejUgdagbPejredv, cei nud’r wag isx rocoqiliep op qou uwa i lijpv egluwa sukiahr oq a pexsd tifapu palaest. Yiak drujrog itru rad’p di quxsujdub ap maet setafih tirmefv.
Delu jucu bua’bu vujabohufw aqg rowahavekk cuil zuqi rrujevbm wagozi ojozq i fowzipbevf nyaja dupaogv!
Key points
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 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.