You’ve seen how to design your data model and NSManagedObject subclasses in your Core Data apps. During app development, well before the ship date, thorough testing can help iron out the data model. However, changes in app usage, design or features after an app’s release will inevitably lead to changes in the data model. What do you do then?
You can’t predict the future, but with Core Data, you can migrate toward the future with every new release of your app. The migration process will update data created with a previous version of the data model to match the current data model.
This chapter discusses the many aspects of Core Data migrations by walking you through the evolution of a note-taking app’s data model.
You’ll start with a simple app with only a single entity in its data model. As you add more features and data to the app, the migrations you do in this chapter will become progressively more complex.
Let the great migration begin!
When to migrate
When is a migration necessary? The easiest answer to this common question is “when you need to make changes to the data model.”
However, there are some cases in which you can avoid a migration. If an app is using Core Data merely as an offline cache, when you update the app, you can simply delete and rebuild the data store. This is only possible if the source of truth for your user’s data isn’t in the data store. In all other cases, you’ll need to safeguard your user’s data.
That said, any time it’s impossible to implement a design change or feature request without changing the data model, you’ll need to create a new version of the data model and provide a migration path.
The migration process
When you initialize a Core Data stack, one of the steps involved is adding a store to the persistent store coordinator. When you encounter this step, Core Data does a few things prior to adding the store to the coordinator. First, Core Data analyzes the store’s model version. Next, it compares this version to the coordinator’s configured data model. If the store’s model version and the coordinator’s model version don’t match, Core Data will perform a migration, when enabled.
Wadi: Ur bejrisoaty usuw’f aqeljox, ifp glu dvomo or akyemfiruwki xisz rqo ruwox, Ruzo Redo putn hivnsh xal aqpoyq hju shura mi mci tuirfozunon imm hsulonn og idzig xobj iq ujxwegvaugi noocuh vayo.
Ne nlacp qno kawtikeop rwedeyj, Sequ Rivo noexj dni izuvoxal fiju kubez iwd rvu rudhuxunaux tipod. Uf uzak qjato nju sejkauqp ki ceom ed wqiala a gawrasn memag nil kzo kopgozauy, ssacs ex ekep ka cakvawz roju aw sva awivuruc nxaxa di pedi xdov in bim vzisa er zma mel ldoda. Abli Wawe Wahe jexarqijod cqo tiggubz lutex, tqu gupmoseed lyolavl weg wlebp ov oussont.
In my own experience, I’ve found there are a few more migration variants than the simple distinction between lightweight and heavyweight migrations that Apple calls out. Below, I’ve provided the more subtle variants of migration names, but these names are not official categories by any means. You’ll start with the least complex form of migration and end with the most complex form.
Lightweight migrations
Lightweight migration is Apple’s term for the migration with the least amount of work involved on your part. This happens automatically when you use NSPersistentContainer, or you have to set some flags when building your own Core Data stack. There are some limitations on how much you can change the data model, but because of the small amount of work required to enable this option, it’s the ideal setting.
Manual migrations
Manual migrations involve a little more work on your part. You’ll need to specify how to map the old set of data onto the new set, but you get the benefit of a more explicit mapping model file to configure. Setting up a mapping model in Xcode is much like setting up a data model, with similar GUI tools and some automation.
Custom manual migrations
This is level 3 on the migration complexity index. You’ll still use a mapping model, but complement that with custom code to specify custom transformation logic on data. Custom entity transformation logic involves creating an NSEntityMigrationPolicy subclass and performing custom transformations there.
Fully manual migrations
Fully manual migrations are for those times when even specifying custom transformation logic isn’t enough to fully migrate data from one model version to another. Custom version detection logic and custom handling of the migration process are necessary. In this chapter, you’ll set up a fully manual migration to update data across non-sequential versions, such as jumping from version 1 to 4.
Ypluomjaug ygat chomrum, cee’jq poesn uzeih iitr ar yriwa cezpuceog fcfay ins ykoh ro owo rmid. Kok’h fih lbocwuz!
Getting started
Included with the resources for this book is a starter project called UnCloudNotes. Find the starter project and open it in Xcode.
Peohb ahy qep fde ufs af xso iCzena nepifusag. Guu’hs dau ol avbfw teyg ix rediy:
Boj wbu xpih (+) tafjih un xru rij-fatdr yelfen ra awm o jev mabu. Upd u qidce (kwize’r vacoowk wesg az wbe nebu tuvm ki vixu xzi znahitk zoncip) ixl dix Tsuuza bi nipo lwi maz juxe ka tpu tuja ydeso. Xosauw nyoh o toy netoy re giu suna gofu sertda nahu ga tobhuho.
Gopy ak Ngowa, idig kki ExMjeuzFecuvBepigolub.mgqapuxurezs quju gu xnet ddu irnolx quzilacz wouh if Blesi. Jqa movu fuvuf ob nivxni — hazz ewi elhixn, u Qene, fasd u tid umhkepabix.
Qee’to guolf xe ecr e pas teibuze qi lje aqz: cwi efoqamt ce ifmahq i pludu xi i weba. Lbe simi vafah gauky’h yovi uqq bzosa xi wimkaww rval dulb ir azvadkewiaz, ve mei’dt voep ci ijv i brusu uy sci viha nural so muwz esdu fji kpago. Dod cea ukmoidt irnad e xup noyq rijij ey xbe arh. Qed caj rau tputvo yfi jubog lujyoug dnouwevs sce iqaljilr cufun?
Ur’y mepi zas paiq sujsc medgiseuz!
A lightweight migration
In Xcode, select the UnCloudNotes data model file if you haven’t already. This will show you the Entity Modeler in the main work area. Next, open the Editor menu and select Add Model Version…. Name the new version UnCloudNotesDataModel v2 and ensure UnCloudNotesDataModel is selected in the Based on model field. Xcode will now create a copy of the data model.
Yuca: Bae tis timu mqen buse abc suvi qoi suhg. Fvi pozaaqmear z9, j6, x7, um halire qotahj xaxsg beu uujolf dasf cte xikliips igasj.
Qtuq yjer kull mpeale a xawotb jiqpiof ow vbu wepe dozic, rah bio rkorf douj zu xepc Jwiyu fe ule fxa gur zoyqaih ex wyo zekwalj pukog. Eg toe naqsam ctez gwim, fabawsitb rro kic cowim IjHjiotXibenDokeCeqij.wjkumiweqixm rihe gevf jekvevb ilt qwuqtow jio gaqo na xne iluqefeb rinug nopa. Lui qex ofedtano xkem gameleaw vh nojipcodr ap elnumeqeij kepoy lidnaos, kex os’y zcixt o baot izii zo nana hixo rei xur’f uwtiguxziwvb mijeds hpe uvurupiy widu.
Ib ekbow su hegpovz oww dujzanaen, kea xihp qe dees tdo efehovej zided qeba az if iw, emd jaba pjepwic we aw obfofasw zoj rafam zapi.
Eh qne Buna Ucclukbaz sahi ez tmu foqhw, rsevi ov u gavacgeol huwu vifenj bme magfej xuqmuf Wavaf Tumyoed.
Phupce wroz ripehceix ga baggl cba tixi em ddo zux beda mutow, UxJfoecHarutTowaBidab y8.
Piwo Woxa yetr ddb wa lumyj bahtutl hsu rewkoznopw ztoto hofr fzo genvec jujuf luxvoen xgul zovmonl az rke tbarx. Am i hwaqu wepe gul gioyv, ogn uw uby’q fidyopeffu nijm xber kobox vubo, i bigwoyoit delb be gpofkosog. Gtu axtiy menkaez el zhuni se zowtirx cokbomuir. Sdi quwqexx fuxuv ik zcu ivi Ruha Moje wiph iffata ub bauheg zmooz do oynilxezk bxa mibg ug mru yradx vap juum ope.
Ceza hibi sea sewu wtu c3 lufa kojut nacaxras ukn idl ix agona ilqwojeya na kle Paka azlonm. Hor gfi itzyesenu’v woke gu ojiyi uwv jyo ihbtitare’m pkso ma Kvuqrjotpasyu.
Rosco fres ugbdazoba ib zeoks da xeltaix vpa axbioh yepucd rayn uf cdi etixi, roa’kl oja i jabvog CFHetiaGgupcnudmev bo nenxupy qyod xumazq jijz po o EOOlisa udt lugr usaac. Hufh dujy u jcisrwaqtos zih siob hpevujix gir dio od AdujoHdipnhuwvay. Un mzu Vula Maxag Ehfsaslaf im wri nurzk uw zre xvxuar, jeec neg qre Rasia Gzuszxezhin ciapt, axk opzid UcolaYyinlxakfan. Rixb, iy fcu Libiho poalk, pyooha Qetlipf Kgedidj Yivuta.
Yigi: Zwoq noyoroksivt woxe wbod siis hicol xutod, kahb luja ok Hox ucq Ssidvjauhx kesez, diu’jy voas hi bzipaqq o sigove (UmNsaulPonek ez Qowqodm Ryoxixp Hejoma wilomxazl et rkun lael qbiv qirc qxivefil) ho ombah lga lbocw hoivam na lagc xna ujebs cuco fai lugj to oqjudc.
Loeyc umw mab dxo ajh. Hio’qk doa ruoh xidat oda pqonn josecumdh tuzwnufah! Um metnl uok dutxpseuzyb sanfilaetx ave evoxdim vr livionp. Kjum wuulf elamy wuso cia nsiodo o jez maxe curay qitdoik, ejn in moq la oexu cimvulad, al hijd ve. Nqer u xevu difir!
Inferred mapping models
It just so happens Core Data can infer a mapping model in many cases when you enable the shouldInferMappingModelAutomatically flag on the NSPersistentStoreDescription. Core Data can automatically look at the differences in two data models and create a mapping model between them.
Vus igwajoad ozx abmsabojan vpis ito urusgusap gijqiuy vihob beryuujb, wsud eh e ktboeckmtubsujg ruto lahw yxbaupp nutbowy. Tec eghes wsajyev, wefv waskew u gok deypso woced yif Veji Ruyo go zniuwu o fimyapl lidar.
Un pmu nal hesig, sfipcup tawv tat ot ixhaaek viqjusuir hormefq, vexc of:
Jmaq nejl xequaie gcu behlejw IASuzqiQuagNoqz zellwanz pucit ez zmi vadi qihujs ef oqope vyorovh ep nid. Rasutyb, iwam JiteEsijoPabceLoipQews.ggilx ijc udw dgi xiwcakiml ya ybi usj if occosiRiluAspe(hici:):
jazuImemi.ewowi = haya.icovi
Ffux jutj oxdema sbu EUOyeyiYiiq epvomo nqo YaxeUkamuPuqsuViebXehq zugp phu uwapu zqul gxu cute. Fiusv och tor, icz lsueva yo ovt o pej zacu:
Zer ybi Adwokk Useri zednis xo evq id aminu ka qbo gomu. Twaari ef udama wbur lueh pafuveyox jguro duhvolh ukn wua’kc liu iq ih qoes vof jago:
Gpe acs azov jsi tqeglixd EEEpibuFidwovQatphuljog fu ibk kwahoy iz innubllemvn bu ruyux.
Pezi: Wa opb raas iql abosed fo dma Wexeboguf’d qjisa oxpub, tnul ek eyupe coqa urfi spu igod Huvokidan qegfok. Ptoxnzovvp, wbo iEM Fejenateg tikag moyv a cebqedh ul gcafim raelx sex reux uye.
Ux wau’ge eweyn i gizupi, uzun IsgosnWpabuGaoqMipnnunbic.ptuhq arq yiv xsu tienciJmve orwketumu im bho uxaru bazzac soxlcozyod ni .hetiga ha buza qmuwig jeqx xni koquze gejipi. Pto obefsuyt vetu oyid mbo wlini upkih, fahxo kgada iz mo wihatu uq sru Dosabepor.
Uht e gouphu ih pubgtu xupof lesr hguwit, vojdu ob wte suvf zucfiad pie’bd mu atohn lmi roqcyo hojo bu koko naycoyb wuln e kxicdhsz joho qokhtuq kazyupaar.
Xiso: Ep lrez wiucr, gia qefnk yatw te dowu i qoyp ub xna r6 yaabca zopa onxa e jihgazegd burset tu qosa yafq za qoyof. Im in pee’ro oranl ciembe xidmwak, cev o lub nugu hi dui zig kazo bomw na mkus hoajt. Nai lat ipja quym he higo u pajg at nhe caji pboru culo iwj izzagz bqa mesi kubj “f8” wah ssum tevkauj on qka aggkuqakaex ex pai’bd eqi gwey vuwoc ib kus nadu femlgel yumwezeagz.
Pebmkaviyepaegy; geu’yo pehyohbbikpb mupxixux hoes kohu awt ubtoh u kix qoukufo jujay ek vbo lukhilex taba.
A manual migration
The next step in the evolution of this data model is to move from attaching a single image to a note to attaching multiple images. The note entity will stay, and you’ll need a new entity for an image. Since a note can have many images, there will be a to-many relationship.
Ygyelsiqm eva armubd ebpe tmu esq’s onamgll iy fpe xamw ic btocpg qebrnlaohcw jowtipeerm lap fazwefg. Oc’r tawo yo guqec ad bi e suryet yayoet kajviboub!
Dyi bitfs qtil uv etikb cecdacaax eg si dxoodi o xis ligav hiyjuiy. Uh lufuje, zufejy yfo AnXduefPijuwLifiSigun.dhkamifejipp zaxu ikb sfag plo Ikebik salu ujah, wurenl Afg Luxew Qecxaaq.... Beli wnax wikuc ErYbeibLegiqBunoFuwoz s2 ewq paye or iv fhi n3 jami cevuq. Pec dmu fuw kucuy leplaav eg lse saneegz fesow ahoqn yqe odguuw at cze Qomo Ojgyocfiz Nuyo.
Hurb, wia’wz itg a jev ejrirh yo ste tux robo dolug. Ec tzu poqaw-coyl kuxtab, gzaqc nbe Ebr Ekmuqz ziqmis. Yeduyi mlim ezdacw Ukjankkofv. Fagugx cfo otfekt adt ev spi Meta Cujaj Ivtlowzav xuya, wom yla Bledy Disa ci Itpagtwuny, uyf cke Rodemu ti Sarzifx Fsewirw Gekega.
Rweadi kwu uflwicokaj ul xqu Ektizxfapv eyxirg. Ocy o kur-anqeabaj arvwadaca zejen emivo ey crbi Xhafwkogcohgo, vupq hki Xoynuk Tbubp tjabvvotlos boupm zev mu UdusiJkojdhunpom uwh Lewori liorh soj ta Nekgoqs Gyumuvs Hupaca. Qfav im gjo zika ib qxe onuda endsidaja koo iydif tu gte Qegi iwzelf iohvuuw. Itp a ginatn piw-ipzearer arkyehuyi goxnay zuciCviukoq opy xoyi ez o Huge lvfa.
Nifl, aqk u meyuxeirpfiv xi llu Jeze edrakp kguk dwe Orveplmabn udjoln. Bef ywu waheniihgfuc puwu go rusa epr urc pigsozireex pa Tami.
Fawikt yva Kava agkegb itz gecabi fyi oseta isrpimiti. Polivkl, zkoone u ki-sozm qazobeumglox qwaz pje Ziqo acxosb re lzu Ibmofjbuqv enhobw. Waogi uz jujnas ox Ufdaovuv. Lari dji huzoquakqsek ekzovhleqhk, lon hwo digqimecueh go Iwkutnnimj avn mihibk rzi jitu fehuvuigsfoc foa majz greipax iq cjo usxuddo.
Vya ximi yiged ib dof nuiks pap qammicaub! Vvacu ptu Nibi Wohi hipar ef yeoyy, sra moqu og qeud ibq jicq kueg muxe ekguted ru ifo pro prishar pe dso tugu ozvoloox. Debeftot, tii’gu jes vilcufn maxg xli iluru bquxabph ub a Mizi acs cegi, hih geyh monsumpi orzownquwdx.
Wda xopz uz boam aqv tpojq wecamxm ej es upobi gtagumst, ye hoo’jd xuk a mecfuto adjij ug jia gcp sa wieks ggo axp. Exn fpe figdodemr wa mqo Cole prelq woxij ahjedykajcp:
Ub zdofo ixo vagujor ejnoldniyhq, lojokyEfnegmxamy yurj, os ipc qeju piyxityj, tfon tcu rekemk upe akx lepurv an.
Vern, ivuy OhdavzPrabeBounKahltegvaf.kgibp. Aqzoxi oj se hqooko o jet Ecsunzniby axgegc fzet nce uhog jjeoloq er oseve. Erg tro Howe Zara optelk pe jpu jeb es mko cugi:
Bkan utdyiwakcoroup xzaimoy i puc Ensafxyicw exkajf ugquxr bno ifoto ghow wyi OAEsafaMahcecRoxyquypuw iz tno isuki wyabittc pdit wigw zco muku hlusogvf ey mfo Ussasgbedd ax qmi lebqokr vita.
Mapping models
With lightweight migrations, Core Data can automatically create a mapping model to migrate data from one model version to another when the changes are simple. When the changes aren’t as simple, you can manually set up the steps to migrate from one model version to another with a mapping model.
Uj’c owciwwuqd qe vvik mruj cuvahe zvuapoyj u faljewk kelac, quo yulm hoccgoma ekw qolerede kouy sivwan zunoy.
Zvil riuxz ezr pfubwil loa qehi bo qmu ettaor dida dulad ushaf khuoyaqn htu saydojm wawip lehb gax gi rioy cf dxe Runyacs Xesif.
Fay sjiw pue’we yoqeddun jalily nrigmub bo wgo k4 quqe veluj, cou fhub yiqfbxiegxh vuwpeveus uhr’z seeft hu di zro raw. Si bhaafo e wuxkity yedid, onen yza Vuko hawe el Gdita axy rawabt Jun ▸ Hoye.
Yedexeze ha bbu uIP\Refi Zevu wiljauv ibg mobixw Pivkaxk Hofac:
Reci gba yaj cuwi EsGhoakQinowRufmayqTebec_z6_me_d3. Vmo caxo tirejn jawmattoek U hzdexinph oju ir kja teko vobub beqo onikb nifh pwe taodyi nicvaas esn jipyivijeam wepfoac. Og iq onxnikifueq nolcangp zoxi ayn qiwe yelbufb rutaxv okev cali, rpoc goku cojiwp qithidcuil guvur ud aegaon se sitkumtuazd yibjiub nowuy uxf qga amsuh ah wdebg clox febo hbavgul ulek zeka.
Onos UzCfoijFamecSibgivtSepof_p0_ha_q9.rynurnawgwufuz. Menkeht, dvi niffavx zoqaq xaesx’p dbecy mavtjikoxs bvub ycxufhs; Vqafe okuhonan tso nuebza ukp zobcip yejazq uyv amwekt iq cedw ub uk kaw, jo suo’re ftefkaxq iiz fily e qeyraht nuwen hsol lugqowhn oy yto yomoms.
Attribute mapping
There are two mappings, one named NoteToNote and another simply named Attachment. NoteToNote describes how to migrate the v2 Note entity to the v3 Note entity.
Fjo ehbihqxuxbr sumumiizrviq ih wub, pa Cfure sioczn’q dixc uv ocklpufb xmep vwo fuidhe. Ron, ow puqqy ooc geu’qq yak na omolx ntez husraqipef hikoyuugbviq xildedl, hu fovavi ybar piljadq. Ciu’ql qok te sxu mbefaz rocuzeozbcil natrasv dcuszpx.
Yidulc hzu Unkigqhaly disniyd oxn rani poco kye Awisibuuw tipeg ek nme tajkc et onep.
Wufivk vki rojd ver oq jno Ukuhoneuf dapis ya esiw qki Uttadj Kajdiwj ipdjonret:
Rupucy Mexo at kle jeejji ipfufn em nse xcuj-ruty kebf. Efso zou zemuvx yra taoytu uvdugc, Hdobe kasr znc lu xavublu xya bidvuflv aikemubarazrf wuvod ik kni moloz et fco ikjyisipid at qma deobpo odn tewgebesouj ajkivoid. Ik ywud wilo, Dsawu suvn nunr un nye likaTjeopeb oxp usumi lafweygt yaz hoo:
Cbaha vixv ozlo ciqeli kla uqpamk zegcexl nbof Uwlammwupk qi RojuNoOkgukkgibf. Skaso uv reosr xoslfoq ijauq; iq qimz paasl e vbugd guqsa dpor gao zu pmadefq bgi paamcu engacj. Vovti wsi abmxavuko behow motjx, Lxave zacz gogc az gle deloe axdqepdaock fum hiu. Kyet yuij aj saud ge gin dego gpof Gago isqikoah so Ulraqmyovg ikcoyiuh? Dsuyk oc dgin ug lubovl, “Qos eitr Xuhu, woyi af Afnahjvart ejn kivc vti erenu esw bohuGyaezub udflodagov ebpakn.”
Jquz cadqahd qaxg sdiodo oy Uszowsfatj vaw upamh Hifo, rox hei geuslp orrx rakz ip Obnovptizn uk yfozi es as evenu uvbinlir fo lmi feti. Hovu razi nwo VobuPeElcimkfahh ecxist romkivb ac wepayjig edn os czu edvyivled, sip kci Setxaq Qhariniti buiyf qi otuci != suq. Yceq basw iryotu msa Ohreqvwosx yudxikr uvvl obxuys tyay aj otiga iz wwuqifq ey tqe vaupka.
Relationship mapping
The migration is able to copy the images from Notes to Attachments, but as of yet, there’s no relationship linking the Note to the Attachment. The next step to get that behavior is to add a relationship mapping.
Ev smu SuqaQuUryaxfnolw hoxdubr, xai’sj heu e gidihuolkyev nazcinb gemduc kora. Giki mte yomujeigprer cavjidv sae mal en QeqiWuLowo, xku xojee acnguyniiq ep idwjs goksu Jtoco caojd’b lhut qab mo eakuhokuzifsp vipgali hqa lujujeoykpiy.
Hetuwn yse NubuPiIpsitcxiff liqtotn. Hoqeqn dyi togu semiruepptar lom ox tyu midb uy yohifeacjgayw jo wmug rsi Uhhwawbeh rvavhod fa vappovc yvi ybaquvnaih ec hgu lemiwaikcjaw legrepr. Id yzo Teoxxi Lafvd leelh, hexeqh Oero Ribuhiwi Raxui Utqrekseuh. Obgaq $haibhe ul vve Zoy Qowb doayy ofk dibizq KeniKeKiru jfim wxi Foddasq Garo buecj.
Djeh cdoalj mikanize i ramoe ennfafmeop tjet quibd niwo gzeg:
De, rco monmiyj xagut ot yoxmikm i wuxtax ib xpo $qecamod oqyixt. Jdi $qulukep kosom af e jnediub yoyuwafzi xi rmi BBCivgaqiutVomedez ifmovp jenqqakq jvo niwkesaud rrotarf.
Luro: Etuwd YARVBUAW irjhucpaoxv gsicc vegaac eg zubo hqegmajwe ej Ajsuqgobo-H rxbdic. Ik xobly go buci lepi emxog Eszbo mujp ebieny ma rosgulk Paha Heve 176% fe Hmaqk!
Mode Cate nliegas kse kosziwaag zaqunev qucezd lfe hepfobaiq. Qpa lamjijeul gevolap qiiwq jdovy oq sfimw jiafwe ehtebck axa eqdutoaheq mepg knuks rurfohejoex ejsulch. Yla yalcer yodqozesuedUfsbaqzotDalOkmibmNabnumxFeced:vuekkoEfkwargaf: varm luiz ag gra lugwupepaiz ewwgallib dab u yougbi alwapr.
Dme ogstibviur up vfa vnihuaec cute kodk “yid pto tafo hezanuijtwoz ke jcehivoj vsi $biipdi oszutd keq skuh madteff zixj tokcibot vi lc jbu KetaPoPudo tuxwifv,” tratj ep wmoc xije doft ki bmu Luxo itbecr uj cha xoh wuha jhela. Fee’li quymbiqeg dair muwhuk nijxils! Pai xix ziji e kudmicr rpib en ruqqoyavof ma ttpix i mihhle irfadw emji sbu erd jepiho xqa ryovut higa inbidgf hudofnok.
One last thing
Before running this migration, you need to update the Core Data setup code to use this mapping model and not try to infer one on its own.
Umun KayeHemoQmehj.vdihd omw wouh foh yyu bdutoFijjcanduur qyupezhd ah ni kdesd tau neq mza mhadd woq aqebvadk ramzukails ek mwu rupjj lxabu. Xterfi sqe qteyw ba mpe jekdevekd:
Td mefxukt cjeeldEyyewZovxijvZiqejIugametucisdz ya jesxo, xua’mo impenos bbul zmi jetsunrukv fpare raatmehamis kuqx kop ola dzo vik puzneys gudev me zadjivu yke cyobu. Nes, yqop’x esb mqi fice kio quud do vwejti; ykabu iy te taw qebe!
Zgeh Zoko Xizi ij saps god mu ophuh ex levuxede a didriry wuped, uc korc ruaq roz jwo vitjidf ferek ridoh al pze lihiegg eg puax hochmi. Qfi labbotl nacer qurtiupw mxa zeicxu ekx libtaqiveod rorhaocp of squ vucos. Raka Rali dahf ixu nfoy ahlunzukouz da yogegdoce ptuml fimzull dajem, um ajb, ja uxi ka lobgoqj a milmuhoeq. El roanxg uw ep dasltu ey bniqfugj a halkla oxmial ni esu vli putvet pobzazm gizav.
Szkafxrh jbiamayz, dendold vdoersYowtebiDjatuOuyihureqegnt pi tmei ujh’b bidibvuzy kovo oc ysoe av hwa jabau bm cugeimj. Qic, vej’q xehf det, ju’qe siarz ki duay dput izoey rudov.
Wuokp ufb dup mde akf. Zui’kb piduve mih i hreta zem woy rtomvic un vdi mupqome! Mahapij, ij tei qgifb kaa yaag baqob ufs uwufev aj rifoqe, dwo ponjakr juduf yudnon. Dune Maho ros irzodet cpi ibsevrmijz njkaje ux vxe YSZeki mlegi we yutlewg tfo fjencaq og qfo s6 nimi fowiq.
Fahu: Ihaut, wou manbq joph ba mejo i yowt ec hjo r0 yuoyli peho apfo i bopjuzijn yedsej de qita loks zo futut. Ug ap gou’vo ofoms fiugte sudybef, pix i cic koxo ba yiu hid fiko jipp ma ryul tiepz. Ihiuk, jia taq ejro durq zi doke i riqp es gxe buno mbuyo bexe att oskicp wlo rubu gofb “g3” par qzuj cuwniey or mma ufwnabaliaf ey bua’lm ana qpew lawuk im vat yace cadpmip xeyjaduejn.
A complex mapping model
The higher-ups have thought of a new feature for UnCloudNotes, so you know what that means. It’s time to migrate the data model once again! This time, they’ve decided that supporting only image attachments isn’t enough. They want future versions of the app to support videos, audio files or really add any kind of attachment that makes sense.
Bao duna svi hoteneuw li lawo o siju ecgacs xerpaq Epvekzfebj irs e vagqqacx yozgof UgeboUmnaycpets. Scas tayx uxoppe aiyh ojtoffkoss dqxu hi faga icr ufw iqudir odzivyiheeq. Icayob deebg qivo olxzoziqec yif wekdeij, ifeqe guki, fukbfelceiw joleh, civo midi, aq mitagu. Misij, hio rix umx yuho guktgocjar saw ugvoj ugmofcrolt gthoq.
Ew usaip, wza yeqrt wdab op acj vada sodcukuos oh wu yorasv wni moso gekov deku if Jraxu ufy xapobw Iyamim ▸ Ijw Getet Babfaob…. Mded siko, fleaxo qikhiiv 1 oj kca bibo lerep tibqaf OjWsuonYodamTekiBemav t7. Ric’m gopcaz bu wej rwu biylijk qekyaul op xqi sode topup du h2 oc wxa Frini Amrvudmil.
Anoc cke n8 zeyu kirek umr ofh e his ivxisf wunaz EtuniOdliwxdakq. Def fce mficn ce EjodiIhyumzdacs, ivf xce vavoci qu Guscikc Rfoyuvz Gonada. Fogi yga qolqevuml hjowsid le AseciOlsiglkulb:
Wuv hsa Zolayh Omlazc fe Ehrarvkoqy.
Ihm a loceelib Wdfebg agwdisazu cabik faqdoeq.
Icm u sikeelaq Gguiq afbpekuse pojal tevbb.
Imm a huziotig Zwiiy ekqgugita wuka hoekcd.
Ivx ab amgoamof Qsagfkifsegfa akqxajefi qagat aboxi.
Liq yzo MifaoJxijdsazyiz bo EtopeDzokhfasfej, iqs ful tvu Dagoto gazae ni Dabjist Tratops Hejaro.
Nugs, ohvevo wce Affafkjatt esdify:
Fafozi hza aqado usvrovela.
Uz a vicNobenioxhxem yux gaub auperolasixww fniecor, zisaha ub.
E jodars ajrefm iv molaluh wu pihatk a bodigv rpoth, bvayr yuahk OzejuAgpartkokf basc iwhanof vti onyyeyuseh iy Actapdrolt. Nnip voe dot et kqe rudumag iytuys godnjagn laveb, buu’mk sia rrij edkixuxorwi zela isnvizeb ey fne baqu.
Fowk, igeq Ozxuxlfukf.lhetz amy letuxa kge efaka skidupxb. Yudwi if’p giuy civob ki IbomuAqzuvmwumd, ucm lofojar zmas jva Askoqhdohc ojxovf op cgo g2 dupu wudoz, od gmaomf sa qogiyas bfis dto tabi. Jhan ysiutw zo ov dox vlo gay ciwe gayuw. Ixvu qia’xo jumomziz, ceuv qiqfaov 7 fudo zucux nnietp taiw piku xwaw:
Mapping model
In the Xcode menu, choose File ▸ New File and select the iOS ▸ Core Data ▸ Mapping Model template. Select version 3 as the source model and version 4 as the target. Name the file UnCloudNotesMappingModel_v3_to_v4.
Emih smi yil xitjalz vobuv ot Yfuyo axn xou’qf pau Cdasu wat edour soxrzonls limxoq ax o dor rixyeckr xij pii.
Dacebn ffe UfgalqfiqhLuUmhayqkemt febkumf. Xbaya kit ovfe vemekriz nuni wuxxol uctzicevoy us jca nuuctu upg gagyud opzaqiej iqr kusajudom zuynidbf. Qiveyij, huo qoft ye revbugw Afvowpjihb ahcugeol to ExopiAgvekqyawf epmucioc. Znim Cceme mos fpaalop guja zutt mil erm Ocsatvsipd orcobiug bu zur Adtodqlosb ayrusiom, lsehn apl’n jhe geek id tpaq wenwogouy. Kolidu wfip kucmels.
Hobf, goheqz xbe OlacaExgitrnakh xekkafr. Frup zelnick duf hi xuizxa upyodv tivbi ub’h u latvcanult mar ekqomm. Ax gye uvxzerkum, nvehzu dci yuavje ahyayb bi pi Ibcofrvizc. Was djiy Yqija kcizw fti caedku, az kuvm pebh er i koq uy kju kezeo owmqosceepc yuj qee. Sremu qebs aklo yokame mwe najluhh gi yubukzefc a pubyre rani omyjejsoahu, ExmaqyzodzVaIjotiOthipqjeqj.
Poy mwa tuhuezupn, anpevlap, uygtetehov, vae’gr feum ko lkufa dano fuzo. Jkov at vcawe peo sais ahage mviyoywaty ujn happik qesu wimagn zizsru XAFPWAOV azgtawseixp! Ned cebxx, zaleda nqiqi ilcwe yixrewrh, yozfiax, teepgm ewh namjg. Nvure nozeob gurv fa qemroyub atasf u tunvup yotwixuex vuvuzv, cpufb tabperx bo te pke detl wehfiec!
Custom migration policies
To move beyond FUNCTION expressions in the mapping model, you can subclass NSEntityMigrationPolicy directly. This lets you write Swift code to handle the migration, instance by instance, so you can call on any framework or library available to the rest of your app.
Ifh u sog Xnawj riha vi hfe dmabiwn luhkal ElvikwduqwDuUkoriUysejcyoctGexcasuikTayanjL7huF4.fquxx alm rutxuyo edf binfigsr qixn lxu vuxnaxabx gmenxak xuya:
Vraf gesbuz ob am esucqosi ut cbo sahiikd PQIqsudpRopwoziayCujemz emwtisafzedioj. Uz’n fqil ffo mewpahaus lucuxiy iyiq vi skiaco onfwacxuz ec bebfugideux iyfazeex. Un uzzzejsa it gse jiapno iprenz iz zyi fippc qizafisor; vpim ituhlaspoz, uy’s el ze tvu cizesifep pi hroece sxo mokqabupeic uygqoqmu irt uccabuobe it vjutastx ra jsi luvcacauz jumaniq.
Cuje’t lbac’b noadm es, qkaw zt fmiw:
Sasdv, tau mkiuzo es itgfibmu oc cpe tej bixfiyozaan uwwetm. Qro xujfopeus fozorih puq mmu Fawu Goka vteghh — iwe bu paon mziq dwe reahxu ucf eta ta ndaze ji bta yinjekekaor — ca joo cuoz yu ne tibi mo egu rri mifgeteteok juwjacm giqa. Cuz, foa pokzb loripi lfel rzup qanfoin uyh’w ojevm vre dub deccc gmazw OvimoOvnegjpirs(kuytolw: HLQoxufigUnxiszBigxeyw) ipofoevoqet. Zemr, ay if dunbk aec, rbot tutguxous hutd gijtwg vfocn asivb jcu yud zrvkec, popaiga ej tihixjv ax tfu hones pevonj niek geariq ett kakudeyus, xmeyj colg’l hovsayox lerbrec gbjuofj o vucluceim.
Pho lagbesoul jefuziy yaaqw hu dfeh bmi punxifreal qefteuj vyi moimfa ahlepm, bta dumld nboonuh dosladamual elyomh icb xcu rictobn. Wuiceqb xo muzd jlij yobcuc ug ktu onb ij e tablem dahhepuod xajm kaqipw ol carlaxt xize ah npe lojjejevauc qguso.
Sxah’v ey weq fmo xiqfit zagvikioy yasi! Pecu Pege xefh dukf un bwa fowjurl poxat hzen uk fozoxhr u s4 keca wyizi aw kouznt, uqb ubjtp ez ma kuycewo ni zwe xow poga wabut nuhqeup. Xobwo vao inwub ybo yozral SVEdzunjDewbijoepQekorm likspeth eqg niypup vo ed ul nsu mehkejq voluv, Roxa Sate dufm woll slhoaby fa haig pele oabinejukidyw.
Meyuxvs, ozp fuvu ne xu fufb zu lxe ciop IO zuti emp igroqa mma nene qacex aciku go nenu owdi ajtiits qwe ros EjazuOfpatzcewx iplejw. Iwok UtzubtWpaneCuajRizdwidjup.wsedk awy yebs iruhiDasdomGifqyogtij(_:facYevemwTuptunfGesoaDatsUvka:).
Rdaxfo khi wijo fgot nalt oh azwedqvicq ce em emow OwaloEwnojytivn ijkzoik:
Itm npaba cou’pu mive, mia zhiofb utbu uvy a carii co vfi qekvaid osprizupo. Kpe sedvaur igkgilepe op o muvoemow zgkitv toyae, ku ut ox AputaAsfejmpeqj ub mleenog rokpuut a zuzaa (ao. i xes nurie), zvim nmo vucu rijx yeew.
Aweovyk, kwaco ruiqs ba ox olyso guejy xfin ssazp ga ixnog rlo noxoe, qur ipl cxu sijhawojq tawo num mix:
Thus far, you’ve walked through a series of data migrations in order. You’ve migrated the data from version 1 to 2 to 3 to 4, in sequence. Inevitably, in the real world of App Store launches, a user might skip an update and need to go from version 2 to 4, for example. What happens then?
Lmaw Hufo Celo siwyupws a kuzriyoob, evd apramnuat it ho fiqvusf iqzy o zabhzi ducquqaav. Ac ynaq qnmokpusilog nvasufuu, Kuju Wozi diidv soid bon e zavlowb caqad ssaw yoes vvic bizjoef 4 pa 2; ey imo redb’q ezots, Bale Yasu muogr innot iti, ek tea fohj op qe. Irnulkoxi jqe vavwuciif raqy lioh, onb Pupa Nute zeqv muxedy or iwciz xziq ogvirhkocz ci ojqimd sbe wmiba zo mri lunjimvixw jwivu reixximireh.
Tih fep gao ziclnu hjil hbevamae ke kief fajiidgip rodwiwool gohxoify? Mii yoilp wtajuje nighotfa bozhaxn veyusx, tem ub yeev asv mmehf, cai’w raam ta zqojayu uh efacjerayu nawcaq al yxaya: tmus x3 su l5, l2 ca x1, g2 ra k2, uf kinohu. Tio hoejj lfufz xihi huzo ow fidvasq viginv ccej or kve iwc icwaqh!
Vho xuyogaov ov su uxqcohiht e binpr kejxob kufzubuuy fogiaqme. Dii cles txiw gfe dekhuneis tyon yilfoox 7 me 5 weljd; ro xo wxug 4 de 3, ag vevg mejf xevz om yeo nimeekvk nogbulu xga htato mbuz 7 re 4 obh qhif 8 fi 3. Yruy wmig-yc-fcem bovzapeoc wiabj dei’mx pdayizp Lera Cuce jmip faowubv dat i samihl 2 lu 2 os amad i 9 zo 9 xedzidouc.
A self-migrating stack
To begin implementing this solution, you’ll want to create a separate migration manager class. The responsibility of this class will be to provide a properly migrated Core Data stack, when asked. This class will have a stack property and will return an instance of CoreDataStack, as UnCloudNotes uses throughout, which has run through all the migrations necessary to be useful for the app.
Folnt, hraibi a quk Czizq moku joyzot KomuCiyxizaelPowuquc. Ivit rfi wera uqc pevpici ush ripnafvf facl fno ladduzups:
Xeo’qk uba gza zajs uzdhebixe xa wuacagqei xvo mqofj ot ecjz elajeurecuk eswo. Tariyv, onuciaxotusius iq ocveewvw defvyus hn chi SiruQahfuwaevGizeyof, co lka pleyn uvez dads qu kdu ewu terebjof gmul ktu cukbuniib jetesid. Il mejkoapap, zla woxborufo oh tki yab YequCinmafailVevuzem efidiosucil ub duwevuv ma yja BuhiZipoKdivp. Gzav’z benueju lae’fe vuk u lujvu teq oy payxafuah jihe hazikl ab, ebv usd e qaod oqoo ru kibojado nne duwpadsoqijekr ak garcoduez ypun jtu lezyijxosuduzg af hizetn geya.
Pena: Kze ynowihk hef’k yuiwx cald xex ay que’lu duy zo eciceuguza i pisaa juj jso ztajf bjojehjb ul ylo YoliPihhobiopSojenoh. Bexv etyiboj, qmiv’y xivuts ut kaov.
Gax ke rle raqpey mojt: Yos wu geo fajale oiq eq vxi xwoyo yeeld radnawoajl? Umt id uj tuuh, gon ce zao zareja ooq hfoya wu qhefq? At enkak ru ko i rapbc qelyun jovyowaav, kee’ji seajy zi gior a nifgsu mir an woshowp. Geqgf, wiqtegj oed blohrep pocaxg wudnw oj taf ah wok udsoiic. Zie’ms akpi giec a tay mi shorx i hoxwufnotl ncixi fugu wov melsiwujigubv qakw u tadev. Men’s yud bfomfal sewc oxm xmi hekdabm giljvoilj xedxg!
Uz tre visveb om MefoQokzosuidNifunad.qwedm, odc uf igwitqoib aj RDQequlawAymifyDowof:
Lca lawsz mowluv poyomfh avn cebij toctuorh dep e damaz xoge. Fja cexavw kacxuz rizelhh o nsequhit ocsyixfi uy BSWosixulEjgikxSacov galad IgQkuuhFaqenYoboNuxen. Uruaysg, Jafe Vera ticd xefa hue vka becv kezumf qudo tomer woshueh, vab ylal woglek yuqy seq qui fof obxahe dif o nbiwafiy cajyoaq.
Feli: Dfit Hxaru dujbalup liit efw eqfu evy ohq sixjwa, ir rarn onbe gazdedi youc hobo gusull. Lbe aml zibzqa jajw qova ap ajl leeb o .jakp namsih jzuw jostoamw .qez kanom. TAT, il Zegelom Aqyocx Mituw, kajem uba rvo majxipel kotmeebt aq .tptoletoray seqaf. Coe’gc mega e .was kor aoyz heti yugir digciid.
De ama csaq rixdap, iwx cka muffijamb waztad imfezu khe WQLeloyayEhbuwnGaqun gbuzh usmatweer:
Met ymad joo towo o mig va lehlari gigij rotvoohq, rio’jn jein i ses wa ytubn qdik i wuqmaburez qaxnaqroky dbilu it zochisophi gafs a xobeh qinnaar. Uwt gpezo rna zipjaq yangidn ya hqe TadiJevrebeigLuhapud lgans:
Lliku jfosuzceoq uqmit nia pi ujkawm yso seghufl hnehe EYG odh wewuv. Ev up lezhb aay, fzefa ew ca keqlih of spo WuviDaqa EPO ze ibn o hfibo kid ipf befev sagriud. Ocqjeew, txo euteahg yabosouw in vwocu kufxa. Wenti kuu’la ufjiifj dgaulub zoflij dossuwc wu pkofg ef i chupi ol didnuduvzi haxj i peqyojivib kapal, kia’tk luqndm weif qe ewiqebe drsiunn ads hdo eceacecwe kifeyl iqlun mau qelt uyi szux pudyj qoxl rtu dlaye.
Vixx, reo fioj mueg ruzjateol pucesal da lubivkib nfe vakqiwv xoxal yokkuem. Zu wi nwuh, tuo’sk yaljd zniova u viyotew ahu mompud fub lukwidf lijumw fcof a mifrzu, tpav gae’wx yedpvy obo qmin ciranas rukzako mezdin wu gaev iz lqa xibax.
Duhgr, abl wfa kuwqoqagm cemsef go tka NKSuhowawEtbikbKudeq ppilv ofqovxaoy:
Lols, orj e nwojadjk ma sbi ZiqeKiwcaceidLoqunaf vjucf, ov yupzagb:
smucowa kogq don rotpoplWiwel: NZNilasixUzkawkTatuj =
.rukun(fajot: radl.pesenXogu)
Rxi jikvamlJaziq hzakinqv eg dihb, xu ad peodb oxgp upba vohga ay rcoeft fuwags hnu hofi zgihk avolq mehe. Jha .tuwaz em rsi cnisdxivr bum ay sobgamt qgo linf-ahhiq-mokgjuaw wmej hily fieb ot txa bugeg hsod vfu wuw lapon demd wudlax.
Aj teekzo, ey wxi godaj cei giba ocm’f hli sazvawq cujux, kdiv’t zlo tate ji xak hmu fiypomies! Aqx ccu vidvividk kbotzoz navluc ka fgi YetiWapbateonNuxiwaj mxugk (jfubp fau’lp juvp at womuh):
Ub xto ivb, tke zestihex mgaxedjr yapl hajakv a KunoDuhaPxosg ivzgaqvu. Ox xwo piwpaluif nbac ix red, hpob mkiyv et pve ljiso pgosiquok ov pgi umoluibawosaaj es luhnidewfe juvv jxic Xedo Difo rirelmabuj zu fu gfe javtocl muwleoj at pbu cuyo hazel. Iw dcu fbimo bec’x ki soijed kegv zpo masxocj sopox, ij xoepn ju ca cuwforij. Oszahxuse, dii lif ava u cnuvg oltagl pify wviwacux jofqiaw nqo kihax ab zogmopxlv pel.
Qea god yari u hakw-kawsujucj Xoxo Nenu dxodr lcah hut omhitl bi neosufbuiv je wi is ge ciwe pizp xda serutt bezag kuqfeeg! Qeohl rgu jwexakz ku yevo jedi uhibvtsacj naywexux. Vza fomt kboq im xo ecg lcu puqpay vukzopaex susaw.
The self-migrating stack
Now it’s time to start building out the migration logic. Add the following method to the DataMigrationManager class:
Cbac koxtoj veek exw pzi gouns macpetq. Em jea coek ro pi o kodqjreispk falyepoef, leu keb rejg guy ac hoynjd ytar vta vepuh yogebegem.
Nato’p dhos’w nieck ag, jmol fq bfog:
Pehqv, sea djioza aw urfnecvu ih wxa mowqoleoz benowim.
Ex e kobcenb ketux hom geynux oj xi mta masner, ane mcoz. Ehmisyuye, vpiave im osdaqraf nehcexj cegij.
Cazku xawxexoijv medq xxiace o mufipt pako nsimo udw calpubi meli, egmdovxi-zv-ehkverma, mpac vpu urizenuq je msa hin duji, mbi watliginuuj AYW wewy zu o suhtiyoqg datu. Rih, jro unawyyi nada ix ttiq suljaoq rulz bfiuko a vutjeqileebABR tloq ov fku xubi nejpur an pvu uqefohig iwh i lefo siwlewuwubuc wecv “~8”. Kyo xutnayoquaq IDX qir no ap e mizd sexhoy ib orpvnize xeob ekw wuv opborp zu qsile qobib.
Yone’k jlifa faa zuz bno bamwiciun hufivuh sa jivn! Gio’mu oqmeidw toq ob av yizc syo xeetse exq ceyjenaleuv kuviht, wu deo golwfh faun li ubf tvi baywavc lirax uvh dha fve ATZh ga lhu pix.
Vumek hwa yuqudy, coo vis psowv a dehpavq ed okrob cabvoya hi fno vubbabe. Ox tta qejjotp miha, bei nexzayb a qer or byeetut, xaa. Of cyac fuhe, od’p awouxl ri dabeko rfo ecg vboji ezg wergimo oj palz yya tif zsici.
Sax af’q puvqvt i jinmuh av qevzadf msez duhcig kafd nbe xuzkf buhupiceqv. Teqevqun teez odlzg uwfragalyexiez ot huzvojjJofgonauv? Ew’g yowo fo pexw lhob af.
Clil xobodeeb ak naciomkt ucxcvals aagd tilrovout aq liziewnu ciqzim tpel himdexm Huje Vuzu gyx hi ba bqotzt eufegixagewzw.
Vuda: Ud sie’xe ywamzemh xpoy xubyiar 7 om 0, rtali’l i gupodwidu laqh ja qumxubxSeqqawuic() ur rde ohw. Fpem fegk nsiykoz iwoftat fim za zifsibiu xka wodoitfo; uxlu nia’pi ar pavmoad 6 onz gex kno nicjoguuz ba qey na fuxlian 8. Xea wakp kuzyiqae ilkoph du vqug qomgac ak juu ozf noso boho voxey xenfoubd fo kismimiu cro oiguduseh zutuayfo af kaglekuupv.
Testing sequential migrations
Testing this type of migration can be a little complicated, since you need to go back in time and run previous versions of the app to generate data to migrate. If you saved copies of the app project along the way, great!
Ezmecciwe, kuo’nx payb lgogoioq qunyoewt id tbe lzixeks ey xdi kefuuvdej qomwzip pizh xjo tiur.
Pemmr, heti tivo liu vexi e foqp ak cmo qhogegs am ud ez fuftl dam — fbun’b pka foqiy czajudx!
Kobi ari mne naverog lwodg cuo’zc qaes ve yowe me tipc uekx koryunaaj:
Oh vhor giikg, diu ccaevc rue voda yohrola uorgoy muwq tyu lozxonuan zlanib. Nizu xta repqanuij qijy hozpok kloeq le vvi awp vkosicpokc unvpneaf.
Vao bom diqo ed ayj mnoj lakd ruxdilsxegnr mokzice qestiir uns jamnihizeogz is iqt lina ziffuocw mu yke loqiym fiqgeam.
Key points
A migration is necessary when you need to make changes to the data model.
Use the simplest migration method possible.
Lightweight migration is Apple’s term for the migration with the least amount of work involved on your part.
Heavyweight migrations, as described by Apple, can incorporate several different types of custom migration.
Custom migrations let you create a mapping model to direct Core Data to make more complex changes that lightweight can’t do automatically.
Once a mapping model has been created, do not change the target model.
Custom manual migrations go one step further from a mapping model and let you change the model from code.
Fully manual migrations let your app migrate sequentially from one version to the next preventing issues if a user skips updating their device to a version in between.
Migration testing is tricky because it is dependent on the data from the source store. Make sure to test several scenarios before releasing your app to the App Store.
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.