我需要为我的 Other Realm
进行迁移 .
我通过这种方法获得我的领域路径( AppDelegate
) . 如果用户之前登录,我将检索用户的领域,否则我将使用 Default Realm
.
func getRealmPath() -> String {
let preferences : NSUserDefaults = NSUserDefaults()
let username = preferences.objectForKey(usernameKey) as! String?
if username != nil {
let realmName = ("\(username!).realm")
print("RealmName: \(realmName)", terminator: "")
let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
return documents.stringByAppendingPathComponent(realmName)
}else{
return Realm.Configuration.defaultConfiguration.path!
}
}
我通过这种方法进行了迁移(在 AppDelegate:didFinishLaunchingWithOptions
中调用) .
func updateRealm(){
let config = Realm.Configuration(path: getRealmPath(), schemaVersion: 2, migrationBlock: { (migration, oldSchemaVersion) -> Void in
print("oldSchemaVersion \(oldSchemaVersion)")
migration.create("RLMStringTimestamp", value: ["pKey": NSUUID().UUIDString, "value": "", "updatedAt": NSDate(), "createdAt": NSDate(), "deletedAt": Date().getInitDate(), "updatedBy" : " ", "syncedAt": NSDate() ])
if oldSchemaVersion < 2 {
//MIGRATION
let firstNameTimeStamp = RLMStringTimestamp(newValue: oldObject!["firstName"] as? String)
migration.create("RLMStringTimestamp", value: firstNameTimeStamp)
newObject!["firstName"] = firstNameTimeStamp
}
}
Realm.Configuration.defaultConfiguration = config
//EDIT 2
Realm.Configuration.defaultConfiguration.path = getRealmPath()
//EDIT 1
//<strike>let realm = try! Realm(path: getRealmPath())</strike>
//EDIT 4
print(Realm.Configuration.defaultConfiguration)
//EDIT 3
let realm = try! Realm()
}
对于我的RLMCustomer对象,我将var firstName:String =“”修改为var firstName:RLMStringTimeStamp!
即使我将schemaVersion更改为非常高的值,migrationBlock也没有得到调用 . 任何人都可以帮助我发现我错过了什么或做错了什么?
运行应用程序后,它与 bad excess, code = 257
崩溃
编辑1:
错误:'试试!'表达式意外地引发了错误:错误Domain = io.realm Code = 0“提供的架构版本0小于上次设置的版本1” . UserInfo = 0x170660c00 :file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.0.59/src/swift/stdlib/public/ core / ErrorType.swift,第50行
它似乎正在读取错误的配置文件,我怀疑错误是由于Realm.Configuration.defaultConfiguration = config如何设置其他Realm的配置?
编辑2:
我使我的默认领域包含我的其他领域的名称和路径
编辑4:
似乎配置文件是正确的 . 如果在旧领域有客户记录,我可以毫无问题地运行应用程序 . 我可以从 oldObject["firstName"]
获取值
print(Realm.Configuration.defaultConfiguration)
Realm.Configuration {path = /var/mobile/Containers/Data/Application/8670C084-75E7-4955-89FB-137620C9B00D/Documents/perwyl.realm; inMemoryIdentifier =(null); encryptionKey =(null); readOnly = 0; schemaVersion = 2; migrationBlock = <NSMallocBlock:0x170451220>; dynamic = 0; customSchema =(null); } oldSchemaVersion 0
非常感谢!!!
编辑5:解决我的问题
如果我将StringTimestamp对象直接分配给newObject,我不确定为什么会崩溃 .
let firstName = (oldObject!["firstName"] as? String)!
let firstNameTimeStamp = StringTimestamp(newValue: firstName)
let testName = migration.create("StringTimestamp",value: firstNameTimeStamp)
newObject!["firstName"] = firstNameTimeStamp //Crashes
newObject!["firstName"] = testName //works
感谢大家的指导! :)
3 回答
为什么不让领域使用默认配置?由于您将默认配置中的路径设置为
getRealmPath()
,因此可以执行以下操作:通过使用
Realm(path: getRealmPath())
实例化域,您将覆盖先前设置的defaultConfiguration
. 也就是说,领域的路径变为getRealmPath()
,但是您在config
中设置的所有其他属性都将丢失,而是使用默认值 . 这包括schemaVersion = 0
和migrationBlock = nil
.初始化程序(如
Realm(path:)
和Realm(configuration:)
)的目的是允许您使用默认值以外的替代配置 . 如果你想要的是使用默认配置的修改版本,那么你需要在以下方面做一些事情:调试领域配置问题的一种巧妙方法是在实例化领域之前设置断点或打印日志 . 运行以下代码可以让我知道要使用的默认配置是什么 .
输出看起来像
通过查看它我确定我的领域是用
edman.realm
,schemaVersion = 2
的路径实例化的,并且它具有非零migrationBlock
.每当架构更新时,您必须在架构配置中将架构版本更新为更大的值 . 也就是说,在你的
updateRealm()
函数中来自realm docs .
您正确设置了迁移块,但未更新架构版本 . 这就是迁移块未被执行的原因,尽管它在您的配置中提供 .
磁盘中的版本与配置中的版本之间的差异是触发
migrationBlock
的原因 .Swift 3.0解决方案
并将像这样使用