В моем проекте мне нужна возможность создать резервную копию базы данных, поэтому в соответствии с этим блогом я создал 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
. Сохраните возможность восстановить Core Date из созданной резервной копии, используя replacePersistentStore
.
Спасибо за любой совет.