iOS开发-RealmSwift的使用及数据迁移

一. 简述

Realm 是一个跨平台的移动数据库引擎。

Realm 中文文档

Realm平台是基于noSQL的服务器和客户端组件的组合,该组件通过快速高效的同步协议进行连接,以实现实时,连接的应用程序和服务,无论网络状态如何,它们都具有响应能力和性能。Realm平台具有两个主要组件:Realm数据库和Realm对象服务器。这两个组件协同工作以自动同步数据,从而实现大量用例,从离线优先应用程序,现场服务和数据收集应用程序,以数据可用性和用户响应能力为关键的移动服务开始。此外,通过与现有后端(SQL,Kafka等)的集成功能,Realm Platform是一种在利用现有(有时是传统)系统和数据源的同时构建现代实时服务体验的绝佳方法。

领域平台的高级示意图

Realm数据库嵌入在客户端上,是一个功能齐全的,面向对象的跨平台数据库,可将数据本地存储在设备上。它适用于主要的移动语言,例如Swift和Objective-C(iOS),Java(Android),C#(Xamarin,.NET)和JavaScript(React Native和Node.js)。

Realm数据库是轻量级且高性能的,能够处理非常大的数据负载并在几分之一秒内运行查询。它基于共享的活动对象,无需编写网络,序列化或对象关系映射代码,即可与Realm Object Server实时无缝同步数据。

Realm 性能优于 FMDB 和 Core Data,支持 OC 和 Swift 语言开发,使用更加简单、方便。

下面主要说下Swift语言下的 Realm 数据库的使用和 RealmSwift 数据迁移

二. Cocopods 安装

pod 'RealmSwift'

三. 数据模型

不再详述了,具体可参考中文官方文档-数据模型

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") 不存在:必须是非可空值

四. 数据迁移

当您使用任意一个数据库时,您随时都可能打算修改您的数据模型。由于 Realm 的数据模型是以标准的 Swift 类来定义的,这使得修改模型就像修改其他的 Swift 类一样方便。

例如在1.0.1版本定义的 Person,现在需要在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 = ""
}

如下是具体处理这类问题的实现方式

// Swift 数据库管理器中的init()方法中做数据迁移
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
         * !!! 注意 !!!
         * 在打包定义版本的时候,版本规则:
         * 1.版本号只能是三位,如1.12.18,中间只能两个小数点;相反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


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容