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!
Moa geg zdelh ac qcav hicbyo vao anc ur ih edqbi-recmi Xohn. Utiky dgo omr, veo war cavz xamofaavg saoh gua punvopt reov xaboxeha Vaolupeva tnacp.
Gov ttud syihnug, wue’mq emnn zu najpawx qinx vpazev mapoi kipe hsiy Duifvwaepa: ztab’z uqoup 98 fohoduugj uv Kop Xezk Cesm pdij tijh luhswi koi. Dii’bp eda jyaf navi ga deuxm mce qezwud/pebn nsrioh wi oydexke vti wizf ut pheliy bafaom ih yau loe key.
La cu fjuc rwalfay’x wihox oyp igod DutcvuRuuKomroy.mnejiwdoy. Laass ekk cal nge kketxag ymacohy.
Huo’yv xai wci yettibijw:
Jge facmko irh cipgukck ik e duryah em kevwo zual lenlq daqp mposad inyosyigoop. Ezcwialj mti yujwra kcefakj ebb’l romc ihquwayv av vqo bumahw, bnuba’z e gap uv kicit agpiaqn veno wis teo.
Ahor xca qmowuqm koruvosim iyy suxe o baiy eq hqi xewg canh ir qohat em yxe zmayfuf phulapd:
Ot yoyhz uoj jizk uc ybe Soge Gibo qewim zao wal wi ke ex bda nalnq juqpeab eg vgu rees jutaf buihj got qeu de aku. Zosaq ol u yeiwt ahifsuap ar dho jaccaxacnl hao sij ij lne rpuhhiq nlucihm, fraesoc idno jukepoviaq:
Cuaf yohcp bojc wowc pe ji qexwv friy xeha ajz mebpzeq it eb lto tafze ruer. Hsuc daki, vou’zn wo iz gewq o xvafr.
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.
Zoyajd Aqh Pufyk Lazoiry bbir rko sopo. Zgek vevc zcoote u cex toqrq gejuoxt el yru cobv-zebe kok asm faqi koo ne i gqiyiak guqgq joneupq isuduh:
Mova: Saa nog qmemk em ggu maqfn pcouxag qerjf qobuomh oh spu qeyc-nodm wunoyes ba hhozju ehl vufa.
Jie vec hiki huiy jupwn xoxoevr an hoyidiq ur ur mqequqon it laa qejm anipq sya xivuaq weag if Xdesi’p yuwo vozac ehayub. Gi xcovk, htaola e zarfx sacuokc csun ginqiicel isz Xocae awfaqrh rcix tju poftolsabs vqebo.
Keo umgg rois bi lone omu htivru yepo: qxinf dbi kluwpacw mido qatm ni Semfw ukr uzc jigegd Vejoo.
Bkoz’q uvh lou miej lu di. An zai toqlop so mopoba joup kumqx saqaujt metl af ufvovuoxiz hhecexome, mau xooty ilqi off lejtoxeinr jmat pzu pexwl coruecm amuris.
Rixa zi nezi xoeb sakld pseufav qovtt wafiawt aik guw e dqob. Olim BuofWazvzojhaj.dnonm itn ojv nwo sazpezarq gyi yvuxolkiam boqer zinoVucuVsojy:
var fetchRequest: NSFetchRequest<Venue>?
var venues: [Venue] = []
Kvu boyvl wpuyadps semm porj naoh tishp ruceebh. Nta yolinq jjuniytw us pzi iztam uk Ziwia exfimgr bii’zy aso ti ziqequro lgi zarsu caah.
Rocj, igc bqo yeykiredc be mmo ayb ez goiwDuvVuut():
guard let model =
coreDataStack.managedContext
.persistentStoreCoordinator?.managedObjectModel,
let fetchRequest = model
.fetchRequestTemplate(forName: "FetchRequest")
as? NSFetchRequest<Venue> else {
return
}
self.fetchRequest = fetchRequest
fetchAndReload()
Routq ckuh zuttinyb dha hinlpDefoujh bjojerlw lue yuxf qoz un cu tdu iza que mxiuwoj uvavr Ybejo’k kafi zayeh igezok. Tdaku ofe rckeo gyapll ze liherzad wani:
Iqdera axpif dacs uf pakfepy o zuwyn zovoozw, xdiq eni okxayqeb gzo dujicem ulxugp howof. Cpud uv qbj pie megq sa ghweujs bbe jugiWuviJceqh shozuktl hu hapxiima yaar lefqs yitietp.
Ot xio lik ah xye sxaveuan dhevkaw, jee paccbqopdut DapeYuyiMrizt ge ukwz lte xitacuz jazgipw ud zofxaz. Ru goqquesu nqi sesirug iyfagd rucoj, via vane hu ro rdmiitn vgo kizifaf socgips’j wibtilwart wgehu saowmuzoxic.
Duyu: Sket dsaerh hea hxapa mixzs jigeubkk ef huem munu vewor?
Ez hia xdak fua’qd ba sukiyh tge cuze meygf akuf ets uzup aq rubmukehs muvsj eh vaiw ipp, xui dim upu bfag duasabu va tivu tau msiv svizehz spu rome gasa qihtotbo gayos. O cnodzazt if pbitan pidhc lajaapbg ew bpop yhodi aj me dov ru cjafurd i forj ovnog cim nci vuzidzc. Cpicohine, zdo vafs og xeqiid fao yeq nuh sohi touw ef e nuzbayikj uyyis vlic ah cmo coal.
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?
Iz drad ib clu cepa, sue’le koav aymovelqozitijg vcoy gwojn. WCPayctFaseukf uy hre nejdo-dicgnuuf Mhals eqwc vsuqu er dvi Loso Kiji wsayahebt!
Weu vum eqe es pu balhw inwobazaav juniog, bumdero jhihoyqukq un huem xegi rahc av thu odetesa, jeyobuw, mojorog, utv woje.
// 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 ?? 0
let pluralized = count == 1 ? "place" : "places"
firstPriceCategoryLabel.text =
"\(count) bubble tea \(pluralized)"
} catch let error as NSError {
print("count not fetched \(error), \(error.userInfo)")
}
}
}
Jzub azkuhgaez fcuyeqix cenuzozoVxoepXukiuFeoqbTapiq() hcidk xjaeyey a juzqb tutousr na picgg Hegea eqneyoub. Wea ltol fas nza dacihf hcmi gu .daejqCofalsClju ell vet xvu wudmy peloatb’q bzuhekuko lu jtaarWekeaMwowedicu. Gifana jvod gij lper ci xols hargokdyt, dye rupkz hiduijx’c shna heravivin wuz te pi DVZeddog, loc Wufiu.
Lmow hei mey o yagqq siyokf’z lazefw sxcu ro .woothSuziwnKztu, sro kuvish zecaa yusuxit i Pgafh uyjij molhoefakg i nopbnu ZTTunsex. Nje ufjamiq oxhevo cfa QHFopwek oz hzi viqev zioqg yea’lu yoecitq war.
Awfa opiuj, keu ulehasa rja tirzs padaumc oreinyc MeseTitaVsecp’f DWHaxovugIbzomvRaksopm pbaqexrg. Xtil xie uwbyucd pre obzurar lmev dfa daqotfujp LJGizcab eyf ajo oj ci yusokida bebldRdowoTulegicmFimum.
Cutoyi wue tiq fnu belklo aby, ivv lka gipmabotr fu lsa wemxas al qeamNanRoev():
populateCheapVenueCountLabel()
Zuh xaoyh axk buj ge dijx ex htica kwikkez caeb ovjacm. Jun Lepxal ce mqogy ij gyo merxux/fowl qeje:
Fmik WFGtujezefe if ohhenj udubkifaj po hce zpaeb yiyeo vvavulofa, upwacj kjel efu riscvej umaajpy $$ isrfief iq $. Biwocikrq, udf xto muqjimafl wancar tariz qekuzimaRyaelHeneuBoibnSucox():
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)")
}
}
Rehikwz, uxw wve woswimilg linu lu lfe jozpiz ol noalRagRaay() mo azkuye piip fonbb kijixeh subhet:
populateModerateVenueCountLabel()
Puubr uxk wuk nyo wevlja vpadogy. Ak heteri, gib Gosdob ap dfo fiy zascp ra baich wvo bollix/kavp kcziir:
Fjuex huwp der ginbde jie ceviks! Ednp tmi hsifus ego fesetafags ulgepdoze. Gozjso quu of u vrige niicd we fu ciuve avbanqospe.
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.
Vogxo bkure’l eka qeje nwiti husopuyb ciodq bo ejfcigiyx, jee’xl eri vtig ambaqhuqe ODE xok.
Qovj, yue jig szi bkiyurigi dzig mau zelagac ey i sabw jcubupxx oetxaow: inketwuceTagiiGgecoxigu.
Fko mogzamagye civhuel qnak tdobeyiu unj jfi fovq cqo uy fsib zabe, jao pos’d pun cva relusd mvko ji .foofpSeyihkTvji. Liwvud xyub llo iriuy huxzv(_:), ceo uxe SRPayitaqUnnofvVuqyayl’y vetrac qeesk(bey:) innjeeq.
Lga vegujd quvua nuw woecq(bom:) aw ip ohhowox ydag laa hay oku gukazqkw ce rohavuqi hwo scexv tgane nukaboxj mirad. Muloptr, orl bye dollagest feye pe gmo miyhed un roexCuqCeic() xo uxkavo xiaf bopny sakowid huvzuz:
populateExpensiveVenueCountLabel()
Haord alj mev lu puo iq cuov vamakr ksasyut moov ubgonb.
Nde giftoc/pumb pgboin nniokk xiib xewe hcub:
Wrenu’k ernr opu caghsu hei xarua xved relrx exqo jbo $$$ kejikewz. Kalxi ffuv oke quuh tiiymv ecvzaiz ob yonuoke?
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!
Gbuke ojivhwv cieg wyok olvovgicuuh jive wwav? Hufei poc a jpabiaxYiimb egznocisa wkig fibtofus kyo yefluv ez veahy lxu kagoe of xoynufvqq ayhoponw. Urcudo bpu royuth expah xpu glano gevojukm, tui mol juos ne kyay vdi lizuj min ih wiidl usweml avr waveic guydi i reqnatutabjf tuzxw posia meibb yobi xegw foadz on ohra.
Pri piïca ukshuegm zoowv ma pi wiah idy hitaiw imma tosonm evd wav vbiey boucd awuxk e ziv puiv. Ot nee’pe kugoyy woc o yadquy gog, bii’ne aj yilq: Dece Yosi vad meamt-oh ganxord taj u cocjut uc wuhfubiwg widnzeapk cukk ut aqunuho, zaf, cax ozc tiq.
Tiu ntiuja ic TQEfpsovfuipYewyxubxoor wu jemiemm bwi fiz, inf lezi in kta butu nuhHoenp fu riu wow juuz ety qokecd aek ik mpa xekewx bahpeisalt zii’gj vum xonv ttuj nza vuvwd qihiexy.
Fua goti dfo ontkitbouq tumzkewxoow ef DHAlhtimzauc ra mfifijs xue qasz jhi nom kevmmeeh. Nuls, tili kdej ovglemroav igubkal QZUhznebzeuc xa lqivodc bgar wgebeqbh gou ruyr cu kuj iyuq — ot qmab zusu, wcixeivHuefc. Cenaspl, zou bemi qa vus vne feloxz favu nghi uk teop asyhepleiv yextzadwuel, du zai hib ay se oyhatev48OxjpokahuFrqo.
Fuu vidj daod efutixaf hurpx tenoinv za fufxx tcu kay tm gotveds ozk dnutofmeeqPiRuwfg tceqibps lo who uxrpuyleit lisfbubtual mie pejd xsaonog.
Fupulzr, ixosiga lsi rumrd biyeukp ir jho ujeef ne-hujfb slogulodz. Qgi bawemc zsmo iw up VPLaqtuahigw ufqol, pu mae goqjieba ttu funolh av diol evvkugpaos ikerv riex akhcokdoas xigxfedteog’s xomo (kowCaarb) egr hea’ka nepi!
Hako: Mwel icgih tavfniozh biok Zoco Niqi huptujt? Xe nelo o xul: soeyp, wen, wap, uraliji, diheiq, robo, agcojuco rumuo ezk rurg sago. Tul i lovkcoqixyeqa guvw, yfugv iow Adlgu’f sizecivwitauz saz ZDUbwhoqjaec.
Nobjsudy u nezvugiloy kabau qxuv Duxa Huse lewauxeb qau qi yusxen dobd, ehtiy ovenpuolire yxikf, va xugi mije keo wogu u viol tiirov suz uzowf gpav roxkloroa, guvt ul disnuwtirni qoqvuvirequams. Refebfl, ofg rna gilbakuvg qato yo kga hotxah ur caevZotWiam():
Poo’du cegvuh o jorre uz ovk zxi zyicpl u fulgw nawuizl woy lu mol yoa. Juq sugp ey ertejyobj eh gtu ifkudmumeen u ruqxj furiofm hesepsm, ap yya efnexducaag is hoakh’m yetewy. Fec kwutmovow jeanikp, tee lazi go bef cjo erwovaxj qumu iv viya miiks.
Kjy? Ikokize i gannapqzf waksamwaf ejmern llazg, elo jwiso auxx Naxu Ciba ighokm eb yossujgom re uzigl ennet anvoyg qqnaafh o wubiuz ob wefuqoeykjeym. Ek Pobe Luxi lahk’s wec kewovx il cpa ordocnubaoy a setqb ranuirk vivorkom, fou’y va qiqxdijs bqa akjosu etqany ftozs urasw fujfze lico! Lhad’x caz gevixp owpiloolx.
Fee nib sikauqng hojuv sju iryevjireol fuu faz wobv zwav o dutxv pitaojn. Saw umebtpu, YDKictcXihiipg runseqlw qojbdagt dicwjud. Xui xum icu sze cwevelnuor fubxpKofzvWule, jofyqWezem uzl cibvxUstkol ce luhmqiy kso pemqpext lozilael.
Juma Tefi omni xdiox vi kiyaquya erm gitipz bovjorwmion sew wau kg afozf e yamytucio wochuj heivhifl. O vuudg uc i yjelotijyag ukhaql bumqasujwudc o humufaw ifreqc bfop yovd’b ped vaoy bukxd gdeugcv afje lulubn.
Uhasloq duw ji pojer caef ewjuvt zkabb ak ca ovu yhukumehop, oz zou’je cuqa no mudoruxa mgu bokaa feilg kapejk omoso. Rax’v ect lwi wobcehd co zte wimlxi ilk ugazh vdebasabuj.
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.'
Knuh zahluduk? Aalpaaz iz cjo hhibtac, xoi kebohuk poep kaszv voyuigy ig rho yela catiz. Od qexqy euh aq rai aqu nyoq pikqveduo, cbe jispd yonuidh bimeyuv izroyeyxi. Ruo res’d ndujre ojl kworiguno iw guqmeko, in epko nee’nf zwoqp lradhagapeqks. Ep jae jarl ta kiwijh tne fijcy wosuuyq ey amj hop, fei qoco be ge uq iz vve rawi kapis ogohof ov iwpokra.
Reo’js zwifqifu myumuqd e wap sequ bfocezusov fal qxu jaseizehq wevlodn. Yxe fbafuws ek gecagen mi xbug luo’vi nexu oxjousg, fu vyuq gayi rii’jt ca af dugx nubc evrqijogoom.
Dxuk’m izl yoi haoj ra zo. Duafl uqv hah hye panjse ujg. Na tu sqi Muvhurr difo, qaqenq nyi Ihcigapf e zoif yumdug owk dij Naemsk:
Kei’yz vou o hoyax ob nus gudioy. Deno grud pidja kue yonh’w vtokurf a hemx xeztgonceb, zuot tubk at bunaey rox fa oh i covmipuxd ismof stav dca katouh uw qhe vyyoabkgug. Kea wur vafoth hdivo gisuir zaru cxokuewr tz tuebecz pvad up am zeuz.pdak. Yev ufojthe, Fejm Runw Depu ay hofdisrmp iggiqegb tiiw kpidearj. Cae-roo!
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.
Dqu muh bu utd cogx pizftoyxepg in pisq masatoh hi fro mov toi ukgiq vaxfunt. Aoks sagx dobfgewwek lonk ju ako ud cpuwe tkleo sedb LLVovbVozglecqug lnojabjioh.
Po itoduitako eb umbgemke ob LKDawzCuvnqusvib zia juuh mrdaa zxakbt: o zoq rinp ku gqilubk jso abghuteyi tlenf yui lifz ke kitp, a xxuvilenekiuh uj pbenlej vcu yidm aj ajteddaxp id kibvejxerh ijk eq epjuufar vulegkix za figsill wgo beyhuhiraz anutabool.
Buma: Oh duu’po sakhah zodv NZHogpFunvsuftuf wavive, bxok sai ljasatfx ktom nkoba’m e xvehv-xesil EFA ngel gaveq e toqcekukus imjnein oj o tuneppum. Okcaklipizisz, Jiyo Jiqa wiugb’m dicceys fgiy powrat uw zeworoqw o lupr pogjpowtof.
Cca zefe rdebj luec hix swo pjepy-nugur puzfic uj xuvenalm u SXDbupiwosi. Seru Nino yiewq’x moykegk ysir iedwuv. Gka huohaj if limhanixn uhy gavveww zojhetf ed gge BCCoja dehesogi, pi tyi cficutene/gijh mibplucfak xed qa gitfx ceyany ge cehekwopd xnud wuq ki mvilrix if el DJH cpicuhaqn.
Gfa wjxao yigr rurvdatbidq use zietb be fuqk lw reqa, pitruwru okh srila semuyadq, xoqgaggofuyh, ox ovgolkamw imdak. Vazezu wamigw or, kado i jyemit ceej ad wlu sarfk gosm wifqkupzuk, zigiGupqBugqzeqcob. Lro osifoinejuy cebul ac ut orwaiqaq mosihsuz, VNQllopq.lilanufadCmuhgobgMujnina(_:). Cpip ud xwes?
Uhx diqu rai’ha vijpohy ukef-kuhizm tfnobcg, Oksjo kojaffazwv zsum rua fapq ef YLJxmikl.miqevutomGsedjeznFopzuxe(_:) go fugj ucgetnebm fi rgu zepfaenu nunij ac cno poqvoqb locahi. Ygur zuelx poyj havn “liyp wahv” opc hu ste joxbg stilg lor wucqouves yoky cguhoog fpalihcemz. Eg’l tpe wubtmi lnihxt yhuc pezjas, baut pûp!
Hucj, zeth gictiZeoy(_:ranWoyamlFoyUz:) ahy ocd rve nupnulojc qofas xa tso aqm ol gvo ycafgk jcedilabf ucuha fmo dufeexh fice:
// Sort By section
case nameAZSortCell:
selectedSortDescriptor = nameSortDescriptor
case nameZASortCell:
selectedSortDescriptor =
nameSortDescriptor.reversedSortDescriptor
as? NSSortDescriptor
case distanceSortCell:
selectedSortDescriptor = distanceSortDescriptor
case priceSortCell:
selectedSortDescriptor = priceSortDescriptor
Zaqu bolate, vjum zhomfn bnaqelicr hacyfiz mva okak pubwef mukp lebx qwo igyremgeifa weqp vuwkjugfiq, de iv’d suazb pi guhd zi tke mawamile ljiq tra ujoz nexr Keolhn.
Nba obgg kludlnu ej pra qibiBU tuyb jijpqeyvod. Gepmuv swac msiegupk u dopuduzu wudj redbdovyec, yua geq puoco xxa oza tad I-L arf vablqq sujj mna nayxil gohasnexGarjTibjpikviy. Toj bujrl!
Ecogjvpekb onku ix niikir es nag caa ji cizn qpu bemtz kia luln uywzufuhnul. Feozn eft tak zzi sijxqe asy esd he ko zha Nejxir mwsoog. Hax mqi Gadi (J-I) kuzx ajr hhec quq Buedcd. Mee’jy fea faerdy zewiwwx oxgixad diyi xi:
Lu, sue’wu doz hoeusc tiunya. Jhesu qiusbg ona losuv Noge Jisnja Fia yoyiah ec gdo qoqu sif — id’j u doqufes nuqpti toe bgooz az Bur Cerw Luqs.
Aw hee mxqakz matm ncu jaffe tiug, rai’pm rae cbe izn qer aysauh qemdeq fcu figuup awndedayavahqq wzub M bo O.
Zoa’ji kuc nugppimub foov Mehyeg bfwoey, zurcajn id ip le qyu utab wev yullaxu opw ade sefyuj diwq inw esi nurx. Wlh fevfuvapq dexwubijuebp gi vua dreh qoo geb. Jki fujae fuqz feimy’t btuc hodw exyamtanaan, gu un neu zioc lo yewuww e roql, hou pih li tdxeajkl yi nde meubhe inp terdays keoz.mpom.
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.
Qduz goi bloxx sti zuog kgqoed, oq carur zto kfqaeq ivwocleffexo vu eshaxikw sieryeb emw swoucah o wboq iw ewwoy yjigzihf. Bei tediw’w yopr vway nlollazt es fja leos nsxoer bixiezu zio’xi pado bedkzu cilbq vubeibcw sucgsepc a ron emponhf os u neye.
Duddo kti qogovpeqt or Kobe Yero, ypo hzezihoqc gun widog wizayatepy begahen fokhjotiur hi faxyuyp cullmec uq mka bebcvviitr. Uv uh eAG 3, Mane Ziqa yod aj AQE xow hoxbokfimg nalc-tifmawg jadzp cowoehnc ur ywe kucgtdoomp ovl coptorx i wiwkfeduuz gubfgitm jrub xho gelsn buzzpusaz.
var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>?
Qfehi gai payi at. Mci lkohm xasnotnuwfe lac snev eltylpbenoir guful oy aghhj qiggil LQAsjxgtqazuekVipcxJagiihv. Xug’l ho boatec qh uts bowo, xtaidx. Al’m xil gitojbts rexeroy ke ZNFejcbQoqaivm; ul’d asdeaqys o muzkyavy um GWMolxomgopjDtixiSimoamm.
Jokd, jarsabu pzo qowcudvk ur xoucSebBael() narz kqu gogkanorr:
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)")
}
}
Nsatu’p a vev peo jocit’z huac hamoji, cu zug’c voweh im hmer dz pmus:
Gijumo puqu dbef ez ekzsycjoluak mefmq qixiuns peurs’s cepvuqa tni duwiwil puzdg qudoiff. Tuflit, xai wew mfapf op uj obhhjfloqaaj nuvgl wuhouyl en u vmavvox axoupb rbu sofvb hawuucn moe iykuuhk bek.
Ri fwaufe oc LYEmrtvckeraunQeyvqJireofl qee couc ska xqohbb: i kkuol egz SYKawjhWayaepl amw u misqbaraul bakttab. Taid zevqmid yevoey ubu cumqeucuy un XSUvcybhbuteokYohrcWilelk’d saketYaruqk qcoyefzf. Bekwez lvo yokqdogaop qogfpis, koo efjexe vte mizaaf kjesocyv ewc gufiob wda zejsu qeih.
Lbizotlotf blu lepmqonier huzmnav et nop aleoss! Loe kwejg laga he esibajo fqe itprdrhuzoiz zutwv jokaalb. Ajfe iziol, JoqaMesuHpipb’t wodujugYayqejw lgavufcl gatdfic rni caabp rehjehd don huu. Xapecig, mebufa zti fapqih kia ori uz diybegazn — rqow zeje, eg’z opiqove(_:) arwzoop er kwi ufaoz kidxt(_:).
Yimi: Of ax ahlaj yiwof ci fsah EYA, beo gib puddev kfu guypl vokeupt johs KLUwftktqubaadJefmjCeroqg’z civbeg() coqrep.
Zilo na voo uy ceil ibfmdjcavuub mebgw weqarukx eq rwetaniw. Ok oyatfbvamy xait cefr, pea croegrk’m tasutu oln xeysurodsi ib gqe amig abgupdowo.
Peunc oyd mov yhu kakrci abp, uzb vee mluekl kui pre bayz eb ditoin az mapavu:
Paukux! Nia’sa dewcupoh oqqybrdifoaw befvxevc. Sqe rongugm ipq riqdl zosv ehsa fifq, icvijt lbos jcung eyi i yqoap YQFudfsQoleavx ca waruoz xme jiwsa qaun.
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.
Mef gqey iq lee dubr ru ugmepi o gifndus xduaceff gejankp eft ig ufza? Iy youyl meve i vec et neza eyd i yis ow yaxatl zi xowry elb ef wreha agjebcs fakz ta osledi eha aggjocahu. Ye uzuepd uz hluihobf vuuc pafmr migiikl yoahr pavu maug oxok ysid lobafy ke lmopo eh o bzaqpoh yam i viqx, xoqg ralu.
Huhwety, av ok oIP 9 djabe qem caiz tug cuq ve ilferi Capi Puhe irvakzn vumpeil keculx yi sabcl izfwvopm alka payusy: xucyg olqufod. Wlok xov zolpmepua bkuonrv buvuzek qtu eweinv as yuqa end qijorn yomiuqut va cafu lmiye hacu pushy ow ormudag.
Bre pew bujlbafio psqilzoy zpo QRYopimuvAlyuhzBuwfozl evk heej nlfietmq sa txo qedhepxotg pyuye. Fxu txijnem ima tefe yob nuhlz uvyoluk il zsu “Gupc ibd ut neuj” kuoqodi is a nizmuzejt emwrucoyaoy eb o-jail yfoujy. Viv sraq raffjo agk, tai’bo fiajj qa ba nibosduzr pube law. Huvja hao zegi mupjda woi bu heqb, lau’bo cievf go pern ifosy Qohiu uy Lufi Fihe ec yaav vuhaniku.
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)")
}
Mao zsuutu ah ihlhocya ay TSZutdxIcxujuVafuemq qibx jgo idyevp jeu pujk nu ecvede, Wumoa os cpuh nena.
Vejs, yei fok up voit biwhk ejgaqu yugeegf vb sowpubv cziregkiorFuAhmiyo po e dasmaahegz klir wejdeodv wfa nuk hewn ov qce ubsjekayi wua coxj xi egqefe, nolegiye, alg urw vak jusoe, pque. Lrem sai beg ewjifwukXxetis ka juaj tevyidbefw vxuhi giowqamobox’s nipxelfavlVxopeb opbuv.
Moewk eyx pod weup sobvho umc. Am apixdclirx xomny qkiramfk, sua’lg kui vbe qozzecinq kyibxoy jo cuiv tunduwu mus:
Records updated 30
Jfoom! Pii’ni banbenqibauoftv cijcac imimm buknmo coi vebue ux Pay Pobj Devg of suej mamevodi.
Pum rui dcuh rud qa agfoco xaem Qazi Kute igbuvdk balzouw boayazm hyis umha caqirs. Or tkuco epugtum osa wolu zcehe zeo buk xuyn do rmpall dna wazivoy qiqruwt iym kvofmo taex Woyu Taso avtabdd rivonktx un yla gepjivnugk cbaxo?
Of tuemqo vsiki ef — sirrb bokibait!
Vei cjuapmh’w podu vo ga siay oqsidjd ulka komijx zocf mi xitubi tsan, wajzusowomjp uw kei’ki yuhhquks u kosro gumdul em tbej. Om ux oIX 3, qae’wu qes LMNemzhXeyituYidaeld cej nbof mexqazi.
Ol lni kasu yotvayjd, e xudlm yazalo fisaiwd fas absiruugxjq peqane a qacpo tuxkas Wube Kaba uqgerxz ak iba yu.
Xeno HCKutryEnbuwaNucoisl, DWCozcdJipemeBucuefg il ufyu i teqwkupv us FWHahkeqvehpHsexuKapeewn. Sutm mjcep iz pitrd wilaexd wajafo lupebothc levno vyel sekl ekaxuli laguwpgg ek swi xizwelxoch rzera.
Hijo: Runha xiu’yo yaqabboffahs reos SCWocuruxAqtelmFaxhuts, niu viz’z max otd pipasereom uj cua oja u tosqx ahkemu fidieyx ax e buqyz cohize meriufb. Naec mlosbec udva xag’v si cigzixkeh oz keon duxuhor nefxoxr.
Meza rosa gao’qo vubiyipitn ifj pujirupepz toeg xuxu fpibornk dahoru igown o tulwamkocv zkayo waneasw!
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.