Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Realm Swift iOS - safely deleting and re-keying an encrypted Realm

Tags:

ios

swift

realm

Does Realm Swift have some way to safely delete and create a new encrypted Realm file with a new key (but the same file name)?

My use case: when a user logs out of my app, I delete the encrypted .realm file, since the encryption key will also be deleted:

static func deleteRealm() {
  let configuration = Realm.Configuration()    
  let path = NSURL.fileURLWithPath(configuration.path!)     
                  .URLByDeletingLastPathComponent?
                  .URLByAppendingPathComponent("encrypted.realm")
                  .path!
  if NSFileManager.defaultManager().fileExistsAtPath(path) {
      // Delete realm
      try! NSFileManager.defaultManager().removeItemAtPath(path)
    }
  }
}

(Unfortunately, calling realm.deleteAll() will not suffice, since there's a new key)

But when another user logs in immediately after log out and I attempt to re-intialize an encrypted Realm DB with a new key, like this:

static func intializeRealm() -> Realm! {
    let realmKey = generateSecureRealmKey()
    var configuration = Realm.Configuration()
    configuration.path = RealmDB.getRealmPath()
    configuration.encryptionKey = NSData(bytes: realmKey, length: realmKey.count)
    return try! Realm(configuration: configuration)
  }

I get this exception:

    *** Terminating app due to uncaught exception 'RLMException', 
         reason: 'Realm at path '****/encrypted.realm' already opened
         with different encryption key'

It seems that the old configuration cache is still being used (since the filename is the same) even though the realm file has been deleted.

The sample encryption app for Realm Swift uses autoreleasepool to get around this, but that doesn't seem feasible for a larger app. Or is it? Would I have to surround all uses of realm with autoreleasepool?

like image 267
weltan Avatar asked Mar 05 '16 06:03

weltan


1 Answers

Before you can delete an existing Realm database, or create a new one with a new encryption key at the same path, you will need to make sure that all Realm accessors are closed. But as you point out, that might be difficult to achieve in a larger app. The easiest way around that is probably using a new file path as well. For that reason I'd recommend to post-pone the deletion of the actual database itself to the next application launch. You might be able to achieve that by storing the path to the currently used Realm and deleting all other .realm files and all their auxiliary files in the same directory.

like image 156
marius Avatar answered Oct 31 '22 19:10

marius