J'ai un objet NotSureItem
dans lequel j'ai trois propriétés title
dont le nom est renommé en text
et textDescription
que j'avais ajouté plus tard et une propriété dateTime
. Maintenant, lorsque je vais exécuter mon application, elle se bloque lorsque je veux ajouter quelque chose à ces propriétés. Il montre les déclarations suivantes.
'Migration is required for object type 'NotSureItem' due to the following errors:
- Property 'text' is missing from latest object model.
- Property 'title' has been added to latest object model.
- Property 'textDescription' has been added to latest object model.'
Voici mon code:
import Foundation
import Realm
class NotSureItem: RLMObject {
dynamic var title = "" // renamed from 'text'
dynamic var textDescription = "" // added afterwards
dynamic var dateTime = NSDate()
}
Tant que vous n'avez pas publié votre application , vous pouvez simplement supprimer votre application et l'exécuter à nouveau.
Chaque fois que vous modifiez les propriétés de vos objets Realm, votre base de données existante devient incompatible avec le nouveau.
Tant que vous en êtes encore au stade du développement, vous pouvez simplement supprimer l’application du simulateur/appareil et la redémarrer.
Une fois votre application publiée et si vous modifiez les propriétés de vos objets, vous devez implémenter une migration vers la nouvelle version de la base de données.
Pour effectuer réellement une migration, vous implémentez un bloc de migration de royaume. En règle générale, vous ajoutez le bloc à application(application:didFinishLaunchingWithOptions:)
:
var configuration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 1 {
// if just the name of your model's property changed you can do this
migration.renameProperty(onType: NotSureItem.className(), from: "text", to: "title")
// if you want to fill a new property with some values you have to enumerate
// the existing objects and set the new value
migration.enumerateObjects(ofType: NotSureItem.className()) { oldObject, newObject in
let text = oldObject!["text"] as! String
newObject!["textDescription"] = "The title is \(text)"
}
// if you added a new property or removed a property you don't
// have to do anything because Realm automatically detects that
}
}
)
Realm.Configuration.defaultConfiguration = configuration
// opening the Realm file now makes sure that the migration is performed
let realm = try! Realm()
Chaque fois que votre schéma change, vous devez augmenter la schemaVersion
dans le bloc de migration et mettre à jour la migration nécessaire dans le bloc.
Supprimer l'application et la réinstaller n'est pas une bonne pratique. Nous devrions intégrer certaines étapes de la migration au cours du développement dès la première fois que nous rencontrons un besoin de migration. Le lien donné par SilentDirge est bon: document de migration de royaume , qui donne de bons exemples pour la gestion de situations différentes.
Pour une tâche de migration minimale, l'extrait de code suivant provenant du lien ci-dessus peut effectuer automatiquement la migration et doit être utilisé avec la méthode disFinishLaunchWithOptions
de AppDelegate:
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
// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let _ = try! Realm()
Le code ci-dessous fonctionne pour moi
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 2;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
// The enumerateObjects:block: method iterates
// over every 'Person' object stored in the Realm file
[migration enumerateObjects:Person.className
block:^(RLMObject *oldObject, RLMObject *newObject) {
// Add the 'fullName' property only to Realms with a schema version of 0
if (oldSchemaVersion < 1) {
newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
oldObject[@"firstName"],
oldObject[@"lastName"]];
}
// Add the 'email' property to Realms with a schema version of 0 or 1
if (oldSchemaVersion < 2) {
newObject[@"email"] = @"";
}
}];
};
[RLMRealmConfiguration setDefaultConfiguration:config];
// now that we have updated the schema version and provided a migration block,
// opening an outdated Realm will automatically perform the migration and
// opening the Realm will succeed
[RLMRealm defaultRealm];
return YES;
}
Plus d'infos: https://realm.io/docs/objc/latest/#getting-started
Votre base de données modifiée n'est plus compatible avec la base de données enregistrée, c'est pourquoi une migration est requise. Vous avez le choix entre supprimer l’ancien fichier de base de données et recommencer à zéro (fonctionne très bien si vous êtes dans la phase de développement initiale), ou si vous êtes en direct, effectuez la migration.
Pour ce faire, vous définissez une version de schéma et fournissez un "script" de migration de base de données dans votre configuration de royaume. L'ensemble du processus est documenté ici (avec des exemples de code): ici
Vous pouvez effacer la base de données au lancement de la manière suivante:
[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];
var 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: 2,
// 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
}
})
do{
realm = try Realm(configuration: config)
print("Database Path : \(config.fileURL!)")
}catch{
print(error.localizedDescription)
}