Comment compactez-vous une Realm DB sur iOS?

Je voudrais compacter une instance Realm sur iOS périodiquement pour récupérer de l'espace. Je pense que le process consiste à copyr la database dans un location temporaire, puis à le recopyr et à utiliser le nouveau file default.realm.

Mon problème est Realm() agit comme un singleton et recycle des objects, donc je ne peux pas vraiment le fermer et lui dire d'ouvrir le nouveau file default.realm.

Les docs ici ( https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html ) suggèrent que j'emballe tous les appels de Realm () dans autorelease { } mais cela ne peut pas être aussi compliqué.

Il peut être difficile de détruire complètement tous les accesseurs de templates récupérés, mais il n'y a malheureusement pas d'autre moyen de fermer un royaume.

Comme vous l'avez écrit "périodiquement", chaque lancement d'application peut suffire, selon votre cas d'utilisation.

Au lancement de votre application, il devrait être relativement facile d'ouvrir Realm dans un autoreleasepool dédié, d'écrire une copy compactée sur un path différent et de replace votre file default.realm par celui-ci.

Swift 2.1

 func compactRealm() { let defaultURL = Realm.Configuration.defaultConfiguration.fileURL! let defaultParentURL = defaultURL.URLByDeletingLastPathComponent! let compactedURL = defaultParentURL.URLByAppendingPathComponent("default-compact.realm") autoreleasepool { let realm = try! Realm() realm.writeCopyToPath(compactedURL) try! NSFileManager.defaultManager().removeItemAtURL(defaultURL) try! NSFileManager.defaultManager().moveItemAtURL(compactedURL, toURL: defaultURL) } } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { compactRealm() // further setup … return true } 

Swift 3.0

 func compactRealm() { let defaultURL = Realm.Configuration.defaultConfiguration.fileURL! let defaultParentURL = defaultURL.deletingLastPathComponent() let compactedURL = defaultParentURL.appendingPathComponent("default-compact.realm") autoreleasepool { let realm = try! Realm() try! realm.writeCopy(toFile: compactedURL) try! FileManager.default.removeItem(at: defaultURL) try! FileManager.default.moveItem(at: compactedURL, to: defaultURL) } } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { compactRealm() // further setup … return true } 

La réponse donnée par @marius a un problème: le domaine ouvert peut toujours referencer le file supprimé. Cela signifie que certaines écritures peuvent se refind dans l'ancien file (supprimé), entraînant la perte de données pour l'application.

L'implémentation correcte de la méthode compactRealm ressemble à ceci (swift 3):

 func compactRealm() { let defaultURL = Realm.Configuration.defaultConfiguration.fileURL! let defaultParentURL = defaultURL.deletingLastPathComponent() let compactedURL = defaultParentURL.appendingPathComponent("default-compact.realm") autoreleasepool { let realm = try! Realm() try! realm.writeCopy(toFile: compactedURL) } try! FileManager.default.removeItem(at: defaultURL) try! FileManager.default.moveItem(at: compactedURL, to: defaultURL) } 

Ce problème m'a rendu fou jusqu'à ce que j'ai trouvé une réponse ici