How do you compact a Realm database on iOS?

I would like to periodically copy an instance of Realm on iOS to recover space. I think the process is to copy the db to a temporary location, then copy it and use the new default.realm file.

My Realm() problem acts like a singleton and recycles objects, so I cannot close it and say it to open a new default.realm file.

The docs here ( https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html ) suggest to wrap all Realm () calls in autorelease { } , but this can't be complicated.

+5
source share
3 answers

It may be really difficult to completely demolish all the extracted model accessors, but unfortunately there is no other way to close the kingdom.

As you wrote โ€œperiodicallyโ€, each application launch can be quite often, depending on your use case.

When starting the application, it should be relatively easy to open Realm in the selected autoreleasepool, write a compressed copy to another path and replace the default.realm file with it.

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 } 
+19
source

The answer given by @marius has a problem: open Realm may still refer to the remote file. This means that some records may appear in the old (deleted) file, as a result of which the application will lose data.

The correct implementation of the compactRealm method looks like this: (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) } 

This problem drove me crazy until I found the answer here

+2
source

Well .. this problem seems to be mostly outdated. Last fall, Realm added an automatic compact feature. Realm Docs / compacting-realms . I think the only reason for this, described by @marius, is that you need to control the user interface and compactly in the background.

See this question for more details: How to properly use shouldCompactOnLaunch in RealmSwift

0
source

Source: https://habr.com/ru/post/1247997/


All Articles