我需要为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:
错误:&#39;尝试!&#39;表达式意外地引发了错误:错误Domain = io.realm Code = 0&#34;提供的架构版本0小于上次设置的版本1。&#34; UserInfo = 0x170660c00 {NSLocalizedDescription =提供的架构版本0小于上次设置的版本1.}:file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.0.59/src/swift/stdlib/public/ core / ErrorType.swift,第50行
它似乎正在读取错误的配置文件,我怀疑错误是由于 Realm.Configuration.defaultConfiguration = config
如何设置Other Realm
的配置?
编辑2:
我让我的
的名称和路径default realm
包含other realm
编辑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 =&lt; NSMallocBlock :0x170451220&gt ;; dynamic = 0; customSchema =(null); } oldSchemaVersion 0
非常感谢!
编辑5:解决我的问题
如果我直接将
StringTimestamp object
分配给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
感谢大家的指导! :)
答案 0 :(得分:0)
为什么不让领域使用默认配置?由于您将默认配置中的路径设置为getRealmPath()
,因此只需执行以下操作:
let realm = try! Realm()
通过使用Realm(path: getRealmPath())
实例化域,您将覆盖先前设置的defaultConfiguration
。也就是说,领域的路径变为getRealmPath()
,但您在config
中设置的所有其他属性都将丢失,而是使用默认值。其中包括schemaVersion = 0
和migrationBlock = nil
。
Realm(path:)
和Realm(configuration:)
等初始化程序的目的是允许您使用默认值以外的替代配置。如果你想要的是使用默认配置的修改版本,那么你需要做以下几点:
// Get a copy of the default configuration
var otherConfig = Realm.Configuration.defaultConfiguration
// Update the copy with what you need
otherConfig.path = "/some/path/otherRealm.realm"
// Use the updated configuration to instantiate a realm
let otherRealm = try! Realm(configuration: otherConfig)
调试域配置问题的一种巧妙方法是在实例化域之前设置断点或打印日志。运行以下代码可以让我知道要使用的默认配置是什么。
print(Realm.Configuration.defaultConfiguration))
let realm = try! Realm()
输出类似于
Realm.Configuration {
path = /Users/<full-path-omitted>/edman.realm;
schemaVersion = 2;
migrationBlock = <__NSMallocBlock__: 0x7faee04ac590>;
// other properties...
}
通过查看它我确定我的领域使用edman.realm
,schemaVersion = 2
的路径进行了实例化,并且它具有非零migrationBlock
。
答案 1 :(得分:0)
每当架构更新时,您必须在架构配置中将架构版本更新为更大的值。也就是说,在updateRealm()
函数
let config = Realm.Configuration(
path: getRealmPath(),
schemaVersion: 3, // any value larger than previous version
migrationBlock: { /* ... */}
})
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm()
来自realm docs。
您可以通过设置来定义迁移和关联的架构版本
Realm.Configuration.schemaVersion
和Realm.Configuration.migrationBlock
。使用此配置创建Realm时,如果需要迁移,则将应用迁移块将Realm更新为给定的架构版本。
您正确设置了迁移块,但未更新架构版本。这就是迁移块未被执行的原因,尽管它在您的配置中提供。
磁盘版本与配置版本之间的差异是触发migrationBlock
的原因。
答案 2 :(得分:0)
Swift 3.0解决方案
class func realmConfigs(_ realmName: String) -> RealmSwift.Realm.Configuration?{
var config = Realm.Configuration()
config.readOnly = true
// Use the default directory, but replace the filename with the username
let fileURLString = Bundle.main.path(forResource: realmName, ofType: "realm")
guard fileURLString != nil else {
return nil
}
config.fileURL = URL(string: fileURLString!)
config.schemaVersion = UInt64(1.0)
// Set this as the configuration used for the default Realm
return config
}
将会像这样使用
var realm : Realm?
do{
let config = realmConfigs("FILE_NAME")
Realm.Configuration.defaultConfiguration = config!
realm = try Realm(fileURL: realmURL)
}
catch {
print("Opening realm file error: \(error)")
}