CoreData:使用CoreData完成一個通信錄存儲

CoreData做爲Apple的親兒子,依然在App須要存儲結構化數據上發揮着重要的做用。CoreData已經超過十年了,並且親爹還在積極的維護着它。git

在Monster、Indeed這些海外主流招聘網站看一下iOS的職位,基本上都會大大寫着要求會熟練使用CoreData。github

然而這麼一個成熟,被實踐檢驗過的代碼庫反而在國內使用並非特別多。FMDB、Realm等等在被普遍使用。常常在面試的時候問iOSer是否是瞭解數據庫,回答都是瞭解。再一細問,不少人也都是隻使用到了FMDB,對於CoreData倒是瞭解甚少。面試

後來想了想,多是由於CoreData的入門成本有點高,並且相關的中文資料比較少的緣故吧。數據庫

爲了寫這個系列,還專門買來了objc.io的CoreData這本書。讀完以後受益不淺。數組

這個系列要寫多少篇尚未想好,大概也仍是會從基本到高級的一個過渡。安全

第一篇經過一個通信錄實現數據庫的讀取。第二篇會存儲更多類型的數據。bash

最終實現結果: 架構

CoreDataDemo.gif

1. Core Data架構

一個基本的 Core Data 棧由四個主要部分組成:託管對象 (NSManagedObject),託管對象上下文 (NSManagedObjectContext),持久化存儲協調器 (NSPersistentStoreCoordinator),以及持久化存儲 (NSPersistentStore)。app

image.png

  • NSManagedObject是咱們的數據模型,也就是咱們存儲的對象。這些對象都保存在NSManagedObjectContext中,每一個存儲對象都知道本身對應哪一個上下文。ide

  • NSManagedObjectContext :平常打交道的都是這個。其餘三個在數據遷移的時候纔會看到。

  • NSPersistenStoreCoordinator : 是模型和存儲數據庫之間的橋樑,負責二者之間最複雜的細節隱藏。

關於Context想多說點,由於是每天都打交道的嘛。它實際上是內存中的一塊區域,對象全部的操做都須要一個context。直到save以前,都是在內存中,不會對數據庫中的內容有任何影響。每個託管對象都對應一個Context,一個對象只會跟一個特定的Context打交道。直到生命週期結束。

Context是線程不安全的。

2. CoreData的基本讀取操做

2. 1 獲取CoreData已經保存數據的五個步驟

  1. 獲取總代理和託管對象總管
  2. 從Entity獲取一個fetchRequest
  3. 根據fetchRequest,從managedContext中查詢數據
  4. 保存。保存過程當中可能會出錯,要作一下處理。
  5. 添加到數組中

2.2 基本存儲

  1. 獲取總代理和託管對象總管
  2. 創建一個Entity
  3. 保存內容
  4. 保存Entity到託管對象。若是保存失敗,進行處理
  5. 保存到數組中,更新UI

3. 更新一個通信錄的列表頁Demo

需求:完成一個通信錄的列表頁。要求:

  1. 從本地數據庫中讀取名字列表
  2. 點擊增長能夠添加一個名字
  3. 添加的名字能夠保存到本地數據庫中

好,接下來我們來一步一步實現這個需求。爲了突出重點,我們先從最簡單的開始,使用默認帶數據庫的工程進行着手。

3.1 Xcode建立默認帶數據庫的工程

image.png

在 Xcode 建立工程時,提供了建立 CoreData 的模板,只須要咱們在建立時,勾選 CoreData 選項,Xcode 就會自動建立出數據模型文件。

這個Demo用這個建立,純粹是爲了簡單直奔主題。否則還要一開始分享不少其餘的內容,看官們會以爲膩的。

可是,實際開發中不建議使用這種方式建立。一般狀況下咱們都會把生成的模板代碼都刪除的。

3.2 建立本地數據庫模板

image.png

勾選完成以後,會看到一個後綴名是"xcdatamodeld"的文件,這個就是我們的數據庫模板啦。

固然,如今裏面是還不能存數據的,還須要咱們設置一下字段名稱。

image.png
第一步,要添加一個Entity,這個就至關因而數據庫中的一張表。

第二步,對新建的Entity命名。

第三步,設計Entity裏面的屬性。我們這個Demo的需求裏面只須要一我的名,因此就只設置了一個名字叫作name的屬性,類型是String。

其餘更多的屬性類型,咱們會在下面一篇文章分享。

3.3 查詢本地數據

咦?在最開始的不是說一個基本的 Core Data 棧由四個主要部分組成嘛?怎麼沒有看到吶?

來來來,這就是最開始咱們使用Xcode建立默認帶數據庫的工程的緣由。使用了這個選項,會自動的在AppDelegate中生成相應的代碼。確實簡化了我們第一次學習的成本,可是就像沒人會把全部代碼都寫在Controller裏面同樣,在APPDelegate也不會寫這些東西。

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

3.4 插入並保存數據至本地數據庫

private func saveName(text: String) {
    //        步驟一:獲取總代理和託管對象總管
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
    let managedObectContext = appDelegate.persistentContainer.viewContext
    
    //        步驟二:創建一個entity
    let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedObectContext)
    
    let person = NSManagedObject(entity: entity!, insertInto: managedObectContext)
    
    //        步驟三:保存文本框中的值到person
    person.setValue(text, forKey: "name")
    
    //        步驟四:保存entity到託管對象中。若是保存失敗,進行處理
    do {
        try managedObectContext.save()
    } catch  {
        fatalError("沒法保存")
    }
    
    //        步驟五:保存到數組中,更新UI
    people.append(person)
}
複製代碼

全部的源代碼在這裏哈:GitHub 下載後給顆Star吧~ 麼麼噠~(~o ̄3 ̄)~ 愛大家~

相關文章
相關標籤/搜索