一. 簡述
Realm 是一個跨平臺的移動數(shù)據(jù)庫引擎。
Realm平臺是基于noSQL的服務(wù)器和客戶端組件的組合,該組件通過快速高效的同步協(xié)議進行連接,以實現(xiàn)實時,連接的應(yīng)用程序和服務(wù),無論網(wǎng)絡(luò)狀態(tài)如何,它們都具有響應(yīng)能力和性能。Realm平臺具有兩個主要組件:Realm數(shù)據(jù)庫和Realm對象服務(wù)器。這兩個組件協(xié)同工作以自動同步數(shù)據(jù),從而實現(xiàn)大量用例,從離線優(yōu)先應(yīng)用程序,現(xiàn)場服務(wù)和數(shù)據(jù)收集應(yīng)用程序,以數(shù)據(jù)可用性和用戶響應(yīng)能力為關(guān)鍵的移動服務(wù)開始。此外,通過與現(xiàn)有后端(SQL,Kafka等)的集成功能,Realm Platform是一種在利用現(xiàn)有(有時是傳統(tǒng))系統(tǒng)和數(shù)據(jù)源的同時構(gòu)建現(xiàn)代實時服務(wù)體驗的絕佳方法。

Realm數(shù)據(jù)庫嵌入在客戶端上,是一個功能齊全的,面向?qū)ο蟮目缙脚_數(shù)據(jù)庫,可將數(shù)據(jù)本地存儲在設(shè)備上。它適用于主要的移動語言,例如Swift和Objective-C(iOS),Java(Android),C#(Xamarin,.NET)和JavaScript(React Native和Node.js)。
Realm數(shù)據(jù)庫是輕量級且高性能的,能夠處理非常大的數(shù)據(jù)負載并在幾分之一秒內(nèi)運行查詢。它基于共享的活動對象,無需編寫網(wǎng)絡(luò),序列化或?qū)ο箨P(guān)系映射代碼,即可與Realm Object Server實時無縫同步數(shù)據(jù)。
Realm 性能優(yōu)于 FMDB 和 Core Data,支持 OC 和 Swift 語言開發(fā),使用更加簡單、方便。
下面主要說下Swift語言下的 Realm 數(shù)據(jù)庫的使用和 RealmSwift 數(shù)據(jù)遷移
二. Cocopods 安裝
pod 'RealmSwift'
三. 數(shù)據(jù)模型
不再詳述了,具體可參考中文官方文檔-數(shù)據(jù)模型
Realm 支持的屬性
| 類型 | 非可空值形式 | 可空值形式 |
|---|---|---|
| Bool | @objc dynamic var value = false |
let value = RealmOptional<Bool>() |
| Int | @objc dynamic var value = 0 |
let value = RealmOptional<Int>() |
| Float | @objc dynamic var value: Float = 0.0 |
let value = RealmOptional<Float>() |
| Double | @objc dynamic var value: Double = 0.0 |
let value = RealmOptional<Double>() |
| String | @objc dynamic var value = "" |
@objc dynamic var value: String? = nil |
| Data | @objc dynamic var value = Data() |
@objc dynamic var value: Data? = nil |
| Date | @objc dynamic var value = Date() |
@objc dynamic var value: Date? = nil |
| Object | 不存在:必須是可空值 | @objc dynamic var value: Class? |
| List | let value = List<Type>() |
不存在:必須是非可空值 |
| LinkingObjects | let value = LinkingObjects(fromType: Class.self, property: "property") |
不存在:必須是非可空值 |
四. 數(shù)據(jù)遷移
當您使用任意一個數(shù)據(jù)庫時,您隨時都可能打算修改您的數(shù)據(jù)模型。由于 Realm 的數(shù)據(jù)模型是以標準的 Swift 類來定義的,這使得修改模型就像修改其他的 Swift 類一樣方便。
例如在1.0.1版本定義的 Person,現(xiàn)在需要在1.0.2版本中添加一個 email 的屬性。
// 1.0.1版本定義的Person
class Person: Object {
@objc dynamic var name = ""
@objc dynamic var age = 0
}
// 1.0.2版本新增email屬性
class Person: Object {
@objc dynamic var name = ""
@objc dynamic var age = 0
@objc dynamic var email = ""
}
如下是具體處理這類問題的實現(xiàn)方式
// Swift 數(shù)據(jù)庫管理器中的init()方法中做數(shù)據(jù)遷移
override init() {
let realmName = "demo.realm"
let defaultUrl = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first
let configCompact = Realm.Configuration(
fileURL: defaultUrl?.appendingPathComponent("\(realmName)"),
shouldCompactOnLaunch: { totalBytes, usedBytes in
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
})
do {
// 如果滿足配置塊條件,則在第一次打開時壓縮 Realm
_ = try Realm(configuration: configCompact)
} catch {
// 處理壓縮或打開 Realm 的錯誤
}
let currentVersion : String = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
let currentVersions = currentVersion.components(separatedBy: ".")
let currentVersionStr = NSMutableString()
for subVersion in currentVersions {
let subs = String(format: "%02d", (subVersion as NSString).integerValue)
currentVersionStr.append(subs)
}
/*!
* 當前版本的UInt64版本號
* 如currentVersion = "1.0.1",schemaVersion = 010001; currentVersion = 10.12.25, schemaVersion = 101225
* !!! 注意 !!!
* 在打包定義版本的時候,版本規(guī)則:
* 1.版本號只能是三位,如1.12.18,中間只能兩個小數(shù)點;相反1.12.18.2或者1.22等禁用的。
* 2.版本號不能超過100,如定義到1.0.99或者1.99.1時,之后的下個版本不能定義1.0.100或1.100.0
*/
let schemaVersion : UInt64 = UInt64(currentVersionStr as String)!
let config = Realm.Configuration(
fileURL: defaultUrl?.appendingPathComponent("\(realmName)"),
schemaVersion: schemaVersion,
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < schemaVersion) {
migration.enumerateObjects(ofType: Person.className()) { (oldObject, newObject) in
// 新增字段
newObject!["email"] = ""
}
migration.enumerateObjects(ofType: Student.className()) { (oldObject, newObject) in
// 改字段
let firstName = oldObject!["firstName"] as! String
let lastName = oldObject!["lastName"] as! String
newObject!["fullName"] = "\(firstName) \(lastName)"
}
}
})
Realm.Configuration.defaultConfiguration = config
_ = try! Realm()
}
?? 個人博客 ForgetSou