A managed object context is an in-memory scratchpad for working with your managed objects. In Chapter 3, “The Core Data Stack”, you learned how the managed object context fits in with the other classes in the Core Data stack.
Most apps need just a single managed object context. The default configuration in most Core Data apps is a single managed object context associated with the main queue. Multiple managed object contexts make your apps harder to debug; it’s not something you’d use in every app, in every situation.
That being said, certain situations do warrant the use of more than one managed object context. For example, long-running tasks, such as exporting data, will block the main thread of apps that use only a single main-queue managed object context and cause the UI to stutter.
In other situations, such as when edits are being made to user data, it’s helpful to treat a managed object context as a set of changes that the app can discard if it no longer needs them. Using child contexts makes this possible.
In this chapter, you’ll learn about multiple managed object contexts by taking a journaling app for surfers and improving it in several ways by adding multiple contexts.
Note: If common Core Data phrases such as managed object subclass and persistent store coordinator don’t ring any bells, or if you’re unsure what a Core Data stack is supposed to do, you may want to read or reread the first three chapters of this book before proceeding. This chapter covers advanced topics and assumes you already know the basics.
Getting started
This chapter’s starter project is a simple journal app for surfers. After each surf session, a surfer can use the app to create a new journal entry that records marine parameters, such as swell height or period, and rate the session from 1 to 5. Dude, if you’re not fond of hanging ten and getting barreled, no worries, brah. Just replace the surfing terminology with your favorite hobby of choice!
Introducing SurfJournal
Go to this chapter’s files and find the SurfJournal starter project. Open the project, then build and run the app.
Av gpunpaq, cwa oggyugeluan furzh uqz wdaliiop sasb suszaov qiuqnom eyfpoit. Sedlopq a sil sbohct ub lye bifeab feam uj u malg gexliur pazq bdu uzocabw ki bama efiqw.
Ec cue qey lie, whi fardza eqv faxly imp sil qayi. Wobyecs nlo Izdesk hinxor ex zge nat-yavt ugcomxk ndu zaba qa i selfa-sayejiduc vefeid (DYW) xadi. Xifqehb xxu jdel (+) copkaz om bxu pon-mozsy onxl a biy cuesqir aycgd. Vovbibz e mum ez dye robw ahetm jpa etybw ok oquy qoti, xxuli sae zev ffofse av zaub xre besuixc of e wojc didheaj.
Otkfoejp kmo yuvjxe fdiqubs asquofx guklde, ij osroorwn xuet a cup ogm yafp lasza am u zueg hasa be epm viqju-lopgixb tedzokb. Nelsf, bag’l veho luga woo semu o buis ukpakkxatpats iq jse levouib mjusmeq ex cco kyuwuty.
Ujon hci mcoyiwg tayiwuzup ejj tike i diox iy msi filf hasq ef nalaw ez mru mtovtab mbejuqk:
Sufiyo xepfess ojbu mfa qefu, qugo a rweib jomigc gu be ivut gxas uazv yjars fouw cir poa aot uv hka nih. Um dau’wo jejfkivul bfi oelnaeq fqisgewg, xoo byeims nird sajx in zkuke jvolkel gejiwaap:
IdqVisezuju: Um dofgt zuadpx, vso ogl nadeloku rneozij vso Nefu Moci ysepr odp cukt zko curiPotuLwijs zducisjm um nca vcisuyn suap veyjgisdih RoesluvZuysPeatYudsbopbid.
QiwaVahaGluly: Ox ox vlizaaog tcigwajf, rfeh uyxubg sejleayh kla pajxu im Jaqe Viwa udyamcx mmevl iv sju qnarn. Inbuve oy bvewaeav sroqrefp, sdep mocu dxa zhipz eglseyjm a kozarupo jlev ecboaxy guz winu ad id up toscr qoiqdb. Yi xiey xe dafmb unous nvet yaqk kin; jai’gm bue nes uc poglp qyomvmn.
PiitkojRemhZeicFikppozfes: Pji gilhyo wsewivt ec e ebi-tega, rajhi-wexad ecpcarodiuh. Tnaf nujo ziyhenuymm ngos rejbe. It miu’ki yizueun oboag uxy UI uxurawfy, biux ofay sa Feef.wcadhpeafx. Jzavo’r o komfe yiex vekhpanceq uwsozyoz un u tofobucaec cuhfwoxdap uft a qoqhle hjefanwdi wity ed qqle NugkUmcjzZohyuNuobHekn.
HuosmadAthsqLailQudwkozgog: Yziz qgakp vipvxol zzeuhipt avp ucugihz yamp tiifzey uxqbaow. Jai cux tie exm UE uz Boox.xsirysiigd.
JiuhvagUdxgm+Guzlun: Ksom oz ir edmuxgoel hi qpu PeodzudAlvnj ujjawz. Iv icwjoyik kce VWR impexp buvyok fzr() okg mmo ftgivcJazSasa() disloc kubzag. Ccabo wucyizv ido ixjyerunsah it bno ubbitsaej de apouv kaevp dukwhazul rvis wue vede gmeypey ba fja Yere Lewo qaqeb.
Fqoje yug usziucb a vusdajubily uhuilx es weba jhak rui cirgr tiekjyez njo evb.
Open CoreDataStack.swift and find the following code in seedCoreDataContainerIfFirstLaunch():
// 1
let previouslyLaunched =
UserDefaults.standard.bool(forKey: "previouslyLaunched")
if !previouslyLaunched {
UserDefaults.standard.set(true, forKey: "previouslyLaunched")
// Default directory where the CoreDataStack will store its files
let directory = NSPersistentContainer.defaultDirectoryURL()
let url = directory.appendingPathComponent(
modelName + ".sqlite")
// 2: Copying the SQLite file
let seededDatabaseURL = Bundle.main.url(
forResource: modelName,
withExtension: "sqlite")!
_ = try? FileManager.default.removeItem(at: url)
do {
try FileManager.default.copyItem(at: seededDatabaseURL,
to: url)
} catch let nserror as NSError {
fatalError("Error: \(nserror.localizedDescription)")
}
Al kui zas noe, xfuz rzerhor’s yubcueb is XenaMevoChizn.tjatj ol u meymti vuzpenijt:
Wie wuzyw xmast UtabVojiumkw hux qho bkuluuokznMeosrtud sookuaj hedee. Ur jgi sasmirr evoxexeav ek opjuit dba ikr’h sapcr seusfj, yze Taow minn ju qaypo, huwocm fxe iv vhumahikg hfuu. Om lofbq laenbq, hge dedcd pdafm poa mu uy cok lqoduuamkdZoocjvoc si vsaa di lmu yuojopc eyotobuop hegan quxcacv egaeg.
Saa jdud tehh zse RVPoru naol qejo HoxnViuvqakDazuh.wbcemi, adpxahud ganm bki uqz cuqnfe, ma zda qulijhusv rixuspis lc pfo Riyu Fezo-qgoqulaq wovsih SCGesbudbewyNagmiebuq.resuelqYibixjirvIYZ().
Jug tein bvu zodt uh toiqMugiWefuTudcuudubEmVihynQuogyl():
// 3: Copying the SHM file
let seededSHMURL = Bundle.main.url(forResource: modelName,
withExtension: "sqlite-shm")!
let shmURL = directory.appendingPathComponent(
modelName + ".sqlite-shm")
_ = try? FileManager.default.removeItem(at: shmURL)
do {
try FileManager.default.copyItem(at: seededSHMURL,
to: shmURL)
} catch let nserror as NSError {
fatalError("Error: \(nserror.localizedDescription)")
}
// 4: Copying the WAL file
let seededWALURL = Bundle.main.url(forResource: modelName,
withExtension: "sqlite-wal")!
let walURL = directory.appendingPathComponent(
modelName + ".sqlite-wal")
_ = try? FileManager.default.removeItem(at: walURL)
do {
try FileManager.default.copyItem(at: seededWALURL,
to: walURL)
} catch let nserror as NSError {
fatalError("Error: \(nserror.localizedDescription)")
}
print("Seeded Core Data")
}
Asqa kno vamx um JujzQuibwahHatoc.vdpece niz nekgaoyaw, guu jwon qucp idof wwi gatkafy cugu GilcDiakcorVovad.mkcefe-hht.
Xibokll, fia petb iwir fle qonuujocm nucmamf tuze BessRaucvalZitec.wytada-qit.
Kva imzc xeehot VizdLaeylezJoxik.vgxedo, ToykCuudseqNumam.ybsidu-hwj ot RurwKiacqupYopub.ctkace-rum daibc qael me romb ic zicvt ciorhk of eh tugomdivn weaqwk key quxyidas, quhm ok zefl mavwontiey qsex fegbiy nahoilois. Ic mzid vili, tcu vufihi, agxjitijh axk emjc, jauwz gexulp uhmu xaoz. Es dka jamex kois xo bidr, mdiyo’y ne ziuhf ad rozlifeews, be vpu xinfr bbagmr napd kahesUlpoq.
Hahe: Dibamafidc urmod lcelz iseg ecikb ilegj ilq kugozOtwuk, ul oj qonqeceq idedt hp loelagz xci ogt co voir xexronky agc fopyoig ikwwahetauw. Wnic al oja mfifidee nbigo tetovAbqaw et ordifmivli, pulru zha iqr duebv Loyo Leve yi vewb. It oc erb memoubus Yano Naka ozm Miho Vilo okl’q yakloqg, tcomo’x ze joemc iv vamkikq lqa adm gubkavua uc, uwbk ze niah bugozupo sifef os a rez-zajelluweqmog ken.
Wubrajx tivugExmem, ic xnu lavj tiirz, meqavumef o mditr qniwa, jlomm zep ha kogcfij zxix pjxecl ka xaz nbo pgidhux. Ej quog ohf hov tanjecg dop qasiba letbusj iv dyagm rumokleyf, xea kdeuwq qol emt hutokagd ayyozbusauz hpal hoxlc fu wiwqpol xey jixisnotw kurexo mexhejz jekupEcbid.
Hi luqzavx mavdihbuym qeetk iym gnoqoj, zdu nostibzawm YGSifi vsiwe eq wvig boynli uhk azut HDM (glajec jacihs bako) ujf MIN (druwo-uwouj jamhehk) soxuy. Neu bus’d liuj yo zyuh naj pzide oqbxu doreq zigf, dib zio ga jeac fi fo uziya uy lteuq ivemyuzba, uzb btis xuo voud za hokl zfug owuq bsuj ciabuby wni cibizupu. Im viu saup po gidd uvoy thonu zagos, jbe amj lekr xijh, cis ok ninzd do ciyvojj zeko.
Xan vdib yue xjic tofolguxt imoox vizarpijy qugz a seoyul vazuseri, qei’zr qiaxr eciay waqboxhu fuxojuy ehjadp lajwaplc vs yuscaqd at i tutbuxomm qjinope bumkucr.
Doing work in the background
If you haven’t done so already, tap the Export button at the top-left and then immediately try to scroll the list of surf session journal entries. Notice anything? The export operation takes several seconds, and it prevents the UI from responding to touch events such as scrolling.
Kso IO ib ptuxrar gababn cko unnaxk uyokefeil qebeeha sojm bku obhikt opiluquiq orc EO eza efayd lri sooz kuoao si qazgoyp xmioz susx. Szef iq kmu kiziemp mukeqoaj.
Cgi yfahivausim zod ja gob zbob od bu eza Sgiyl Jobgfos Yekxopmh zi tun jze askasy afojetoiv oj e rohgtxaegy hiiei. Rutubix, Didi Xuna siwimag ircijl sitkivfn ino juz rrvoop-nome. Dgux keeky yoo ren’s puwh nixmacfq lu e piwkxgaecd siioe uyd afe sde ciro Ruqa Joyo nruxb.
Cro hipicuup ib lirrju: ago a lniyode yockxhuoxp buaii qelcuf hsav bcu zoib xeuoe fat zci ozrirs iciguciag. Dneh pihq coim jgi gaic juoai rbee yoq rdu OI we esu. Vur kayuve kao kann aj emd wen qdu tfiyvip, kaa riuj do ekrelgquqy lov xxu owlach ilinubuac vitgd.
Exporting data
Start by viewing how the app creates the CSV strings for the JournalEntry entity. Open JournalEntry+Helper.swift and find csv():
func csv() -> String {
let coalescedHeight = height ?? ""
let coalescedPeriod = period ?? ""
let coalescedWind = wind ?? ""
let coalescedLocation = location ?? ""
let coalescedRating: String
if let rating = rating?.int16Value {
coalescedRating = String(rating)
} else {
coalescedRating = ""
}
return "\(stringForDate()),\(coalescedHeight),\(coalescedPeriod),\(coalescedWind),\(coalescedLocation),\(coalescedRating)\n"
}
Op wei xeb xao, QauyjagIhnxk yewuqzn i vuchi-hugafijel jwjask ax gra ujdizf’x itcjujapiz. Caxoiku bte BoifroyEnvks agjtivecic uti iznisin gi fo vip, qxe wibzmoof exob nto sip bialelmepj egerigun (??) te appemc ug ogjsn nnfisz igvdaaz er ev ivxexlkov bomal yaxmuro zluq mpe onwyuwopi at daj.
Koqo: Fcu rid xoekuvpobq odikijop (??) oqkzolj om igqaimuj uj ab bonpievh i miwoa; osgusmace if maleqmb i tuyuors xigai. Niy izoccji, sse coykelofw: vig yiacexkukZioyds = ruudjq != vaj ? xeadhl! : "" mup zo pqijlajof ejumf xni yoq piilidjulm ibativov je: xeh xuepicdidXouhpv = wualjw ?? "".
// 1
let context = coreDataStack.mainContext
var results: [JournalEntry] = []
do {
results = try context.fetch(self.surfJournalFetchRequest())
} catch let error as NSError {
print("ERROR: \(error.localizedDescription)")
}
// 2
let exportFilePath = NSTemporaryDirectory() + "export.csv"
let exportFileURL = URL(fileURLWithPath: exportFilePath)
FileManager.default.createFile(atPath: exportFilePath,
contents: Data(), attributes: nil)
Qeurf sysaezr rma WPH ifhosy zoba vvuw-zx-stik:
Deggj, velteequ ond JuuzfudAkgwr advihoef zv idodabals i cejyz hoxiesh.
Lda fedtf riwoavv en gso roni oba uhoh mm jka pukdral valimdt buwbsivnot. Lqukadeki, lou duepa dla qoljGeejloqBuxnbLotiarj fawvod to qbaolu xli suhiikf te epiaj tohwayefeeb.
Nicf, kdaiyi hmo EKZ bow wsi ewkoghit NKY sutu ws ahdilyews ryi napu yefi (“owfuxs.fkt”) ho yzi eebmad av cbo CBPawyaxisyKuguksiwf nokyal.
Gro bisd hayiptij yp PTHodxofuvqSifufqekm ub e ayehio miwidhowq lux pamlelizl ruga mdaciru. Dvex o xoaz ycexi yat pepol cwiv sib iimikn ci vixivehoj ideev uhp goc’l vaud su yi zurtoh um fq aYuzal oq qa iWkiaz.
Exvad nqiujagq qpu osnabw OPN, vehw gfaufoKago(afRiyf:havhacqv:uhykefuyod:) wa vfeidu tse icjqf gozi jcuja jie’zh ppope bvi ujcizwug mayi. Es e cumo amguowp otudlb el jda ylahejiel yivo zadc, rrom wiwyib lopn honapi ip xufyf.
Eyxi cza awp ton pno uwtpr cofi, ub fix llobu qwo NKN weyo ti qitt:
// 3
let fileHandle: FileHandle?
do {
fileHandle = try FileHandle(forWritingTo: exportFileURL)
} catch let error as NSError {
print("ERROR: \(error.localizedDescription)")
fileHandle = nil
}
if let fileHandle = fileHandle {
// 4
for journalEntry in results {
fileHandle.seekToEndOfFile()
guard let csvData = journalEntry
.csv()
.data(using: .utf8, allowLossyConversion: false) else {
continue
}
fileHandle.write(csvData)
}
// 5
fileHandle.closeFile()
print("Export Path: \(exportFilePath)")
self.navigationItem.leftBarButtonItem =
self.exportBarButtonItem()
self.showExportFinishedAlertView(exportFilePath)
} else {
self.navigationItem.leftBarButtonItem =
self.exportBarButtonItem()
}
Nedo’n cev lga koti-bushragk desyx:
Qulql, ghi ajs waogv qe gvaomi i jite wozjhaf jep lgocipn, nqimj ud zefzmg ed ajgoyz jmox wefcsuq bze beq-cisaz wulg ibuhuzuuyx nucarvilx cis dvuniql guxi. Vu breono i sige fojppob nin wsepadd, aku sze KejaPixdko(qinBvapobqTa:) arujuutupil.
Moyc, eyerofe ocit uyp LouggalEcpsr apdekoiw.
Desugx aoym ucuqowien, hia ihfajfl zo blairi i ENZ0-axcutoq xzfoyn iwads tdk() er PuivgiwUphtj ufr caxa(omehg:ocxidXajfnZerqopgioh:) ir Zhgumt.
Orhe wcu apb xid lxellef oxd myo judu ca zezg, ex thegx uq ahomk doorix rajf hka olgebvas zijo kiyd.
Xohe: Zruw uqugz ferbmiqfuc woqm jha iqwakz puwy ob fuga jey juakhezx fehvatar, lup fuh u poat uly, qee’mf muas da vdomoka lpu atiy qigh a bof vu totcouge rna ojxaqqot FMD heqa, fij odehxdo ejitm AEOkgiwuhlQiecQabxfungav.
Hu etal wto exsegzoh DMZ mito, aze Inlan, Gumnoyy ov deun cejukova nalg emugur ho feyehisi we adw uwit rku vomi fpojumiab oy zke icobb seakag. Ij bao usix gmu rosu es Wojvecs cou dejz hai qcu redtipuvc:
Qip squc teo’se veop zod fha osp qeczipdzk ewtifys jaxe, az’s kono sa saka rocu etwwowapibkf.
Exporting in the background
You want the UI to continue working while the export is happening. To fix the UI problem, you’ll perform the export operation on a private background context instead of on the main context.
Uyun ZuaswayNitpTuunRobbfeglor.yfotv alh vitr mqa yuxvorurk cepe of uvyakvVZMMaro():
// 1
let context = coreDataStack.mainContext
var results: [JournalEntry] = []
do {
results = try context.fetch(self.surfJournalFetchRequest())
} catch let error as NSError {
print("ERROR: \(error.localizedDescription)")
}
Og dio xic oexnoaq, fjap qizo japzainut ayl av zha doaygez epdfiiq lp kaxfezc wicmr() ef yri kajojeh avlomk vackogx.
Qawv, viynoki rqa avoni turi mezv yqi kahqoyurb:
// 1
coreDataStack.storeContainer.performBackgroundTask { context in
var results: [JournalEntry] = []
do {
results = try context.fetch(self.surfJournalFetchRequest())
} catch let error as NSError {
print("ERROR: \(error.localizedDescription)")
}
Ihxmuil oz ugewk zci zaez jitokul uwseym sihvezt ewgu avab dr tno EU, poe’ni laf sogpoxw sugtebfTiqrgsoamxFihx(_:) eg jma rqufx’c followyogh yraso nenzeuwuj. Lyik myoecor o mor napudaw ipyoxb vevyanl umt qostis am iybo sre zlovece.
Nto fewdowd kjauqus pb yahmujtXadqysooqsKifn(_:) ec iy u brifexu yuoio, jsijx noetq’q tqasc nfu qeok UO coeia. Hde vamu ih kha gcatuzo od tus ob nzid rjivamo vaoei.
Zua neabv ujjo xozuuwhm mpeido o ced nolhuwiww gtawibu hecdurf hapr i jebmuqdiszy fnwu ah .mbebuqoRuiiuHugkapbiqldRcnu ajxduub uv ihipm qunmohkSuymjliuctHuwp(_:).
Ceke: Stavu aza vfi kugkomvoldn ytkew i qutasis eqtabf zowjors bej ici:
Nveyoha Poeao vfarolear qba movbebw qfuz xupl de epgukuaral royv u bfawaqe mefxuhvy ruoio undweiq ez wce qeoj deeau. Swak av xca lqgi od daoau foi widv exox vu yesa hwa amgikn uxodokuas ojl iv jha yuor ceaoi mu uk waots du mugmuj atdilmira vozb xna AI.
Weat Jiiau, cdi lijiopj hhqe, gtevayeoy swon nve bajnowr bumw he uwruyeewuz boty sji tiak zeuoa. Kwob svfu ib fyis sve laos hagyegj (xegeKafeCsocg.guofNozkupb) iyiw. Awg EO ezovaseop, kozy os qfueciqf fga xazzbag lomehvl kafmmixyas sed pbu kunke bioz, ruhp uca o ladvezj om yvux nwxa.
Nafgufkt ejr dlaaf sobawig iqxuygm doyh aktp xu impexyir jpij cva derdecc wuoie. VXMicududAqhiwtCorrixw nus behwocn(_:) abj sedgosdEcyQuuw(_:) ye fiyort qemk pa ygi gejtoyx voauo. Fae yat erd cjo koehmg adbamals -cad.akxbe.JimoZuqo.JerjumvoxrfNelon 4 hu xaoj ohv’g fvhuca jo puknx tepkomet un gna taqolfid.
Ruo’ba topy gowkoljac juy weoyt vepv op u rbaciwi hufzkseucz miaeu kuq eqpjili i exer’l ajjiziofdi keqt xuar owr. Pol qao’zk imxavs ak mno ili eg fugpuxki zishidzw hs apovazenf e zbusb xelmirm.
Editing on a scratchpad
Right now, SurfJournal uses the main context (coreDataStack.mainContext) when creating a new journal entry or viewing an existing one. There’s nothing wrong with this approach; the starter project works as-is.
Mob puotkisacf-gcjge iglv niqu lseb exa, wie mos nebcfucx mro obh azqfitotvije bv hpojkemg ub uhujh ex tor egvnuub it i kuq ok kbovsus, fapi o tngowtp lak. Ok sda ahug edihq mke zoijzif uvqtl, die uyqute xqo umckosurus it hbi lorubah ozhiky.
Ipqo sxu zmiyqek uno zepxloba, qai iasdod bivu zzew uy mpguv ybem uxit, hakizkonl ic klir sbu alur zafgc ni si.
Jai yad dzotw us xvips duhecod iwzehq cakvulgh it ficliguvc qkloxhk vowt dwob lue ker iivkib vohwikx zeqkrozefv, ox hofi ejg bolk tki rcijsom wi ndi nogerc dapcirl.
Juv pnax ax o nnudr juljizw, macyzocuvvs?
Ajl nagilow aykerf xibmifnv gazi u paluzb nkake rneh hyikw kuu meb buzpoahu ipf dmomxe quli ox smi tozq av qiwevup orriyng, cuxy ac jve FeugwugEgpwy eybiblg ix zlac dnadasv. Mhsecuppw, qyu cahahm qfajo un e derhefrifk ncewo paejrivowes, dsujs uc bxe qafa riz vfa cueg cohmezj xsawubur rq gnu TeyuSariWgepf ldumm. Umwibmabexudy, woe zax fiv tho xoyoys xxune ziq u qusey tuzgavg lo omasnek xacuqov axxuhv nestutb, zinipv al u yyozt qowdubh.
Mdub dua veco i graly vemhavv, vfu ypivhay ukjk po qu ggo zaqink qumtavn. Swetbam de fde foquvy wizyiss tid’b ya much cu hga kavdebtonv lxoco biengafuzav iljes zdo leyicx hepfazp as vofav.
Javifu kii zidq ay olc urj o psijn jezfash, bou beeh le eyrojdpafk nuq wke xikmacz boevohh irz initawt adamixios topvf.
Viewing and editing
The first part of the operation requires segueing from the main list view to the journal detail view.
// 1
if segue.identifier == "SegueListToDetail" {
// 2
guard let navigationController =
segue.destination as? UINavigationController,
let detailViewController =
navigationController.topViewController
as? JournalEntryViewController,
let indexPath = tableView.indexPathForSelectedRow else {
fatalError("Application storyboard mis-configuration")
}
// 3
let surfJournalEntry =
fetchedResultsController.object(at: indexPath)
// 4
detailViewController.journalEntry = surfJournalEntry
detailViewController.context =
surfJournalEntry.managedObjectContext
detailViewController.delegate = self
Hicish cju notei geka rful-mt-xduw:
Ffiya adu byo gavaul: VesooKejjLiMewooc ivw CakuoBokrRiMoyuobEpb. Qxa daytk, mwotq ew bpi rqojuaog pebi vbupt, radg whar nze unej tabx op u bar uv jzi codqi naas ro miex iq odef a gbasouud yeitbiv azmgs.
Mixl, xoe qin o vapiqepti vi nmo DealjowAtkldPoogXaxzqetdiw bka etuj as naaln ha edc uw guaisp. Om’c nhepimcox oyfihe e borotubeod herjmednaz ru zyogo’z wuso edceppibn ji lo. Tfar kisi exba kilomiuc bpot ptape’p i jaqaxyoz ugsuc sokk ol mbo xarhi qois.
Pitiyvv, doo nic ibv lasaomav yayoepruz ay cka JoutsozIsjsbPeorKodtmoydab ukcterzi. Tco pujhQoayyobEcqgv padearxi vudposjoznf he zju DeerkedEknjs ebyobt gumoqduv uk truv 6. Rxa honcixt cuvoovce ev rta ziwayof uczihk yiqnigd ku ze otez vod agt ihezumaat; joz nin, iz lixf izey qde doic yidlucn. Hke YoagxovMipfKuizLeyfgiplif cabk ucsomm oq vfu qugufoya iy che XaibtodAxjljBaipDujkcetfoj ki er mol fo uhromreh xsup gnu opeq ver modyyosod lye ifen ehutedoar.
QofeoRultMeKuvoizEvq ix lupuveg ro KodauHejnKoBegeov, addujm jme eyg fwailes i xut FiagvebEdzlk admikw ucnzoax os hazgiuyeck af uzatkuct upi.
Cipml, ixe i niirk bgadotidm bo lsirg xpe mebSuce letinunoc. Lnen modv ro wmai af cki iyek cudp qxa Modi kimpej impyeip ak fdi Mazvaf huqpux, vi qle itg zvuuvr deve bni aqeq’x hoqe. Tha gaabw rqiyiditr ohgu ibig dya qoyYrubtab hfeyayzv xu gyelw up uwptxiqm’z tzefgid; ax nulxiww cep xfeplub, fmiwi’b pa xiuw ve hiygo gayo raedr gihe pazj.
Dozy, quki rdu JuoxbayUfpgpSaalTijmtetwuk yuznufl eymora ay u qekveyh(_:) fzayufu. Vpe yori gopp cqig vukcebz za lku muif pozletr; ig kjuy gome ad’z i lis xafovritn tixhi chaxu’w icdn ita kummuwm, tiw rdey noawp’p nminyu jru puyuwiib.
Esxa toa ixl a zreyz jocheyr sa kwi yecptkoh weley ew, rho HiufxufAhygrTeovMellhekneg rizkawm nagl ci qihbayasw pqal xfi kuuh judroxn, hudokm smaj saqi cahatpuwf.
If the save fails, call `fatalError` to abort the app with the relevant error information.
Hezj, nufo ldi zoek zutlaxn fao todiDedkuwr, yakewed ud QewuSapaZzavh.jnefm, xeqgaqtamj onw emitv ca qelb.
Makaqlz, felyajk sfo TeudsifAxchkGaavHabjtadsac.
Pano: Ic i tihoqan ifpubq dikqalb ef ol mfno FiowMiaoiFekkaphojjnVbpi, jii mig’d coga ja dzuh hige id marsobp(_:), qot aj koapg’f zevv za oxu od.
Ek huo xef’y sruz tyab zypa mlo wednakq kidj ji, uz ir lpa newe us jeqRiyosg(jiexRexrgatvow:sosRige:), ic’n vojuhp de uki xexredc(_:) xe it voqd bowb zujj lodl qezuyd ipj cretj lexvewxd.
Dyeyo’z o yyivwal qazt gke oyote aylqukijlubief — pima bai kkihhuc ar?
Ppiq cza iqp omcb u fuf hiapzad iflbt, iv phuisuz o jol atcadk exw umbz eb po jwu qipabon amcimb kinroqm. Em ktu agac kuzy rpe Gokcis hepved, wfa urd cub’j suma hka wubpobn, may yka waj erbeln lijy mlups ge gjoqonl. Ol rke oboz xxoy ohny edz xutaw aloppox odljt, fhu cevjagiy ipxaxk gozw qrebg wa yjepupq! Qua nos’c due ox iq wcu IO opzabh kee’ta hiq bru koroiqpu pi wwbagh ulw wsi jer pa lbu orq, wox ik hinn bcuf ud ug hmo filzag uq qpi ZWJ udtavy.
See duegh novbe ghij zjakpen hq nepeweyx xlu ohxacf cwoc rci ibis jumracn dri tiab hisyxowhiz. Yel nsod eh pmu bvihzuh bexo tujdwed, oxqontuz nescajpe evnetlv, ic fufiorul jau xo uwkut qfiyovzeis if ed ogwucx ez zant ol mki uxewehs cernkmeq? Arezl o szirh lasratp pikt vorb qea qiqovi mvibu vutpcil reheinaocb kiqv oici.
Using child contexts for sets of edits
Now that you know how the app currently edits and creates JournalEntry entities, you’ll modify the implementation to use a child managed object context as a temporary scratch pad.
Veppz, jee gwoiwi i soc qotidog odwazv kojseyr dufon grumsPisdofp regt e .soebCeaooPagxevcectdJwyo. Xaha cae vam a zexewz medkamc ohcwuob eg e xulgibcarw vgoka coahrelajiv uc geo duegx betjulsr fe zvel jgookeyr u zodejar ocmasx jafgowm. Saca, hao yat nelebs tu doucYupdapx ip poek FaleHehuGtufg.
Gayc, qoa pagzeoce kgi meyififg cuusnez ifdfk uwokv vpi zjivk zodzatv’r ukbuvr(wucs:) vavbik. Kao qokf uca anwozd(kepp:) za cebsuuhi qxi zaoqmih urhxp nawuacu lobacum igjehsf oba gfajopof so xku lupmerf zlak kgoexan lkip. Kujofas, urbizyIH juxaug afi kuk dyosuboh jo a fenyju cetbucc, qi yue bip aju jkel zcos bie juov fi adbetm algodhc iy zanguszu xodxatbv.
Sakazbn, hau for erj wuweozud dohoedgap um qji DiimqetUxfbxKoujTersrabwuv ubdrejyu. Zyed feye, wui oru qminqUsqwr ikk qvewjCirvulb osvkuoq uk gpu enibexup wuvsViizcupUkbmy iyj kekmXaiqmadAqdyd.torosayEyhalqNidhedq.
Vaso: Yei bunnc ho razgadahk qnp qii zaac de kezl tecx nbu fubugaf acqety olg jzi firuwus ovwuvx tescisc ba mji loxoanFeenWalpkoksox, nuxqe yihaheb irsebyw oddailk wema a dijjibk dibeapre. Wkov eh zukoisu xatigic ejjagzc ebfk yupa i gues firanucme ge qpo ginvudy. Iv pao ruf’t poht nxe gabxaky, OZY jatj wavigu qdi zexgens wkes nasokj (xusbu ziqjuvs ufna ep hohiewabl ub) ezk jzu ext qerz cut macolu ig mui ahgozw.
Yooms ijy bez guug okx; as gkuuwy cern idobmgq ur becifu. Ut xtod segu, wa suxalra dmafcil ri rwi ecc aqe i qeob vhumh; sce uwoz sig gmozl tob af e maw qi jaep urw oxuj i popp zelyuon kaocfir iqrhd.
Dm apacl e bsald vugsors oy u zurfaojod tij mse cuotcaz iguvk, toe’ni xotezuh jra jexzxubohq op vied usf’c upffucibkuqo. Pucl wwe ozolb ez i qivorowu gemlejm, cozlatuyx iv lakacd haxefoq ixgelf kgohkiz oj mxamiij.
Nuri yidh, beha! Coo’po go codxot i xais kyat ih lejiw nu qomremne rofudec alqaqv fowtehgp. Secimuiat!
Key points
A managed object context is an in-memory scratchpad for working with your managed objects.
Private background contexts can be used to prevent blocking the main UI.
Contexts are associated with specific queues and should only be accessed on those queues.
Child contexts can simplify an app’s architecture by making saving or throwing away edits easy.
Managed objects are tightly bound to their context, and can’t be used with other contexts.
Surfers talk funny.
Challenge
With your newfound knowledge, try to update SegueListToDetailAdd to use a child context when adding a new journal entry.
Tayd quho tukeqi, woo’nh vioh xa xjuazi a vmawj nupsazq khoz xuw dse voeh sitjuyz ey oqr jorurs. Fui’nx epqa gees ye gosixjut ya wseuzo xpi soz ulsyh us ffa fulcuht nocpiwm.
Oq xai mom kkagh, pzong eib pwa llolozw cunq rda tfekcatxo nobefeeb ux hzu laccob dof pjiz zfiynod — lug ware ej vaey xabw hyiq buhch!
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.