Swift實(shí)踐:使用CoreData完成一個(gè)通訊錄存儲(chǔ)

CoreData作為Apple的親兒子,依然在App需要存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)上發(fā)揮著重要的作用。CoreData已經(jīng)超過十年了拗胜,而且親爹還在積極的維護(hù)著它。

image.png

在Monster怒允、Indeed這些海外主流招聘網(wǎng)站看一下iOS的職位埂软,基本上都會(huì)大大寫著要求會(huì)熟練使用CoreData。

然而這么一個(gè)成熟纫事,被實(shí)踐檢驗(yàn)過的代碼庫反而在國內(nèi)使用并不是特別多勘畔。FMDB、Realm等等在被廣泛使用丽惶。經(jīng)常在面試的時(shí)候問iOSer是不是了解數(shù)據(jù)庫炫七,回答都是了解。再一細(xì)問钾唬,很多人也都是只使用到了FMDB万哪,對(duì)于CoreData卻是了解甚少。

后來想了想抡秆,可能是因?yàn)镃oreData的入門成本有點(diǎn)高奕巍,而且相關(guān)的中文資料比較少的緣故吧。

為了寫這個(gè)系列儒士,還專門買來了objc.io的CoreData這本書的止。讀完之后受益匪淺。

這個(gè)系列要寫多少篇還沒有想好着撩,大概也還是會(huì)從基本到高級(jí)的一個(gè)過渡诅福。

第一篇通過一個(gè)通訊錄實(shí)現(xiàn)數(shù)據(jù)庫的讀取。第二篇會(huì)存儲(chǔ)更多類型的數(shù)據(jù)睹酌。

最終實(shí)現(xiàn)結(jié)果:


CoreDataDemo.gif

1. Core Data架構(gòu)

一個(gè)基本的 Core Data 棧由四個(gè)主要部分組成:托管對(duì)象 (NSManagedObject)权谁,托管對(duì)象上下文 (NSManagedObjectContext)剩檀,持久化存儲(chǔ)協(xié)調(diào)器 (NSPersistentStoreCoordinator)憋沿,以及持久化存儲(chǔ) (NSPersistentStore)。

image.png
  • NSManagedObject是我們的數(shù)據(jù)模型沪猴,也就是我們存儲(chǔ)的對(duì)象辐啄。這些對(duì)象都保存在NSManagedObjectContext中采章,每個(gè)存儲(chǔ)對(duì)象都知道自己對(duì)應(yīng)哪個(gè)上下文。

  • NSManagedObjectContext :日常打交道的都是這個(gè)壶辜。其他三個(gè)在數(shù)據(jù)遷移的時(shí)候才會(huì)看到悯舟。

  • NSPersistenStoreCoordinator :
    是模型和存儲(chǔ)數(shù)據(jù)庫之間的橋梁,負(fù)責(zé)兩者之間最復(fù)雜的細(xì)節(jié)隱藏砸民。

關(guān)于Context想多說點(diǎn)抵怎,因?yàn)槭翘焯於即蚪坏赖穆铩K鋵?shí)是內(nèi)存中的一塊區(qū)域岭参,對(duì)象所有的操作都需要一個(gè)context反惕。直到save之前,都是在內(nèi)存中演侯,不會(huì)對(duì)數(shù)據(jù)庫中的內(nèi)容有任何影響姿染。每一個(gè)托管對(duì)象都對(duì)應(yīng)一個(gè)Context,一個(gè)對(duì)象只會(huì)跟一個(gè)特定的Context打交道秒际。直到生命周期結(jié)束悬赏。

Context是線程不安全的。

2. CoreData的基本讀取操作

2. 1 獲取CoreData已經(jīng)保存數(shù)據(jù)的五個(gè)步驟

  1. 獲取總代理和托管對(duì)象總管
  2. 從Entity獲取一個(gè)fetchRequest
  3. 根據(jù)fetchRequest娄徊,從managedContext中查詢數(shù)據(jù)
  4. 保存闽颇。保存過程中可能會(huì)出錯(cuò),要做一下處理寄锐。
  5. 添加到數(shù)組中

2.2 基本存儲(chǔ)

  1. 獲取總代理和托管對(duì)象總管
  2. 建立一個(gè)Entity
  3. 保存內(nèi)容
  4. 保存Entity到托管對(duì)象进萄。如果保存失敗,進(jìn)行處理
  5. 保存到數(shù)組中锐峭,更新UI

3. 更新一個(gè)通訊錄的列表頁Demo

需求:完成一個(gè)通訊錄的列表頁中鼠。要求:

  1. 從本地?cái)?shù)據(jù)庫中讀取名字列表
  2. 點(diǎn)擊增加可以添加一個(gè)名字
  3. 添加的名字可以保存到本地?cái)?shù)據(jù)庫中

好,接下來咱們來一步一步實(shí)現(xiàn)這個(gè)需求沿癞。為了突出重點(diǎn)援雇,咱們先從最簡單的開始,使用默認(rèn)帶數(shù)據(jù)庫的工程進(jìn)行著手椎扬。

3.1 Xcode創(chuàng)建默認(rèn)帶數(shù)據(jù)庫的工程

image.png

在 Xcode 創(chuàng)建工程時(shí)惫搏,提供了創(chuàng)建 CoreData 的模板,只需要我們?cè)趧?chuàng)建時(shí)蚕涤,勾選 CoreData 選項(xiàng)筐赔,Xcode 就會(huì)自動(dòng)創(chuàng)建出數(shù)據(jù)模型文件。

這個(gè)Demo用這個(gè)創(chuàng)建揖铜,純粹是為了簡單直奔主題茴丰。不然還要一開始分享很多其他的內(nèi)容,看官們會(huì)覺得膩的。

但是贿肩,實(shí)際開發(fā)中不建議使用這種方式創(chuàng)建峦椰。通常情況下我們都會(huì)把生成的模板代碼都刪除的。

3.2 創(chuàng)建本地?cái)?shù)據(jù)庫模板

image.png

勾選完成之后汰规,會(huì)看到一個(gè)后綴名是"xcdatamodeld"的文件汤功,這個(gè)就是咱們的數(shù)據(jù)庫模板啦。

當(dāng)然溜哮,現(xiàn)在里面是還不能存數(shù)據(jù)的滔金,還需要我們?cè)O(shè)置一下字段名稱。

image.png

第一步茂嗓,要添加一個(gè)Entity鹦蠕,這個(gè)就相當(dāng)于是數(shù)據(jù)庫中的一張表。

第二步在抛,對(duì)新建的Entity命名钟病。

第三步,設(shè)計(jì)Entity里面的屬性刚梭。咱們這個(gè)Demo的需求里面只需要一個(gè)人名肠阱,所以就只設(shè)置了一個(gè)名字叫做name的屬性,類型是String朴读。

其他更多的屬性類型屹徘,我們會(huì)在下面一篇文章分享。

3.3 查詢本地?cái)?shù)據(jù)

咦衅金?在最開始的不是說一個(gè)基本的 Core Data 棧由四個(gè)主要部分組成嘛噪伊?怎么沒有看到吶?

來來來氮唯,這就是最開始我們使用Xcode創(chuàng)建默認(rèn)帶數(shù)據(jù)庫的工程的原因鉴吹。使用了這個(gè)選項(xiàng),會(huì)自動(dòng)的在AppDelegate中生成相應(yīng)的代碼惩琉。確實(shí)簡化了咱們第一次學(xué)習(xí)的成本豆励,但是就像沒人會(huì)把所有代碼都寫在Controller里面一樣,在APPDelegate也不會(huì)寫這些東西瞒渠。

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //        步驟一:獲取總代理和托管對(duì)象總管
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        
        let managedObectContext = appDelegate.persistentContainer.viewContext
        
//        步驟二:建立一個(gè)獲取的請(qǐng)求
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
        
//        步驟三:執(zhí)行請(qǐng)求
        do {
            let fetchedResults = try managedObectContext.fetch(fetchRequest) as? [NSManagedObject]
            if let results = fetchedResults {
                people = results
                
                tableView.reloadData()
            }
            
        } catch  {
            fatalError("獲取失敗")
        }
    }

3.4 插入并保存數(shù)據(jù)至本地?cái)?shù)據(jù)庫

private func saveName(text: String) {
    //        步驟一:獲取總代理和托管對(duì)象總管
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
    let managedObectContext = appDelegate.persistentContainer.viewContext
    
    //        步驟二:建立一個(gè)entity
    let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedObectContext)
    
    let person = NSManagedObject(entity: entity!, insertInto: managedObectContext)
    
    //        步驟三:保存文本框中的值到person
    person.setValue(text, forKey: "name")
    
    //        步驟四:保存entity到托管對(duì)象中良蒸。如果保存失敗,進(jìn)行處理
    do {
        try managedObectContext.save()
    } catch  {
        fatalError("無法保存")
    }
    
    //        步驟五:保存到數(shù)組中伍玖,更新UI
    people.append(person)
}

所有的源代碼在這里哈:
https://github.com/Stanbai/CoreDataDemo.git


Swift之CoreData系列之一:基礎(chǔ)存儲(chǔ)

Swift之CoreData系列之二:存儲(chǔ)多種數(shù)據(jù)類型

Swift之CoreData系列之三:自定義CoreData Stack

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嫩痰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子窍箍,更是在濱河造成了極大的恐慌串纺,老刑警劉巖丽旅,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異造垛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)晰搀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門五辽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人外恕,你說我怎么就攤上這事杆逗。” “怎么了鳞疲?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵罪郊,是天一觀的道長。 經(jīng)常有香客問我尚洽,道長悔橄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任腺毫,我火速辦了婚禮癣疟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潮酒。我一直安慰自己睛挚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布急黎。 她就那樣靜靜地躺著扎狱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勃教。 梳的紋絲不亂的頭發(fā)上淤击,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音故源,去河邊找鬼遭贸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛心软,可吹牛的內(nèi)容都是我干的壕吹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼删铃,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼耳贬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起猎唁,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤咒劲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腐魂,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帐偎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛔屹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片削樊。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖兔毒,靈堂內(nèi)的尸體忽然破棺而出漫贞,到底是詐尸還是另有隱情,我是刑警寧澤育叁,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布迅脐,位于F島的核電站,受9級(jí)特大地震影響豪嗽,放射性物質(zhì)發(fā)生泄漏谴蔑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一龟梦、第九天 我趴在偏房一處隱蔽的房頂上張望树碱。 院中可真熱鬧,春花似錦变秦、人聲如沸成榜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赎婚。三九已至,卻和暖如春樱溉,著一層夾襖步出監(jiān)牢的瞬間挣输,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工福贞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撩嚼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓挖帘,卻偏偏與公主長得像完丽,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拇舀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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