iOS開發(fā)-RealmSwift的使用及數(shù)據(jù)遷移

一. 簡述

Realm 是一個跨平臺的移動數(shù)據(jù)庫引擎。

Realm 中文文檔

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ù)體驗的絕佳方法。

領(lǐng)域平臺的高級示意圖

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


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容