Search code examples
iosswiftiphonerealm

Copy existing Realm database file to App Group location for today extension


My iOS app is using Realm database I want to copy or move the current default.realm database file to the new directory (App Group location) so that I can share it with Today Extension widget.

I tried as this post says (How to transfer Realm database to appgroups)

The core code is

let fileManager = FileManager.default
let originalPath = Realm.Configuration.defaultConfiguration.fileURL!
let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.myApp")!.appendingPathComponent("default.realm")
do{
    try fileManager.replaceItemAt(appGroupURL, withItemAt: originalPath)
}
catch{
    print("Error information: \(error)")
}

And I put this code inside Realm migration scope inside didFinishLaunchingWithOptions as below To give you clearer picture where I'm using this code.


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    var config = Realm.Configuration(
        schemaVersion: 1,
        migrationBlock: { migration, oldSchemaVersion in
            if (oldSchemaVersion < 1) {
                let fileManager = FileManager.default
                let originalPath = Realm.Configuration.defaultConfiguration.fileURL!
                let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.myApp")!.appendingPathComponent("default.realm")
                do{
                    try fileManager.replaceItemAt(appGroupURL, withItemAt: originalPath)
                }
                catch{
                    print("Error information: \(error)")
                }
            }
    }
    )
}


When I try this, my console says the file couldn't be saved.

Error Domain=NSCocoaErrorDomain Code=512 "The file “default.realm” couldn’t be saved in the folder “2EEADCEE-F9D9-44A8-BDED-B60A689656A2”." UserInfo={NSFileOriginalItemLocationKey=file:///Users/jm/Library/Developer/CoreSimulator/Devices/38334AE3-6648-402E-AC18-8252426002D6/data/Containers/Shared/AppGroup/2EEADCEE-F9D9-44A8-BDED-B60A689656A2/default.realm, ......

I heard copy / moving Realm database file should be done before opening the file, is this error related to that?

Thanks for your help and have a great day


Solution

  • Thank you @Jay for commenting which helped my find a way.

    As he mentioned moving Realm DB file should be done before we call anything related to the Realm.

    Originally I had a code inside of Realm migration so that it will run only once when the schema version is older,

    but I moved it outside, top of the didFinishLaunchingWithOptions so now it works moving Realm DB file to the different directory.

    Hope this helps somebody who's struggling.

    
    let fileManager = FileManager.default
    let originalPath = Realm.Configuration.defaultConfiguration.fileURL!
    let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myApp")!.appendingPathComponent("default.realm")
    if fileManager.fileExists(atPath: originalPath.absoluteString) {
        do{
            try fileManager.replaceItemAt(appGroupURL, withItemAt: originalPath)
            print("Successfully replaced DB file")
        }
        catch{
            print("Error info: \(error)")
        }
    } else {
        print("File is not exist on original path")
    }
    
    
    var config = Realm.Configuration(
    )
    config.fileURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myApp")!.appendingPathComponent("default.realm")
    
    // Tell Realm to use this new configuration object for the default Realm
    Realm.Configuration.defaultConfiguration = config
    
    // Now that we've told Realm how to handle the schema change, opening the file
    // will automatically perform the migration
    let realm = try! Realm()