在我的项目中,我需要创建数据库备份的可能性,因此根据此blog,我创建了NSPersistentStoreCoordinator
扩展名:
import Foundation
import CoreData
extension NSPersistentStoreCoordinator {
/// Safely copies the specified `NSPersistentStore` to a file.
///
/// Credits: https://oleb.net/blog/2018/03/core-data-sqlite-backup/
func backupPersistentStore(atIndex index: Int) throws {
// Inspiration: https://stackoverflow.com/a/22672386
// Documentation for NSPersistentStoreCoordinate.migratePersistentStore:
// "After invocation of this method, the specified [source] store is
// removed from the coordinator and thus no longer a useful reference."
// => Strategy:
// 1. Create a new "intermediate" NSPersistentStoreCoordinator and add
// the original store file.
// 2. Use this new PSC to migrate to a new file URL.
// 3. Drop all reference to the intermediate PSC.
let sourceStore = persistentStores[index]
let backupCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
let intermediateStoreOptions = (sourceStore.options ?? [:]).merging(
[NSReadOnlyPersistentStoreOption: true],
uniquingKeysWith: { $1 }
)
let intermediateStore = try backupCoordinator.addPersistentStore(
ofType: sourceStore.type,
configurationName: sourceStore.configurationName,
at: sourceStore.url,
options: intermediateStoreOptions
)
let backupStoreOptions: [AnyHashable: Any] = [
NSReadOnlyPersistentStoreOption: true,
// Disable write-ahead logging. Benefit: the entire store will be
// contained in a single file. No need to handle -wal/-shm files.
// https://developer.apple.com/library/content/qa/qa1809/_index.html
NSSQLitePragmasOption: ["journal_mode": "DELETE"],
// Minimize file size
NSSQLiteManualVacuumOption: true,
]
let backupUrl = try prepareBackupUrl()
try backupCoordinator.migratePersistentStore(
intermediateStore,
to: backupUrl,
options: backupStoreOptions,
withType: NSSQLiteStoreType
)
}
/// Remeber to reload persistent stores if you using `NSPersistentContainer`
/// `NSPersistentContainer.loadPersistentStores`
func restorePersistentStore(atIndex index: Int) throws {
let sourceStore = persistentStores[index]
let sourceStoreUrl = sourceStore.url!
let backupUrl = backupFileUrl()
try replacePersistentStore(
at: sourceStoreUrl,
destinationOptions: nil,
withPersistentStoreFrom: backupUrl,
sourceOptions: nil,
ofType: NSSQLiteStoreType
)
}
}
不幸的是,当数据库很大时,migratePersistentStore
的执行时间很长。我正在寻找一些改进措施以加快这一过程。
我对NSPersistentContainer.migratePersistentStore
选项不熟悉。经过一天的研究,我决定在这里寻求帮助。
也许不需要NSSQLiteManualVacuumOption
。也许其他选择对我有帮助。
我的目标:加快migratePersistentStore
。可以使用replacePersistentStore
从创建的备份中还原Core Date。
谢谢您的任何建议。