我们已经使用了一段时间,我们的一些用户已经经历了一些与领域相关的数据丢失。我们认为我们已经将其缩小到压缩方法,以便在文件变得太大时使用。对于这是否是重新创建我们的领域文件的正确方式,我们想征求一些建议。此方法在applicationDidEnterBackground上调用。
我们编写了下面所做工作的示例:
public static func compact() {
// Get the original file path
let configuration = RealmSampleClient.shared.config
guard let originalFileURL = configuration.fileURL else {
return
}
// check if the file size is bigger than 10mb, if not return
guard let attr = try? FileManager.default.attributesOfItem(atPath: originalFileURL.absoluteString),
let fileSize = attr[FileAttributeKey.size] as? UInt64,
fileSize > 500_000_000 else {
return
}
// create a filepath for a copy
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddHHmmss"
let dateString = "\(dateFormatter.string(from: date)).realm"
let copyFileURL = originalFileURL.deletingLastPathComponent().appendingPathComponent(dateString)
// copy the Realm file
do {
let realm = try Realm(configuration: configuration)
try realm.writeCopy(toFile: copyFileURL, encryptionKey: configuration.encryptionKey)
} catch {
return
}
// remove the old file and copy the new one
do {
removeRealmFile(at: originalFileURL)
try FileManager.default.copyItem(at: copyFileURL, to: originalFileURL)
} catch {
}
// remove a copy if it exists
guard FileManager.default.fileExists(atPath: copyFileURL.path) else { return }
do {
try FileManager.default.removeItem(at: copyFileURL)
} catch {
}
}
private static func removeRealmFile(at url: URL = databaseUrl) {
let realmURLs = [
url,
url.appendingPathExtension("lock"),
url.appendingPathExtension("note"),
url.appendingPathExtension("management"),
]
realmURLs.forEach { URL in
guard FileManager.default.fileExists(atPath: URL.path) else { return }
do {
try FileManager.default.removeItem(at: URL)
} catch {
}
}
}谢谢你的帮助
发布于 2019-11-18 09:01:08
我们重新考虑了应用程序的流程,它似乎解决了我们的问题。这与启动过程中访问领域太快有关,可能是在多个线程上。
发布于 2019-01-11 07:37:46
我在这里看不到压缩代码,只有数据库文件的副本。因此,我假设您忽略了这一点,以保持代码的紧凑。
无论如何,当应用程序进入后台模式时,您会执行此操作。你是否为此注册了一个背景任务?如果压缩操作花费了太多的时间,任务就会被iOS杀死,我认为这就是问题所在。
您可以使用UIApplication.shared.beginBackgroundTask显式地要求操作系统提供更多的后台执行时间,但这也是一个非常有限的时间,通常是3分钟。
但这都是在黑暗中挖掘,你应该发布更多的代码,看看你的背景任务是如何设置的。
发布于 2019-01-11 09:44:43
根据领域文档,建议使用自动发布池包装代码,如下所示
do {
let realm = try Realm(configuration: configuration)
try realm.writeCopy(toFile: copyFileURL, encryptionKey: configuration.encryptionKey)
} catch {
return
}在后台任务中这样做肯定会有帮助,友好的建议是始终处理错误,您只是返回catch块,日志可能会有所帮助。
查看更多文档,我可以看到RealmSwift现在集成了一个压缩特性,这里有更多的细节:https://realm.io/docs/swift/latest/#compacting-realms
https://stackoverflow.com/questions/54141642
复制相似问题