web-dev-qa-db-fra.com

Effacer la base de données complète du royaume

Je joue avec le domaine (actuellement 0.85.0) et mon application utilise la base de données pour stocker des données spécifiques à l'utilisateur telles que les contacts de l'utilisateur actuel. Lorsque l'utilisateur décide de se déconnecter, je dois supprimer chaque bit d'informations sur l'utilisateur et la chose la plus évidente, simple et propre à mon avis serait d'effacer le domaine complet. Malheureusement, la bibliothèque Cocoa ne fournit pas cette fonctionnalité.

Actuellement, je suis coincé avec ce qui suit

RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm deleteObjects:[MyRealmClass1 allObjectsInRealm:realm]];
[realm deleteObjects:[MyRealmClass2 allObjectsInRealm:realm]];
[realm deleteObjects:[MyRealmClass3 allObjectsInRealm:realm]];
[realm commitWriteTransaction];

de meilleures idées?

merci

38
floriankrueger

Mise à jour:

Depuis la publication, une nouvelle méthode a été ajoutée pour supprimer tous les objets (comme jpsim l'a déjà mentionné):

// Obj-C
[realm beginWriteTransaction];
[realm deleteAllObjects];
[realm commitWriteTransaction];


// Swift
try! realm.write {
  realm.deleteAll()
}

Notez que ces méthodes ne modifieront pas la structure des données; ils suppriment uniquement les enregistrements existants. Si vous cherchez à modifier les propriétés du modèle de domaine sans écrire de migration (c'est-à-dire, comme vous pourriez le faire en développement), l'ancienne solution ci-dessous peut toujours être utile.

Réponse originale:

Vous pouvez simplement supprimer le fichier de domaine lui-même, comme ils le font dans leur exemple de code pour stocker une REST :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //...

    // Ensure we start with an empty database
    [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:nil];

    //...
}

Mise à jour concernant votre commentaire:

Si vous devez vous assurer que la base de données du domaine n'est plus utilisée, vous pouvez utiliser les notifications du domaine. Si vous deviez incrémenter un compteur openWrites avant chaque écriture, vous pourriez exécuter un bloc à la fin de chaque écriture:

self.notificationToken = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
    if([notification isEqualToString:RLMRealmDidChangeNotification]) {
        self.openWrites = self.openWrites - 1;

        if(!self.openWrites && self.isUserLoggedOut) {
            [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:nil];
        }
    }
}];
49
DonVaughn

RealmSwift: réinitialisation simple à l'aide d'un indicateur

J'ai essayé les réponses ci-dessus, mais en publiant un moyen plus simple de supprimer le fichier de domaine au lieu de migrer:

Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true

Cela définit simplement un indicateur afin que Realm puisse supprimer le fichier existant plutôt que de planter sur try! Realm()

Au lieu de supprimer manuellement le fichier

Je pensais que c'était plus simple que la version Swift de la réponse ci-dessus:

guard let path = Realm.Configuration.defaultConfiguration.fileURL?.absoluteString else {
    fatalError("no realm path")
}

do {
    try NSFileManager().removeItemAtPath(path)
} catch {
    fatalError("couldn't remove at path")
}
11
jonchoi

Depuis le domaine .87. , il est maintenant possible de supprimer tout le contenu du domaine en appelant [[RLMRealm defaultRealm] deleteAllObjects] À partir d'une transaction d'écriture.

De Swift, cela ressemble à ceci: RLMRealm.defaultRealm().deleteAllObjects()

11
jpsim

Au cas où quelqu'un trébuche sur cette question à la recherche d'un moyen de le faire dans Swift, c'est juste la réponse de DonamiteIsTnt réécrite. J'ai ajouté cette fonction à une classe d'utilitaires personnalisée pour pouvoir faire MyAppUtilities.purgeRealm() pendant les tests et le débogage

func purgeRealm() {
    NSFileManager.defaultManager().removeItemAtPath(RLMRealm.defaultRealmPath(), error: nil)
}

Remarque: Si vous avez besoin d'effacer des données, vous pouvez simplement consulter la nouvelle fonctionnalité realm.addOrUpdateObject() de Realm qui vous permet de remplacer les données existantes par leur clé primaire par les nouvelles données. De cette façon, vous n'ajoutez pas continuellement de nouvelles données. Il suffit de remplacer les "anciennes" données. Si vous utilisez addOrUpdateObject() assurez-vous de remplacer la fonction de classe primaryKey de votre modèle afin que Realm sache quelle propriété est votre clé primaire. Dans Swift, par exemple:

override class func primaryKey() -> String {
    return "_id"
}
6
Glen Selle

Je suis tombé sur ce petit problème amusant. Au lieu de cela, j'ai interrogé la version du schéma directement avant d'exécuter la migration de schémas.

NSError *error = NULL;
NSUInteger currentSchemaVersion = [RLMRealm schemaVersionAtPath:[RLMRealm defaultRealmPath] error:&error];
if (currentSchemaVersion == RLMNotVersioned) {
    // new db, skip

} else if (currentSchemaVersion < 26) {
    // kill local db
    [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:&error];
    if (error) {
        MRLogError(error);
    }

} else if (error) {
    // for good measure...
    MRLogError(error);
}

// perform realm migration
[RLMRealm setSchemaVersion:26
            forRealmAtPath:[RLMRealm defaultRealmPath]
        withMigrationBlock:^(RLMMigration *migration, NSUInteger oldSchemaVersion) {

        }];
1
Steve Pascoe

Vous pouvez également aller à l'emplacement où votre fichier de domaine est stocké, supprimer ce fichier à partir de là et la prochaine fois que vous ouvrirez le domaine après avoir exécuté l'application, vous verrez la base de données de domaine vide dans le navigateur.

0
Prathma Rastogi