Run Migration on synced Realm - ios

I've created a new object model and when I open my app I get the following error:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Invalid class subset list:
- 'Mod.generalSettings' links to class 'Setting', which is missing from the list of classes managed by the Realm
- 'Mod.contextSettings' links to class 'Setting', which is missing from the list of classes managed by the Realm
- 'Mod.accountSettings' links to class 'Setting', which is missing from the list of classes managed by the Realm'
I don't get this error when I shut down the Realm Object Server that holds my synced Realm. This is the config that runs on launch:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
syncConfiguration: (user, syncServerURL!),
objectTypes: [Dot.self, Mod.self, Setting.self])
This leads me to believe I need to run a migration for my remote realm. How can I do this?

You don't have direct access to Realm files on the server from the client. All you need to do is run a migration locally and the changes will be pushed up to the server.
If you're not deleting any columns, you can run a migration as simply as:
Realm.Configuration.defaultConfiguration = Realm.Configuration(
syncConfiguration: (user, syncServerURL!),
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in },
objectTypes: [Dot.self, Mod.self, Setting.self])
I hope that helps!

Related

RealmSwift downgrade migration

Is it possible to detect the user is installing an app version with an older db schema version? (downgrading the app version basically)
Want to know if it is possible to detect and delete the current db file so that the app can still recover from it instead of just crashing.
It is an odd scenario but it is happening (some beta testers and such).
Yes, you have access to the old schema version in the migrationBlock of Realm.Configuration, so just check whether the oldSchemaVersion stored on the device is actually higher than the one your current app version has and if so, delete all Realm files using Realm.deleteFiles(for:).
let currentSchemaVersion = 1
let config = Realm.Configuration(
schemaVersion: currentSchemaVersion,
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion > currentSchemaVersion) {
Realm.deleteFiles(for: Realm.Configuration.defaultConfiguration)
}
}
)
// Then set the config and create your `Realm` instance
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm()

Fatal Error :Can't open realm

I am working on IOS. I am using realm database in the frontend. It was working fine until I made some changes to the realm model and all files related to it. I just added one field to these files.
Now I am getting an error "Fatal error: Can't open realm" in the following code
fileprivate func getRealm() -> Realm {
// get default configuration realm
do {
return try Realm()
} catch {
Swift.fatalError("Can't open realm") //Fatal Error :Can't open realm
}
}
Can anyone tell what might be the possible causes for this error.
Thanks in advance.
If you made changes to the realm model, you need to increase your schema version and you may or may need to provide a migration block. See the official documentation for details.
// Inside your [AppDelegate didFinishLaunchingWithOptions:]
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
config.schemaVersion = 1;
// Set the block which will be called automatically when opening a Realm with a
// schema version lower than the one set above
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
// We haven’t migrated anything yet, so oldSchemaVersion == 0
if (oldSchemaVersion < 1) {
// Nothing to do!
// Realm will automatically detect new properties and removed properties
// And will update the schema on disk automatically
}
};
// Tell Realm to use this new configuration object for the default Realm
[RLMRealmConfiguration setDefaultConfiguration:config];
// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
[RLMRealm defaultRealm];
The above issue is caused due to inconsistency in the Realm database. I changed the structure of the model by adding one field. So, the model was having 10 fields but the realm database in my app was having 9 fields, as the app was built before the changes.
I solved the issue by just reinstalling the app which regenerated the realm database in the phone, thereby having a consistent model and database.
The above workaround might be good if your app is yet to be live. But, if your app is already being used by other users, then they will have to reinstall the app on update, which might result in bad user experience for the user.
Ideally, you should be writing a migration block for the new changes.
Hope, this is clear to all.

Realm , Object is already managed by another Realm

Use realm to save data.
Config the realm use defaultconfig.
then , I addOrUpdate some RLMModels
It's success.
I changed the config use
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:#"myname"] URLByAppendingPathExtension:#"realm"];
[RLMRealmConfiguration setDefaultConfiguration:config];
I addOrUpdate the same RLMModels
console print error:
2017-11-09 10:50:18.293801+0800 LNLibBase_Example[96588:8779968]
*** Terminating app due to uncaught exception 'RLMException',
reason: 'Object is already managed by another Realm.
Use create instead to copy it into this Realm.'
As the error message states, an object that is already managed by a Realm cannot be added to a different Realm. What you can do instead is create a copy of it in a different Realm using +createInRealm:withValue:.

Realm migration when using non-default configurations

In the realm docs I see the code example for migrations
let config = Realm.Configuration(
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
schemaVersion: 1,
// Set the block which will be called automatically when opening a Realm with
// a schema version lower than the one set above
migrationBlock: { migration, oldSchemaVersion in
// We haven’t migrated anything yet, so oldSchemaVersion == 0
if (oldSchemaVersion < 1) {
// Nothing to do!
// Realm will automatically detect new properties and removed properties
// And will update the schema on disk automatically
}
})
// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config
and then it says to use let realm = try! Realm() to get the realm instance. However, in our application we are using our own realm configurations with something like
let realm = try! Realm(configuration: RealmConfig.getConfig(typeURL: .userData)!)
We have a few different configurations besides .userData. My question is, how does one go about doing migrations with these non-default configurations? The code example really only shows how to set the default configuration which is insignificant for my use. I couldn't find anything like
Realm.Configuration.userData = config
Does something like this exist that I am missing? Or is there another way I'm supposed to go about this?
You can instantiate different Realm instances with different configurations like this:
let userDataConfiguration = Realm.Configuration(...)
let userDataRealm = try! Realm(configuration: userDataConfiguration)
Learn more in docs at https://realm.io/docs/swift/latest/#realms

AppStore update and Realm

I have application in Appstore based on Realm Mobile Database. I'd like to prepare version 1.1. Will update delete all data in user's local database ?
The upgrade won't delete anything on your current database. The migration is automatic. If you need to change one or more field in your current model, you need to upgrade the database schema version. Place this code into the application:didFinishLaunchingWithOptions: method in your AppDelegate:
//Realm migration
let config = Realm.Configuration(
schemaVersion: 2, //here's the schema version you need to change
migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < 2) {
//if you want to perform particular tasks
//while migrating, place your code here.
}
})
Realm.Configuration.defaultConfiguration = config
_ = try! Realm()
Absolutely not, It won't delete existing database, that's why Realm support automatic/custom migration.

Resources