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
相关产品推荐
相关产品推荐

