web-dev-qa-db-ja.com

完全なレルムデータベースをクリアする

私はレルム(現在は0.85.0)で遊んでおり、私のアプリケーションはデータベースを使用して、現在のユーザーの連絡先などのユーザー固有のデータを保存します。ユーザーがログアウトすることを決定した場合、ユーザーに関するすべての情報を削除する必要がありますが、私の意見では最も明確でシンプルでクリーンなことは、領域全体を消去することです。残念ながら、Cocoa libはその機能を提供していません。

現在、私は次のことにこだわっています

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

より良いアイデアはありますか?

ありがとう

38
floriankrueger

更新:

投稿以来、すべてのオブジェクトを削除するための新しいメソッドが追加されました(jpsimで既に述べたように)。

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


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

これらのメソッドはデータ構造を変更しないことに注意してください。既存のレコードのみを削除します。移行を記述せずにレルムモデルのプロパティを変更する場合(つまり、開発中の場合のように)、以下の古いソリューションが引き続き有用です。

元の答え:

REST response =を格納するためのサンプルコード)で行うように、単にレルムファイル自体を削除できます

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

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

    //...
}

コメントに関する更新:

レルムデータベースが使用されていないことを確認する必要がある場合は、レルムの通知を使用できます。各書き込みの前にopenWritesカウンターをインクリメントする場合、各書き込みが完了するとブロックを実行できます。

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:フラグを使用した単純なリセット

上記の回答を試しましたが、移行する代わりにレルムファイルを削除するもう1つの簡単な方法を投稿しました。

_Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true
_

これは、Realmがtry! Realm()でクラッシュするのではなく、既存のファイルを削除できるようにフラグを設定するだけです

ファイルを手動で削除する代わりに

上記の回答のSwiftバージョンよりも簡単だと思った:

_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

レルム .87. の時点で、書き込みトランザクションから_[[RLMRealm defaultRealm] deleteAllObjects]_を呼び出すことにより、すべてのレルムの内容を削除できるようになりました。

Swiftからは、次のようになります:RLMRealm.defaultRealm().deleteAllObjects()

11
jpsim

Swiftでこれを行う方法を探している人がこの質問に出くわした場合、これはDonamiteIsTntの答えを書き換えただけです。この関数をカスタムユーティリティクラスに追加したので、テストとデバッグ中にMyAppUtilities.purgeRealm()を実行できます

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

注:データを消去する必要がある場合は、Realmの新しいrealm.addOrUpdateObject()機能をチェックして、既存のデータを主キーで新しいデータに置き換えることができます。この方法では、新しいデータを継続的に追加することはありません。 「古い」データを置き換えるだけです。 addOrUpdateObject()を使用する場合は、モデルのprimaryKeyクラス関数をオーバーライドして、Realmがどのプロパティが主キーであるかを認識していることを確認してください。 Swiftでは、たとえば:

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

私はこの楽しい小さな問題に遭遇しました。その代わり、スキーマ移行を実行する前に、スキーマバージョンを直接照会しました。

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

また、レルムファイルが保存されている場所に移動し、そこからそのファイルを削除し、アプリを実行した後に次回レルムを開くと、ブラウザに空のレルムデータベースが表示されます。

0
Prathma Rastogi