2

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

2
  • Two things. 1) You can't alter, change or monkey with Realm in any way once your app 'talks' to it. So if there are any calls to realm (of any kind) that happen prior to didFinishLaunchingWithOptions then it won't work. 2) This may be a sandboxing issue, does your app have access to the folder being written to? Commented May 6, 2020 at 17:54
  • Thanks @Jay I’m a beginner developer so I maybe wrong but if didFinishLaunchingWithOptions runs before viewDidLoad, I guess this is the first call to realm. For 2) I believe so as App Group folder is place for sharing data with today extension apps? Did I have to do additional work for getting access to this path? Sorry for being not so helpful to your questions Commented May 6, 2020 at 18:07

1 Answer 1

5

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()

Sign up to request clarification or add additional context in comments.

1 Comment

You should use originalPath.path instead of absoluteString to make it work in my experience.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.