Swift實踐:使用CoreData儲存多種資料類的通訊錄

非典型技術宅發表於2018-12-11
Snip20171107_2.png

上一篇文章簡單的實現了一個通訊錄,說是通訊錄實際上就只是一個簡簡單單的Name List。這次我們要往這個通訊錄裡面加入更多的元素,目的也是為了學習CoreData如何儲存更多的資料型別。

完成後的效果:

contact.gif

1. CoreData支援儲存資料型別

image.png

咦?這裡面有兩個好像很少看到的型別:Binary Data、Decimal、Transformable。這些都是神馬東西?

1.1 Binary Data

顧名思義,就是二進位制資料。對應到OC中就是NSData, Swift裡面就是Data資料型別。

我們這次就試試在通訊裡面儲存一下圖片,把圖片變成Binary Data進行儲存。

1.2 Decimal

Decimal為SQL Server、MySql等資料庫的一種資料型別,不屬於浮點數型別,可以在定義時劃定整數部分以及小數部分的位數。使用精確小數型別不僅能夠保證資料計算更為精確,還可以節省儲存空間。

Decimal(n,m)表示數值中共有n位數,其中整數n-m位,小數m位。例:decimal(10,6),數值中共有10位數,其中整數佔4位,小數佔6位。

問題來了,Decimal(2,1):
1, 插入資料“12”會怎樣?

  • 會出現資料移除的錯誤。

2, 插入”1.2345“會怎樣?

  • 會自動四捨五入成1.2

3, 插入2,會怎樣?

  • 會自動補充成2.0,以確保2位的有效長度和1位的小數。

1.3 Transformable

這個型別就比較搞了,有人說它是萬能型別,有人說它只要是物件就都可以。

在官方文件裡面,Core Data Release Notes for OS X v10.5 是這麼介紹的:

Transformable Attributes
There`s a new “transformable” type for NSManagedObject attributes that allows you more easily support attribute types that Core Data doesn`t support natively. You access an attribute as a non-standard type, but behind the scenes Core Data uses an instance of NSValueTransformer to convert the attribute to and from an instance of NSData. Core Data then stores the data instance to the persistent store.

If you don’t specify a transformer, transformable attributes to use keyed archiving (NSKeyedUnarchiveFromDataTransformerName).

For more details, see Non-Standard Persistent Attributes.

說到底,這是一個非標準的型別。在中文中,非典型技術宅胖其實覺得翻譯成“其他”型別更貼切。哈哈~~就和有關部門一樣d=====( ̄▽ ̄*)b厲害。

有一點點小小需要注意的地方就是,資料型別要遵守NSCoding協議。只要遵守了,就可以使用這個厲害的儲存型別了。

來來來,舉幾個栗子。Dictionary、Array、Number等等都可以呀。。。

感情是個萬金油型別!!

2. 使用CoreData儲存多種資料類的通訊錄

我們在這裡計劃儲存的型別有Data、Bool、String、Date、Int64。

image.png

2.1 CoreData的基本讀取操作

2. 1.1 獲取CoreData已經儲存資料的五個步驟

  1. 獲取總代理和託管物件總管
  2. 從Entity獲取一個fetchRequest
  3. 根據fetchRequest,從managedContext中查詢資料
  4. 儲存。儲存過程中可能會出錯,要做一下處理。
  5. 新增到陣列中

2.1.2 基本儲存

  1. 獲取總代理和託管物件總管
  2. 建立一個Entity
  3. 儲存內容
  4. 儲存Entity到託管物件。如果儲存失敗,進行處理
  5. 儲存到陣列中,更新UI

2.2 多種型別的儲存

let imgData = from.value(forKey: "avatar") as? Data
let isRelative = from.value(forKey: "isRelative") as? Bool
let name = from.value(forKey: "name") as? String
let updateTime = from.value(forKey: "updateTime") as? Date
let viewTimes = from.value(forKey: "viewTimes") as? Int64
let mobile = from.value(forKey: "mobile") as? String
複製程式碼

來來來,就這樣輕鬆easy的把各種型別的都轉換好啦~ 然後就可以存入進去了吶。

3. Codable

我們們通訊錄裡面通常的做法都會把一個使用者的資訊全部放在一個Model裡面,然後只需要把Model儲存到庫裡面就好了。這個怎麼做呢?

在OC時代,當需要將一個物件持久化時,需要把這個物件序列化,往常的做法是實現 NSCoding 協議。

寫過的人應該都知道實現 NSCoding 協議的程式碼寫起來很痛苦,特別想哭,尤其是當屬性非常多的時候。

於是乎,Swift 4 中引入了 Codable 幫我們解決了這個問題。

struct User: Codable {
    var avatarImg: Data
    var isRelative: Bool
    var name: String
    var updateTime: Date
    var viewTimes: Int64
    var mobile: String     
}
複製程式碼

如果我們想把User 物件的例項持久化,只需要讓 User 遵守 Codable 協議即可,Language 中不用寫別的程式碼。這樣就可以直接把Userencode成JSON啦。

下一篇我們就不能再用Xcode建立自帶的CoreData來搞事情了,我們要自己搞一個CoreData Stack來實現管理。

所有的原始碼都在這裡:
https://github.com/Stanbai/CoreDataDemo.git

相關文章