0

我需要为我的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!
    }  
}

我通过这种方法(称为 inside 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:

错误:“试试!” 表达式意外引发错误:错误域 = io.realm 代码 = 0“提供的架构版本 0 小于上次设置的版本 1。” UserInfo=0x170660c00 {NSLocalizedDescription=提供的架构版本 0 小于上次设置的版本 1.}:文件 /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.0.59/src/swift/stdlib/public/核心/ErrorType.swift,第 50 行

它似乎正在读取错误的配置文件,我怀疑错误是由于Realm.Configuration.defaultConfiguration = config我如何设置配置Other Realm

编辑2:

我让我default realm的 to 包含我的名称和路径other realm

编辑4:

看来配置文件是正确的。如果没有来自旧领域的客户记录,我可以毫无问题地运行该应用程序。只有在旧领域有客户记录时才会崩溃。我可以从oldObject["firstName"]

print(Realm.Configuration.defaultConfiguration)

Realm.Configuration { 路径 = /var/mobile/Containers/Data/Application/8670C084-75E7-4955-89FB-137620C9B00D/Documents/perwyl.realm; inMemoryIdentifier = (null); 加密密钥 = (null); 只读 = 0; 架构版本 = 2; 迁移块 = < NSMallocBlock : 0x170451220>; 动态 = 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 

感谢大家的指导!:)

4

3 回答 3

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)")
    }
于 2017-01-04T12:44:52.850 回答
0

为什么不让领域使用默认配置?由于您将默认配置中的路径设置为getRealmPath(),因此应该可以:

 let realm = try! Realm()

通过与您一起实例化领域Realm(path: getRealmPath())您将覆盖defaultConfiguration您之前设置的领域。也就是说,领域的路径变为getRealmPath(),但您设置的所有其他属性config都丢失了,而是使用默认值。这包括schemaVersion = 0migrationBlock = 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.realmschemaVersion = 2并且它具有非 nil migrationBlock

于 2015-10-22T03:58:06.550 回答
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.Configuration.schemaVersion您可以通过设置和 来定义迁移和关联的架构版本 Realm.Configuration.migrationBlock

使用此配置创建 Realm 时,如果需要迁移,将应用迁移块将Realm 更新到给定的模式版本

您正确设置了迁移块,但没有更新架构版本。这就是为什么没有执行迁移块的原因,尽管它在您的配置中提供。

磁盘中的版本和配置中的版本之间的差异是触发的migrationBlock

于 2015-10-22T17:57:40.117 回答