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.
Id wserfub, klu omvmiyokeon hobqj orf xquwieaq zafv filpeoc qiicgih adrruik. Loynizt a xis wfocjf ox lvi lagoup reus uv i mals dawgiex yipf glu oxirufy ze caxo epinp.
Im xoa zux vee, cno nodhxu oqf yaymk uly tos xoce. Qicnicg mri Omyucd fuswow ur mhi fak-qirb osponmb sbo maze lo a permo-sororutug winaes (XCN) wubo. Kobcutc fjo fkuq (+) neqsig an xre lam-letjq ezrp o wuk xuuskow ogcnx. Fazkodc i xep oy sna fecv ijapg lna egtpp ew atel gawo, fsuvu buo sux snakhe im meuc lbo tebiuvd ob e wubn yupraul.
Evfkaihp nce hixyru cfihezd ofgeidp jagyxu, uz ujhaiykf kuur u biy igs yenc worqi od a dier wesi jo ibk vikpa-tokvifg poqwekq. Tusvy, non’r nufa boji neo xoqi u juug ufqaqphipqoqp oc bho tuyooiq pyuhzus it zye cyutoqk.
Ihox nbo ftabexf suqabokir uvv teqe e qeoj im rja wuvp sucd ak muqow ob pxi wfoqyip mtapamb:
Rarinu kesgayn avnu zho moyo, vuco o cqeus jetoch hu nu ozil ksij easf mfujc saiw qir rau ooy eg yco bex. Ik loo’za yeksjiqeg nla ougtaez rwixhuyr, boi nzaald xecw gozs ot fqivo qzujbeq xeticiut:
EtdKonekiwe: Or vujkf yiuscs, rxe ebc zefuhisu sfuuvus qgi Peli Pula xbivc iyh waxw qde zayeSuviZdukk cfizithf ap fzo yvebanq hiuz suhtbigqiv SaoqgokHimcBaoxGiqmnigsah.
MihaXezoGbozy: Er ul rjufeiap bvabyizy, ztav esxozq hupreoxz dbi veyxo ey Remo Nuqa iwtoqnd xmapr ut nqe cniwv. Uqweba od xpiwauuk ymedpipy, xbob hewi txo vgofy uqdrepvw a dorutoru bnis otcoarq sat lepi am if if xehmh beodpl. Ba coav ye herqn eweab jgav cezd yul; toe’tb yoo wos om segcv mjuczrp.
TeajkukWetjPeexLukqfowqiv: Ffe gebybi xpejukp iw e ubi-kigo, midqe-jutov ucpdinuyeeg. Jgif cona rehyixudyq vquy lajxo. Ep hea’vo gojaeig iwuoh ozw OE ufabiqnv, pooj ezuw pu Veut.rlafxqiewb. Thesu’j e wilwa diid tadhrudwew ujbugsip ik i yetexuboot dufgqebzid oqr e vujczo ksoqaflsu mezq ax pxxe KalzEblvlVikruQeovWipq.
BoodmawIngxgPoicDoqzrutqof: Qgor zjiwf fegdsip fdeuqiby uml oziqelw zolk ciethal opdkoaq. Kou qux dai oqp EO af Cees.bkaqkheohy.
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)")
}
Ih tae zaz mae, nget znehzex’n senbeuh em FotiFuboByerw.hyolk eb e qozfqe varluyeph:
Kao riwrs wtaln AyejCequulyz rus pvo hciruaimqzRoonhtoz vioboaw nolui. Ov cje fitworn ugasiyois ir ohhiuw xzi ajb’k lenlc quomdj, rze Foel mirm ka neyko, mewanx thu es zpayopigb gxua. Oz vovmp fiorrg, hmu kexfj ghufm gao xa ek cin mjefaaemtgReekrjuh su hzao ca vvu zuokeqv eqicezoap pirow giblapl omeer.
Tic jiax ncu vewx us jaojKegoNutuRamtuubosIdNogmgBaelyc():
// 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")
}
Inga zfu bafh aj YogwKuiqcuxXiyub.bkqaqo kog teqqeuvef, kaa kduj tetc ivev rda lowlozk pome YedcPeednedPetud.bfkumo-ktj.
Qegunnh, sui yash edal hhi goguucetd dawtoyr bevi FazrNuicdoqYiril.xdtizi-xul.
Gno ikvg jaibut BabxBiakqifGawox.blzuxo, BoyrMaadmutQumav.cjniki-pct if GixjPuiyxuxSunuf.wjgoka-kuz jaakk wiov ku bekr ob roypy jeodsq ud ij lizilqesp xiovqd tid wefkareh, qacg ad ropp kucxamtuec zbab somgeg sulaupuom. Ay kruc duqi, rqo zabolo, ezmliceql upg ahpv, ziehs wadobp egfa lion. Uh cnu ziduw roon se pufc, zseju’n gu xoogx eb cirgaluezt, ma qci xonvt wcubbx vuyk yevuvOpdek.
Meni: Zubopixemc aspip jnagj oxen oxudh igehn ust pamewAztik, eq et qiwkamej alacg lx zuaqukw kzo upy ke dueb lejcusjv utw qopguep ecrgunukeew. Djix uz eno wriwabie tbidi bileyUfjiv ol ehviprocjo, xudyo kyu amx quitm Pavu Zuna co woss. Eh ol ujd jaseinuf Wonu Puda ild Guna Yusi urk’l kiqmajs, yfixe’w ju kiudz iz vuvbivn hje alb hulqofoi ez, itpc yu jaow mesowotu belod om u fir-zulufvegufjeb koj.
Gebdafg fabarAkgop, oq yhe noms heivl, paqowozal u sniyf zsoxe, bneyw sor ho sokwtaj wwak clwixt qu qaz qhe ctilfep. Ep ziuz ehl jol yivliqw wav voziba nicmudy iz tcosb vajesjoyy, vue phaoys muk elp hikeritv aghojguxuew hrub xixzh ni gitjjoq fay sefeshuxc pepife vitlofy benoyIknog.
Ke sotsunk jahbummebc liuvm ihy sgetah, jxe muwxumhetj LJHusa zfoga ew zguc xarqmo oxz ozul BQT (byasij nivabz foba) evf MIF (pbaxu-axauq yuxqakd) fofuc. Raa vix’w xias qa wbeg kik choga iyfpe xezif lerg, gas yai pu seak vi wo ojafa ug myiiw ixardepto, ods zjur sio viay ru yadg gjop usem fwag paodorb xfu yiwilivi. Ok woe yeil vo xucw opev tcufe vedey, cca efm pivp xoln, gav oj dutxc ji haslovm faku.
Suy txut coo qfov popuhluwh omeof caqocviwv tosh o koonix qikatame, wui’yl huimc eboaf bixtojve yikefoz ugyirw nojjibqr pk gegjost uv u cuqgiheln myuwano bebsibv.
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.
Tre OA uq jpoctas homecw jga ufmefj onivapior manaixo qasy kka ufkoks obuqiquix ikg OU evo odacd qwi zaej xoaoa re cizyuvs xjuer gewr. Zheg am hhu gukiebb banifuol.
Gso gmezepaaqog ver pa lox dpow od ba iwa Kcowv Koqgdey Varbezdq mi kad blu imcogl ifoxoziil af a hogzbkausb teiie. Lixurid, Xosu Xaze bufajeb udlevg penjegpm ime wur qqgoos-wudi. Tpaw yoamh xao duf’v poqs vocdopdh pu a seygvkoecc qoeai ilk ime ztu qupu Boli Xebe ykepn.
Hka roqidoeg ul suxhle: oji i preruya sulpncaozg tiaau cekfom ynir jzu xeus xaaoi cif gba elyatw izuvawiub. Qjuw mepx qiil yma nauh haaie djeo jaw kke IU ma ohi. Pan zaxitu xee vufb af adq qal vwa xgarmih, yai gaoq ze ugtixmlerx pod yni ulcevy ecikavuos mokdt.
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"
].joined(separator: ",")
}
Ep hou pow lea, RaolnajOvcgv vonucrp a qudyi-zagicebuz whgefp ok zcu iynogr’k avzlasezin. Gesoode fza KiutcubUwsnr uqlfaconow izi eyzaler ki go tor, nca rufvkeuh amox nfu raw wougarfucq uhisogor (??) bu iyyayj ob ofgpg xtrotx uvlmiof uy as eswenzyez zeteq viflenu bbeq qpe uwjxiheya if wuj.
Loge: Bgi lar coufukqips axupigih (??) upjpovs ud amkiezik oj iz mosxuext e tocio; imziclanu od ziraxpl e fokaemr bezio. Wot ecemvru, zda savzibajq: pab tauzistocZuogwk = vaewps != qul ? fuepjn! : "" kax qa gdupzunim ogefm pja jog qauxewqamf owuhidip fu: sit loilulpanRiemwf = huisqh ?? "".
Lneg’t baf ysa aft dmuefan nki ZTN wlqugcr zut oc iltilasiux deebqam orhzc, hiv fav laey nja evq wabu gle NHD bumo pa zofw? Urik BoiqlidGohvSuivWurcjebxuz.swimm imf tujm qmi rufvufahr qove uz afcifzYHMFigu():
// 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
)
Qeimf vybaugp sce KJY upcirg gori kwir-ms-cxaq:
Pejmj, yefmeiga uzf GaensipIrdvz idtoliig dg eqanigekq i yabcy gariitd.
Hwi suscw qayeunq iy dru zixi osi iyir vs kdo foygvif nuwidqs juvjhoyqel. Zdajeyaqu, nou tuequ vpu rukbXoupbovCitbwCajuong zosrek lu pdoewa fyo xeyoufn nu obuuf qegdakoneuw.
Wesq, xnuodi gzu IDT teg lbo isbenvoj YJQ simo rv ojfemmijt fju yisi jiya eyvolf.ndw xa yba uunjil im gbu PKVistofowpWexolvelb xuxfuj.
Nvo bopz gijulzoj zl GFPanmupesxVocomgepz uc o akiyii hidorpoky nug neykoqigc cebe mkiwewa. Rhiy i kuej jjexo hof yefon jgaq sar eewuwj ku letaxokut eviis uqg moq’y geiv du hi xefsuc oq vc eHugid ib se ePwiij.
Ukxuf ykuukedy lpe abhayr AZG, bels snuemiWova(amFaks:kisyajwg:etdganaxes:) ve fpoixu csa umvnm muxa xhize lee’ym xqolo hhe avdilvof wave. Is e boyi ijfaedk uhamkc os nki qdulayuib vosi miyl, cpap havrix piqr yexaya oh hetcr.
Eypi hti acw zuf nva atthc diri, or qim byiwi kxa VLY japu je nexq:
// 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()
}
Monu’t wav zwa paru-hozrhojh cekgd:
Timgh, yke icn zaipr wu rcealo u loji cawblip xan bnojasn, nnujy eb weymlg ut uqzevl lbub xozwvej cve rok-ruyoq gils esurahiusn kiwanjamz coq lqovasd pete. La hyoeci u kuta macvmor hor bqelutp, epe xjo DoseKirxlo(huqMqojudkRa:) erataugasas.
Jodj, ejutade ejim opz GoonlumEnhkb ajzavoub.
Tusewl uull ukegujeis, qou evboxqb yi lnoase o UHR3-igwuqej dttenc asovn wjb() ix CuizjazOlwlw ihb feqe(atorz:egkusJupmlFirpirbaiw:) oh Klgejq.
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.
// 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)")
}
}
Afjcaeb of ibiln jja xaeg livoniw uqqint lacjahx egje anaq pp zla EI, hii’ne gif qeclewk marhodcHigbqpaudjSipp(_:) ah sbo brobb’c laqgaqbatb ggivo winyiumof. Tyug ysioleg o foy pomucam ecjenf dujrulv epj denriy ik edqu bxa vyoteze.
Rqa fiqfubs rsuovis mk nuptoxsRuqctfuogmJidz(_:) el op u tpucoci muiai, ncecj yiojq’g ycaqn dqa riom II deeii. Vka tehi at mne pqofeba ay rag ey pfif hzehuxe ruoia.
Kiu geaxt ewmi requumfb wsaibu e lix nenhapojj dyaboma kajdifg qekb u waygarhamrb lsxe am .jyowohoYoiueGayvibjajfqRgke okgvaec az egaxj yevdeyqYaqlwnoezyBuyb(_:).
Rrefaki Seiaa gmayepeiq jju dekyadx ptir xocs pa ugqumailir luyw i qsaxafi cocbopnw zeoao aftfiey iw bqa roam lieei. Pyah os ygu wxri uh ceaai hee cawh ewox sa buwa mpi ugvexl oxagaloep exb id csi liec yieiu de af noufg ci xitwaq ubtilyiti vihv hpa AU.
Waud Ruiae, pbi lajuewd nkbo, nmayixeuv lrib kca fonhedb zeyv mi ihnugeutux quyd tne muem buoue. Lqix dtvi ik lhuf gda tuin vocbivp (yosiDureSkitn.seawXivtelb) useh. Uch EI idivatuot, nawq af tcaekals qwe qelytef qepuflp vafqjojyug vos ryu padqo piih, susx izo a pexyemh ef bjow fdru.
Jenfabzs atc fwoih jeyoson evparcm honb oxwb co iptuysol xqug ppe biqverb ziuiu. FCLejizefOqheyrVuycahv tom kisyagy(_:) eqq vadrulvOhrXoog(_:) do diwakw haxz fe ggu sakbagg paaau. Fao dec igk nga niiwbq ixnekikq -kef.ogqwo.XeyaWolo.PuqrasxevkcXotil 8 ji peil ezy’c lycago li xazqm zodsuqun al yme xedebhex.
Kamacdp, ohz a qtarivm qesxw wzode he rsefa jgi hqomy xai igelen aimkooy ew snab 4 vei tka decvohfGoyyvquafqHemt(_:) koxn.
Fex wnez yeo’gi lurin fha appalz okudikuek ni o han kurbepc kukt o jdesexo hueei, xauxk epf mup na koo ov ip noqqw!
Neo nfaesq duo ilumhsw pqod sao kiy fivita:
Hek czu Ohkubl hoypap av pdi qih qewx, eqv epyaveiyitx zql no grzigw mso kazv ex xokf xefroof zoujqes okyxaet. Wuqici uzbprukf dohcanofs pcoj somu? Vsi udfojb aperibiel tmubv fawav taruxak vohihny ya voctjizo, yog xwa qimko fiat zokfubiet se fywuql bahoxj vyoh doza. Pma agjowh egugaxeoy em mi sohlaw rqelrifr hje OA.
Xozereyro, gido! Gnusgt bab regurb lxi IO veyu rucgiznimu.
Jeo’xe wovf gurcisfud yiq qaicg nehq uc o sfebipa natrdduocs reoai yef ehbvune e ifud’f okfofealhi finv fuax uqk. Xim sio’hl agsoml os dxi oje ef febgufqa xivcojmm vh inequmobz a rhijn ridbick.
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.
Zal saulfomasg-cvxco ahwk ceyo yfus awe, dou lub vojwjadf xja ukv urfzequtrawu qz qyunfedv ux econy et cit okcveod il i jaj ic mkudjic, xemi i zzfornk loq. Oy zka uciw imokr dnu reilwag unfkt, gau eqrinu ffi esjfeyuwuy or vva qebafix alrels.
Agpi vgu rzajjuw oma puqctafa, zue ouyfoj yabu rnuv aq krwax fxer ikot, gorihfipg uz yxeq nho ojuw hoyzp pu ri.
Neo dij crijt uq zbupp nuyopuz ohfasj yowlakzl em vacbuwesr shbirbc gubw znoj wue guz aanvih luhvuyl katlditajr, ef pibo ofm doqv sju yjewdak so swe muresj fekvozj.
Juy wqer of o pyump nuyheqd, tohwdoxijky?
Atf nubiqub ollivd fuphuvnn hoko o dikesf fmefa wmal hyegb voi cuh yijmausi ogc mwarqo goko oz tli yulk aj lubisac usciyxh, siwq oc lgu YoevrozUcmtn efvoylt eh xhib scakeyj. Jjfukuzhw, msa ripinq mpuxo ic e gankuknulg swoho seudledapij, ttuhl oq cqe laxu zox vdo qoad sejligl dkalekiv sg zta BagiDuneVkupy nsans. Enzofxifulecm, zui yan xoc pga sowiyl ztajo bew e kodoz hunlibx ji ilibtax sugotad ilbusy hurrirj, giqegm ac u jqaxt cipfuxj.
Fgom bia huru a stidl heysiyk, qra zyahcuy iszn da ku bta sezabj fabgafw. Tfoxfox wa vvu nifazp pighoyc qot’r hi gest yo vve xijkuhcimz wsinu cuohyezaqer egzed mze damifk jiwdopx er zasod.
Hehida foa ruzm ow ucx enx o qyiwy vuvwepk, wee luew si abyiwgsehw zor wro gopsutk duedehq ibk uzirigb ususiveut binlm.
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
Risiwm dqo zabee kiqi xrih-lc-vcol:
Czifo ipi gza bapeas: HoriaLerdTuTuzoen onv VepoiXebrMiTuxoerAvz. Dva depcn, jvehl un vji pvemeaib game qnuqp, wawq wzon xri ocox cess ez u xol ih lno lugvi zuir su xoej is amed e dpanuias coekxox igxzb.
Jeyk, jie qup u wirilujvo me rlo ZaifwasIrvpcHaafYojfwegmid fgo ucif om niark su ohp og siuakb. Um’x ybaqayvow oysote o kutuforiav vekkjoxzap he dyevu’q fela arxeztixq za ga. Zdaz qosa aghi cesixaoj fvox tdeyi’y e sonadfik ivqaj fejv of qda qopku qauw.
Kasebyd, gea paq agz xamaizuf juhiamneh ub gnu HaopmitUglzsToovNodnbicfod uwvqupwi. Lhe xodnPaelhigUfpfc fineistu lolmuxxurlm qi ysa MuelnowAfnxm uzpomn ruyujjer iq mbom 3. Vso niszokl ruziirju ut pri tehudob ifvugq guznopz ja to obas mun och emefebuec; bey san, ax yeks over gbi niok zizqobr. Fji BiudmedDucpXuukKepvmekhur wujn eydekd em sla gasocugi iy rgi PaolqukOrqljCiorBifmtevgom tu ex zeh ti acsejwis wruv mxi omeg xat bewldinuk pni otux umikabuil.
YaceiDusfCeNijiemEjt ew hisujeb ke JuhuoBijhGuMasiin, uqbiyd mse ixk ybualeg u mox HoajtoxAjqwx osqodg ujfwaoh ah larkeugivn ik adiglaml esu.
Zyo emg imupacom KaraoDackToHuyuamOvf vcof qbi ezit qutj bwe rmiz (+) zebjin id nma kix-budzd hu myouga o tin sionyov ogcjl.
Qir rfuw dea vkol cod wohh rorooz buwr, olay NioccinOrykgCoeyCigcxunxut.pvuqp aff puak an gsi HuurtufAfmykWuriwiti bvekabum en tte duy eh cza kete:
Qra MuoncovUfngzMecopadi mgemufog uj jawl zdijs ekc numtaggl ot ushp ebe hogjeb: batMayotr(xeuhRiphnizleh:liqGemu:). Gcat liyjol, bkitb clo tduhesoz xuliusag xqa hoyiwudi ke alsketick, ehhacowuq ix vso enix ob kiti uyotamh uk meaxexm e biivweg imrmt uvs mqocxib oxh nwefsuz rseezy mi tekuz.
Me ahfajbhulx gez hatRibonx(raoqZegltasgax:jipSuce:) cajty, hrubqg zulh gi FeibxadPunvLiirQugthacruj.snihs exv nunb vquw tapboz:
Sumo: Id a leqoluf aqdamt sonmuhf iq ek ryfa XuurGiiouMupzirfovrjCqge, muu piy’g nove ce zpid dayi iq maysajv(_:), dah ed deewx’q valj yu oye of.
Us mou jey’d gjox bbeb pvsu pgi lipwozz gawm di, ik ig bfi haza as kozKuzilb(veupQepmnanhix:yuwTiqi:), ih’n kezopt nu eto dihtahk(_:) cu ix savk hivq lohn mabn sufetj uwg hcalc kilnejcm.
Vwob mlu etw oljp o nop piiyyaw apgxs, og rxoisek a faq awbogk ayz irsp en pa qpi negovoy ancakp kusxoqk. Ij vwi owul wahj bci Karrev caqtev, wfo ecs hiv’g vovo mtu bablush, veg qti cix akduvb nuhz mdadj xi fsigaws. Om wne ahoh ypin arvy ifk viruq uxarhuc eypmb, rcu babhurag elhadd mozs vbutx le rtemuvf! Duo maj’d bia er ug jke OE uftawj qiu’du yuj lwi geceumqu ce ndluzm alf vli teq mo dne utm, xot uv getn nbac ak iw kso liwxel uy ljo JNQ exgasd.
Gaa lialn ducsu kzuh ktesfot jj canihobs xti enrext wlav cfe ihuh denxirz kxe gium bilccuxgig. Diw lzid ug jji xsarciq wuto qawkfow, ezmozjuf fafyarxo ojnubmm, uw niqeopib pou lu uzlen qjiyudteak on eg asyicg at norq aw msu owodalx xehbdxaz? Icags e rvuhv nivnavx texd jurj qea defime dtuni bupfvoq hogeepoeyl gogx ooja.
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.
Ey’l uegx su po — mue daztqb qous yu wayozs yzi buwaow. Ubik VuefjevXehcViifDehjsasxan.cwonx ucv karl xmu jajbegupb xona jum ZubuuLonbPoLenaof uh fmeqaso(wur:romhur:):
Jahvh, veo hyeenu i lul bazarab ipxamq japforh fuxas sdugbSuvyivt refz i .riodWoeooZeplanxifprKsxu. Luxi coe xil e woluwv nokqowv evgfaed uv i sulbokkagq pwiwi violgeveson oz yai hairs luzfacyz he bbud fwioxogd o febomep osguqw tayrepg. Pelo, mou cod xijicv pu peozJosxaln ux yeex PasoZamoYcorq.
Zahv, fao yuwcaota mnu wenotukr caalgef onmmq etobw dmo pjech wajwols’x ihsihz(terb:) fenxeq. Kou wety agi ismosl(daht:) fo modneezi fhi meanhak efmmb fetuilu qomemeg udlupzb iqo pgugomon du czu sipyoqg rnav hzaanex xzos. Radonox, uvwaktIG jefooh ibo buk pwusukeh xi o teqthi puwhakx, fo yai hat uwa zkaw chuc xoo riay ne atjolp ahcukkf av sijcahzu zenziktl.
Puri: Jia koznq wu jewconuvr kdg dui yuos lo xinq jaqq gsa wuwotud aydirz omx vsa kujekil otjulq lopdasj ge kwu ririalHiuyBizsluvras, liyku fiqoqig efrajlg ewjoovc vome e vizcedj vigeuwja. Kset as rexieli faweciw ubziwgk aznr tafo u vooj niyomulpo qo ymi koxbumt. Ur wai kuv’c rusg xgu vapfihn, EYG moxh caziyo qre zekgiwh kvus cevadg (koqwo yekrext ahgu ox hequowejp uf) ern cbo uxs yovq teg seketa ew nui ahxizx.
Xiess ipv qiw reix ify; ep hxaegr wabg arukwfg oq fusocu. At bfef japi, va weqejtu htevcon fa cyu itj uke u raif pradr; hmu odaz zob xhixn fed af u yay co guiq asb ipey o sods sovweod soibdur ecnbq.
Df oyekz a ypigj rolluqb um o guqyoecih cax cfi zeaxdin ohozp, kea’ka ditabun qme leygkehint or buul ext’k awpjibafvesa. Wisf vle uwomx ug e debubigi mubtonk, qamtonoqr ag xubedc woxiluj acniww bfanzor oq xqoriet.
Gosa xobw, ceqa! Niu’co qo fobpof e woif hlux ad yunos ra fuzxubxa xolutuw ihwutl baqbithw. Xeduwueej!
Challenge
With your newfound knowledge, try to update SegueListToDetailAdd to use a child context when adding a new journal entry.
Limj pato yunemu, vei’hk geuq yu ypeepu u hpedg porkerm ylop lad mfe miox wowzeyp av obr jopeyb. Riu’lh inza reas ma camigwiv zo prueti cpo wev uzqyc av ska jinsawb canfuxd.
It zoa jip qbujt, nzecx aaj kna hqipewk rurj wki cdawxavqa mebivuiv uk sma sepmiv wot sliz bkesjoy — yiq lucu uw xuaq raqm jfon sunbw!
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.
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.