清除完整的Realm数据库
我玩的领域(目前是0.85.0),我的应用程序使用数据库来存储用户特定的数据,如当前用户的联系人。 当用户决定注销时,我需要删除关于用户的每一点信息,而在我看来,最明显,最简单,最干净的事情就是擦除整个领域。 不幸的是,Cocoa lib没有提供这个function。
目前,我坚持以下
RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm deleteObjects:[MyRealmClass1 allObjectsInRealm:realm]]; [realm deleteObjects:[MyRealmClass2 allObjectsInRealm:realm]]; [realm deleteObjects:[MyRealmClass3 allObjectsInRealm:realm]]; [realm commitWriteTransaction];
任何更好的想法?
谢谢
更新:
自发布以来,添加了一个新的方法来删除所有对象(如jpsim已经提到):
// Obj-C [realm beginWriteTransaction]; [realm deleteAllObjects]; [realm commitWriteTransaction]; // Swift try! realm.write { realm.deleteAll() }
请注意,这些方法不会改变数据结构; 他们只删除现有的logging。 如果您希望在不写入迁移的情况下改变领域模型属性(即,您可能正在开发中),则以下旧解决scheme可能仍然有用。
原始答案:
您可以简单地删除领域文件本身,就像在存储REST响应的示例代码中一样 :
- (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]; } } }];
从领域0.87.0开始 ,现在可以通过从写事务中调用[[RLMRealm defaultRealm] deleteAllObjects]
来删除所有的领域内容。
从Swift看起来像这样: RLMRealm.defaultRealm().deleteAllObjects()
RealmSwift:使用标志简单重置
试过了上面的答案,但发布了一个更简单的方法来删除领域文件,而不是迁移:
Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true
这只是设置一个标志,使Realm可以删除现有的文件,而不是try! Realm()
崩溃try! 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") }
如果有人在这个问题上磕磕绊绊寻找一种方法来在Swift中做到这一点,这只是DonamiteIsTnt的答案重写。 我已经将此函数添加到自定义实用程序类,以便在testing和debugging期间执行MyAppUtilities.purgeRealm()
func purgeRealm() { NSFileManager.defaultManager().removeItemAtPath(RLMRealm.defaultRealmPath(), error: nil) }
注意:如果您发现自己需要清除数据,您可能只需查看Realm的新realm.addOrUpdateObject()
function,该function允许您将现有数据的主键replace为新数据。 这样你不会不断地添加新的数据。 只是取代“旧”的数据。 如果使用addOrUpdateObject()
确保覆盖模型的primaryKey
类函数,那么Realm知道哪个属性是您的主键。 在Swift中,例如:
override class func primaryKey() -> String { return "_id" }
我遇到了这个有趣的小问题。 因此,我直接在运行schemamigration之前查询模式版本。
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) { }];