Core Data詳細(xì)解析(七) —— Core Data的輕量級(jí)遷移(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2018.09.26 星期三

前言

數(shù)據(jù)是移動(dòng)端的重點(diǎn)關(guān)注對(duì)象,其中有一條就是數(shù)據(jù)存儲(chǔ)仆葡。CoreData是蘋(píng)果出的數(shù)據(jù)存儲(chǔ)和持久化技術(shù)赏参,面向?qū)ο筮M(jìn)行數(shù)據(jù)相關(guān)存儲(chǔ)。感興趣的可以看下面幾篇文章沿盅。
1. iOS CoreData(一)
2. iOS CoreData實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)(二)
3. Core Data詳細(xì)解析(三) —— 一個(gè)簡(jiǎn)單的入門示例(一)
4. Core Data詳細(xì)解析(四) —— 一個(gè)簡(jiǎn)單的入門示例(二)
5. Core Data詳細(xì)解析(五) —— 基于多上下文的Core Data簡(jiǎn)單解析示例(一)
6. Core Data詳細(xì)解析(六) —— 基于多上下文的Core Data簡(jiǎn)單解析示例(二)

When to Migrate - 何時(shí)需要遷移

首先看一下寫(xiě)作環(huán)境

Swift 4.2, iOS 12, Xcode 10

在應(yīng)用程序開(kāi)發(fā)期間把篓,在發(fā)布日期之前,徹底的測(cè)試可以幫助消除數(shù)據(jù)模型腰涧。 但是韧掩,應(yīng)用程序發(fā)布后應(yīng)用程序使用、設(shè)計(jì)或功能的變化將不可避免地導(dǎo)致數(shù)據(jù)模型的變化窖铡。 那你怎么辦呢疗锐?

您無(wú)法預(yù)測(cè)未來(lái),但使用Core Data费彼,您可以在應(yīng)用的每個(gè)新版本中向未來(lái)遷移窒悔。 遷移過(guò)程將更新使用先前版本的數(shù)據(jù)模型創(chuàng)建的數(shù)據(jù)以匹配當(dāng)前數(shù)據(jù)模型。

本教程將引導(dǎo)您完成筆記記錄應(yīng)用程序數(shù)據(jù)模型的演變敌买,從而討論Core Data遷移的許多方面简珠。 您將從一個(gè)簡(jiǎn)單的應(yīng)用程序開(kāi)始,其數(shù)據(jù)模型中只有一個(gè)實(shí)體虹钮。

何時(shí)需要遷移聋庵? 這個(gè)常見(jiàn)問(wèn)題的最簡(jiǎn)單答案是“當(dāng)您需要對(duì)數(shù)據(jù)模型(data model)進(jìn)行更改時(shí)”。

但是芙粱,在某些情況下您可以避免遷移祭玉。 如果應(yīng)用程序僅將Core Data用作脫機(jī)緩存,則在更新應(yīng)用程序時(shí)春畔,只需刪除并重建數(shù)據(jù)存儲(chǔ)即可脱货。 只有當(dāng)用戶數(shù)據(jù)的真實(shí)來(lái)源不在數(shù)據(jù)存儲(chǔ)中時(shí),才可能這樣做律姨。 在所有其他情況下振峻,您需要保護(hù)用戶的數(shù)據(jù)。

也就是說(shuō)择份,只要不改變數(shù)據(jù)模型就無(wú)法實(shí)現(xiàn)設(shè)計(jì)變更或功能請(qǐng)求扣孟,您就需要?jiǎng)?chuàng)建新版本的數(shù)據(jù)模型并提供遷移路徑。


The Migration Process - 遷移過(guò)程

初始化Core Data堆棧時(shí)荣赶,其中一個(gè)步驟是將存儲(chǔ)添加到持久性存儲(chǔ)協(xié)調(diào)器(persistent store coordinator)凤价。 當(dāng)您遇到此步驟時(shí)鸽斟,Core Data會(huì)在將存儲(chǔ)添加到協(xié)調(diào)器之前執(zhí)行一些操作。 首先利诺,Core Data分析存儲(chǔ)的模型版本富蓄。 接下來(lái),它將此版本與協(xié)調(diào)器配置的數(shù)據(jù)模型進(jìn)行比較慢逾。 如果存儲(chǔ)的模型版本與協(xié)調(diào)器的模型版本不匹配立倍,Core Data將在啟用時(shí)執(zhí)行遷移。

注意:如果未啟用遷移氛改,并且存儲(chǔ)與模型不兼容帐萎,則Core Data將不會(huì)將存儲(chǔ)附加到協(xié)調(diào)器,并使用適當(dāng)?shù)脑虼a指定錯(cuò)誤胜卤。

要啟動(dòng)遷移過(guò)程疆导,Core Data需要原始數(shù)據(jù)模型和目標(biāo)模型。它使用這兩個(gè)版本來(lái)加載或創(chuàng)建遷移的映射模型葛躏,它用于將原始存儲(chǔ)中的數(shù)據(jù)轉(zhuǎn)換為可以存儲(chǔ)在新存儲(chǔ)中的數(shù)據(jù)澈段。一旦Core Data確定了映射模型,遷移過(guò)程就可以開(kāi)始了舰攒。

遷移分三個(gè)步驟進(jìn)行:

  • 1) 首先败富,Core Data將所有對(duì)象從一個(gè)數(shù)據(jù)存儲(chǔ)復(fù)制到下一個(gè)數(shù)據(jù)存儲(chǔ)。
  • 2) 接下來(lái)摩窃,Core Data根據(jù)關(guān)系映射連接并關(guān)聯(lián)所有對(duì)象兽叮。
  • 3) 最后,在目標(biāo)模型中強(qiáng)制執(zhí)行任何數(shù)據(jù)驗(yàn)證猾愿。Core Data在數(shù)據(jù)復(fù)制期間禁用目標(biāo)模型驗(yàn)證鹦聪。

您可能會(huì)問(wèn),“如果出現(xiàn)問(wèn)題蒂秘,原始源數(shù)據(jù)存儲(chǔ)會(huì)發(fā)生什么泽本?”對(duì)于幾乎所有類型的Core Data遷移,除非遷移完成且沒(méi)有錯(cuò)誤姻僧,否則原始存儲(chǔ)不會(huì)發(fā)生任何變化规丽。只有在遷移成功時(shí),Core Data才會(huì)刪除原始數(shù)據(jù)存儲(chǔ)撇贺。

您可能會(huì)問(wèn)赌莺,“如果出現(xiàn)問(wèn)題,原始源數(shù)據(jù)存儲(chǔ)會(huì)發(fā)生什么显熏?”對(duì)于幾乎所有類型的Core Data遷移雄嚣,除非遷移完成且沒(méi)有錯(cuò)誤,否則原始存儲(chǔ)不會(huì)發(fā)生任何變化喘蟆。 只有在遷移成功時(shí)缓升,Core Data才會(huì)刪除原始數(shù)據(jù)存儲(chǔ)。


Types of Migrations - 遷移類型

根據(jù)我自己的經(jīng)驗(yàn)蕴轨,我發(fā)現(xiàn)除了Apple稱之為輕量級(jí)和重量級(jí)遷移之間的簡(jiǎn)單區(qū)別之外港谊,還有一些遷移變體。 下面橙弱,我提供了更微妙的遷移名稱變體歧寺,但這些名稱無(wú)論如何都不是官方類別。 您將從最不復(fù)雜的遷移形式開(kāi)始棘脐,以最復(fù)雜的形式結(jié)束斜筐。

1. Lightweight Migrations - 輕量級(jí)遷移

輕量級(jí)遷移是Apple的遷移術(shù)語(yǔ),只需要您完成最少量的工作蛀缝。 當(dāng)您使用NSPersistentContainer時(shí)顷链,這會(huì)自動(dòng)發(fā)生,或者您在構(gòu)建自己的Core Data堆棧時(shí)必須設(shè)置一些標(biāo)志屈梁。 您可以更改數(shù)據(jù)模型的數(shù)量有一些限制嗤练,但由于啟用此選項(xiàng)所需的工作量很少,因此它是理想的設(shè)置在讶。

2. Manual Migrations - 手動(dòng)遷移

手動(dòng)遷移需要您做更多的工作煞抬。 您需要指定如何將舊數(shù)據(jù)集映射到新集合,但有一個(gè)好處就是您可以獲得要配置的更明確的映射模型文件构哺。 在Xcode中設(shè)置映射模型就像設(shè)置數(shù)據(jù)模型一樣革答,具有類似的GUI工具和一些自動(dòng)化。

3. Custom Manual Migrations - 自定義手動(dòng)遷移

這是遷移復(fù)雜性指數(shù)的第3級(jí)曙强。 您仍將使用映射模型残拐,但使用自定義代碼補(bǔ)充該模型以指定數(shù)據(jù)上的自定義轉(zhuǎn)換邏輯。 自定義實(shí)體轉(zhuǎn)換邏輯涉及創(chuàng)建NSEntityMigrationPolicy子類并在那里執(zhí)行自定義轉(zhuǎn)換旗扑。

4. Fully Manual Migrations - 完全手動(dòng)遷移

完全手動(dòng)遷移適用于那些甚至指定自定義轉(zhuǎn)換邏輯不足以將數(shù)據(jù)從一個(gè)模型版本完全遷移到另一個(gè)模型版本的情況蹦骑。 自定義版本檢測(cè)邏輯和遷移過(guò)程的自定義處理是必要的。 在本文中臀防,您將設(shè)置完全手動(dòng)遷移以跨非順序版本更新數(shù)據(jù)眠菇,例如從版本1跳轉(zhuǎn)到4。

在本文中袱衷,您將了解每種遷移類型以及何時(shí)使用它們捎废。 讓我們開(kāi)始吧!


開(kāi)始

下載本文資源包含一個(gè)名為UnCloudNotes的入門項(xiàng)目致燥。 找到啟動(dòng)項(xiàng)目并在Xcode中打開(kāi)它登疗。

在iPhone模擬器中構(gòu)建并運(yùn)行應(yīng)用程序。 你會(huì)看到一個(gè)空的筆記列表:

點(diǎn)按右上角的加號(hào)(+)按鈕添加新筆記。 添加標(biāo)題(注釋正文中有默認(rèn)文本以使處理更快)辐益,然后點(diǎn)擊Create將新筆記保存到數(shù)據(jù)存儲(chǔ)断傲。 重復(fù)幾次,以便遷移一些示例數(shù)據(jù)智政。

回到Xcode认罩,打開(kāi)UnCloudNotesDatamodel.xcdatamodeld文件,在Xcode中顯示實(shí)體建模工具续捂。 數(shù)據(jù)模型很簡(jiǎn)單 - 只有一個(gè)實(shí)體垦垂,一個(gè)Note,有一些屬性牙瓢。

您將為應(yīng)用添加新功能:將照片附加到note的功能劫拗。 數(shù)據(jù)模型沒(méi)有任何地方可以保留此類信息,因此您需要在數(shù)據(jù)模型中添加一個(gè)位置來(lái)保留照片矾克。 但是你已經(jīng)在應(yīng)用程序中添加了一些測(cè)試notes页慷。 如何在不破壞現(xiàn)有notes的情況下更改模型?

是你第一次遷移的時(shí)候了聂渊!


A Lightweight Migration - 輕量級(jí)遷移

在Xcode中差购,選擇UnCloudNotes數(shù)據(jù)模型文件(如果尚未選擇)。 這將顯示主工作區(qū)中的實(shí)體建模器汉嗽。 接下來(lái)欲逃,打開(kāi)Editor菜單并選擇Add Model Version ....將新版本命名為UnCloudNotesDataModel v2,并確保在Based on model字段中選擇了UnCloudNotesDataModel饼暑。 Xcode現(xiàn)在將創(chuàng)建數(shù)據(jù)模型的副本稳析。

注意:您可以為此文件指定任何名稱。 順序v2弓叛,v3彰居,v4等命名可以幫助您輕松區(qū)分版本。

此步驟將創(chuàng)建數(shù)據(jù)模型的第二個(gè)版本撰筷,但您仍需要告訴Xcode將新版本用作當(dāng)前模型陈惰。 如果您忘記了此步驟,則選擇頂級(jí)UnCloudNotesDataModel.xcdatamodeld文件將執(zhí)行您對(duì)原始模型文件所做的任何更改毕籽。 您可以通過(guò)選擇單個(gè)模型版本來(lái)覆蓋此行為抬闯,但確保您不會(huì)意外地修改原始文件仍然是一個(gè)好主意。

要執(zhí)行任何遷移关筒,您希望保持原始模型文件不變津畸,并對(duì)全新的模型文件進(jìn)行更改积蜻。

在右側(cè)的File Inspector窗格中,底部有一個(gè)名為Model Version的選擇菜單篷就。

更改該選擇以匹配新數(shù)據(jù)模型的名稱UnCloudNotesDataModel v2露久。

完成更改后,請(qǐng)注意項(xiàng)目導(dǎo)航器中的小綠色復(fù)選標(biāo)記圖標(biāo)已從先前的數(shù)據(jù)模型移至v2數(shù)據(jù)模型:

在設(shè)置堆棧時(shí),Core Data將嘗試首先將持久存儲(chǔ)與已勾選的模型版本連接。 如果找到存儲(chǔ)文件塘揣,并且該文件與此模型文件不兼容,則會(huì)觸發(fā)遷移碉纳。 舊版本可用于支持遷移勿负。 當(dāng)前模型是在連接堆棧的其余部分供您使用之前確保加載的Core Data馏艾。

確保選擇了v2數(shù)據(jù)模型劳曹,并將image屬性添加到Note實(shí)體。 將屬性的名稱設(shè)置為image琅摩,將屬性的類型設(shè)置為Transformable铁孵。

由于此屬性將包含圖像的實(shí)際二進(jìn)制位,因此您將使用自定義NSValueTransformer將二進(jìn)制位轉(zhuǎn)換為UIImage房资,然后再返回蜕劝。 只是在ImageTransformer中為您提供了這樣的變換器。 在屏幕右側(cè)的Data Model Inspector中轰异,查找Value Transformer字段岖沛,然后輸入ImageTransformer。 接下來(lái)搭独,在Module字段中婴削,選擇Current Product Module

注意:引用模型文件中的代碼時(shí)牙肝,就像在Xib和Storyboard文件中一樣唉俗,您需要指定一個(gè)moduleUnCloudNotesCurrent Product Module,具體取決于您的下拉提供的內(nèi)容)配椭,以允許類加載器查找你想要添加的確切的代碼虫溜。

新模型現(xiàn)在已經(jīng)準(zhǔn)備好了一些代碼! 打開(kāi)Note.swift并在displayIndex下面添加以下屬性:

@NSManaged var image: UIImage?

構(gòu)建并運(yùn)行應(yīng)用程序股缸。 你會(huì)看到你的notes仍然神奇地顯示出來(lái)衡楞! 事實(shí)證明,默認(rèn)情況下啟用輕量級(jí)遷移敦姻。 這意味著每次創(chuàng)建新的數(shù)據(jù)模型版本時(shí)瘾境,它都可以自動(dòng)遷移,這很省時(shí)間替劈!

后記

本篇主要講述了Core Data的輕量級(jí)遷移寄雀,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陨献,隨后出現(xiàn)的幾起案子盒犹,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件急膀,死亡現(xiàn)場(chǎng)離奇詭異沮协,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)卓嫂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門慷暂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人晨雳,你說(shuō)我怎么就攤上這事行瑞。” “怎么了餐禁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵血久,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我帮非,道長(zhǎng)氧吐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任末盔,我火速辦了婚禮筑舅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘陨舱。我一直安慰自己翠拣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布隅忿。 她就那樣靜靜地躺著心剥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪背桐。 梳的紋絲不亂的頭發(fā)上优烧,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音链峭,去河邊找鬼畦娄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弊仪,可吹牛的內(nèi)容都是我干的熙卡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼励饵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼驳癌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起役听,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颓鲜,失蹤者是張志新(化名)和其女友劉穎表窘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甜滨,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乐严,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衣摩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昂验。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖艾扮,靈堂內(nèi)的尸體忽然破棺而出既琴,到底是詐尸還是另有隱情,我是刑警寧澤栏渺,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布呛梆,位于F島的核電站,受9級(jí)特大地震影響磕诊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纹腌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一霎终、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧升薯,春花似錦莱褒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蛛枚,卻和暖如春谅海,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹦浦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工扭吁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盲镶。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓侥袜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親溉贿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枫吧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容