当我尝试解决sqlite文件的问题时,我意识到我的AppDelegate出错了。
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
我想更改文件名以匹配应用名称,但我不想丢失SingleViewCoreData.sqlite
文件中的当前数据。我怎样才能做到这一点?
答案 0 :(得分:0)
这是我能够解决问题的方法,这一切都是 Swift 3.1
var pURL: URL?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
checkForOldStore()
return true
}
然后我编辑了persistentStoreCoordinator部分。
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
// let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
let url = self.pURL // ADDED THIS CODE WHICH REPLACED CODE FROM ABOVE.
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true])
} catch {
使用以下代码,我首先检查旧的sqlite文件是否与checkForOldStore()
一起存在。请注意,在调用persistentStoreCoordinator
之前,如果文件存在,我将pURL设置为等于migrateStore()
上旧设置的值。并且因为每次应用程序启动时checkForOldStore()
仍然运行,现在该文件不存在,我将pURL
设置为新文件名。
func checkForOldStore() {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let filePath = url.appendingPathComponent("SingleViewCoreData.sqlite")?.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath!) {
print("FILE AVAILABLE")
pURL = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
migrateStore()
} else {
pURL = self.applicationDocumentsDirectory.appendingPathComponent("NewName.sqlite")
print("FILE NOT AVAILABLE")
}
}
在migrateStore()
的末尾,我为每个旧的sqlite文件调用remvoeOldDB
。
func migrateStore() {
// migrate current store from one URL to another
// write out the current store URL before the migration
var storeURL: URL? = persistentStoreCoordinator.persistentStores.last?.url
print("Current Store URL (before migration): \(String(describing: storeURL?.description))")
// grab the current store
let currentStore: NSPersistentStore? = persistentStoreCoordinator.persistentStores.last
// create a new URL
let newStoreURL: URL? = applicationDocumentsDirectory.appendingPathComponent("NewName.sqlite")
// setup new options dictionary if necessary
// migrate current store to new URL
_ = try? persistentStoreCoordinator.migratePersistentStore(currentStore!, to: newStoreURL!, options: nil, withType: NSSQLiteStoreType)
// and to check we're on the new store, write out tha URL again
storeURL = persistentStoreCoordinator.persistentStores.last?.url
print("Current Store URL (after migration): \(String(describing: storeURL?.description))")
removeOldDB(itemName: "SingleViewCoreData", fileExtension: "sqlite")
removeOldDB(itemName: "SingleViewCoreData", fileExtension: "sqlite-shm")
removeOldDB(itemName: "SingleViewCoreData", fileExtension: "sqlite-wal")
}
func removeOldDB(itemName:String, fileExtension: String) {
let fileManager = FileManager.default
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
guard let dirPath = paths.first else {
return
}
let filePath = "\(dirPath)/\(itemName).\(fileExtension)"
do {
try fileManager.removeItem(atPath: filePath)
} catch let error as NSError {
print(error.debugDescription)
}
}