清除完整的Realm数据库

时间:2014-09-26 19:44:54

标签: ios realm

我正在使用领域(目前为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];

任何更好的想法?

感谢

6 个答案:

答案 0 :(得分:47)

<强>更新

自发布以来,添加了一个新方法来删除所有对象(正如jpsim已经提到的那样):

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


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

请注意,这些方法不会改变数据结构;他们只删除现有记录。如果您希望在不编写迁移的情况下更改领域模型属性(即,正如您在开发中所做的那样),下面的旧解决方案可能仍然有用。

原始答案:

您可以简单地删除领域文件本身,就像他们在sample code for storing a 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];
        }
    }
}];

答案 1 :(得分:11)

从领域0.87.0开始,现在可以通过从写入事务中调用[[RLMRealm defaultRealm] deleteAllObjects]来删除所有领域内容。

来自Swift,它看起来像这样:RLMRealm.defaultRealm().deleteAllObjects()

答案 2 :(得分:10)

RealmSwift:使用标志进行简单重置

尝试了上述答案,但发布了一种更简单的方法来删除领域文件而不是迁移:

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")
}

答案 3 :(得分:5)

如果有人在这个问题上绊倒寻找在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"
}

答案 4 :(得分:1)

我遇到了这个有趣的小问题。所以我在运行schemamigration之前直接查询了模式版本。

angular.module('app.controllers.home',[])
.controller("HomeCtrl", function($scope, $location, $http) {
$scope.directory = 'files/';
$.ajax({
    url : $scope.directory + 'file.html',
    type : "GET",
    dataType : "html",
    success : function(data) {
        // that works
        var jData = $(data);
        jData.find('a.link').click(function(e){
            $scope.loadElem();
        });
        $('#panel').html(jData);
    },
    error : function(data) {
        alert('1st fail');
    }
});
setTimeout(function(){
    alert('second call');
    // that fails, goes to the .error
    $http.get($scope.directory + 'file.html').
      success(function(data, status, headers, config) {
        alert("2nd pass");
      }).
      error(function(data, status, headers, config) {
        alert("2nd fail");
      }); }, 3000);

$scope.loadElem(){
    // that fails, goes to the .error
    $.ajax({
        url : $scope.directory + 'file.html',
        type : "GET",
        dataType : "html",
        success : function(data) {
            alert('3rd pass')
        },
        error : function(data) {
            alert('3rd fail');
        }
    });
}
}

答案 5 :(得分:0)

您还可以转到领域文件的存储位置,从该位置删除该文件,并在运行应用程序后下次打开领域时,将在浏览器中看到空的领域数据库。