You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm Swift迁移问题:String包装类集合转原生String集合

解决方案:Realm Swift 从包装类集合迁移到原生字符串集合

问题根源

在Realm迁移块中,enumerateObjects返回的旧对象是MigrationObject类型,而非你定义的StringDB或MyObjDB实例,直接强转成List<StringDB>必然失败。

官方推荐的迁移实现

修改迁移代码,通过键值访问旧集合中每个对象的stringVal属性,无需强转成自定义类:

let config = Realm.Configuration(schemaVersion: latestSchemaVersion, migrationBlock: {
    migration, version in
    if version < 2 {
        migration.enumerateObjects(ofType: MyObjDB.className()) { old, new in
            guard let old = old, let new = new else { return }
            
            // 获取旧集合,类型为MigrationObject的List
            guard let oldEmails = old["emails"] as? List<MigrationObject> else { return }
            let newEmails = List<String>()
            
            for emailObj in oldEmails {
                // 直接通过键值访问包装类的stringVal属性
                if let emailStr = emailObj["stringVal"] as? String {
                    newEmails.append(emailStr)
                }
            }
            
            new["emails"] = newEmails
        }
    }
})

关键说明

  • 旧集合的类型是List<MigrationObject>,而非List<StringDB>:这是Realm迁移机制的设计,迁移时操作的是底层数据模型,而非你的自定义Swift类。
  • 无需依赖字符串拼接+正则提取的不稳定方案,键值访问属性是官方支持的安全方式,完全可用于生产环境。
  • 迁移完成后,务必更新MyObjDB的定义,将emails改为原生字符串集合:
class MyObjDB: Object {
    var emails: List<String> = List<String>() // 替换为原生String集合
    @objc dynamic var id: String = UUID().uuidString

    // 更新便利初始化器,适配String类型
    convenience init(_ emails: [String]) {
        self.init()
        self.emails.append(objectsIn: emails)
    }

    override static func primaryKey() -> String? {
        return "id"
    }
}

内容的提问来源于stack exchange,提问作者Dan Schey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:55:23