gpt4 book ai didi

swift - 使用 Swift 将现有项目的本地核心数据存储迁移到 iCloud

转载 作者:可可西里 更新时间:2023-11-01 02:19:38 24 4
gpt4 key购买 nike

我想为现有项目启用 iCloud for Core Data。用户可以使用新 iPhone 或其他具有旧数据的应用程序。因此,我必须将可能存在的商店迁移到 iCloud/无处不在的容器中的新商店。

当您使用 iOS 8 创建新的 Swift 项目时,我添加了 iCloud 文档功能并使用了 Apple 默认的核心数据堆栈模板。

Apple 核心数据堆栈模板:

    lazy var applicationDocumentsDirectory: NSURL = {
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1] as! NSURL
}()

lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle.mainBundle().URLForResource("testapp", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("testapp.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as [NSObject : AnyObject])
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}

return coordinator
}()

lazy var managedObjectContext: NSManagedObjectContext? = {
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()

// MARK: - Core Data Saving support

func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save(&error) {
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}

我在 apple developer 上阅读了有关函数 migratePersistentStore 的信息,并在 StackOverflow 上阅读了有关答案 Move local Core Data to iCloud 的信息,但我不知道如何在该模板中正确实现。

根据我的理解,我认为,如果 url 指向现有的商店/文件,我必须检查协调器的惰性 var 定义。如果是这样,我必须迁移到具有函数 migratePersistentStore:xmlStore 和选项 NSPersistentStoreUbiquitousContentNameKey 的新商店。

所以我写了一个新的持久化协调器:

具有迁移的持久性协调器

   lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

// create new iCloud-ready-store
let iCloudStoreUrl = self.applicationDocumentsDirectory.URLByAppendingPathComponent("TestAppiCloud.sqlite")
var iCloudOptions: [NSObject : AnyObject]? = [
NSPersistentStoreFileProtectionKey: NSFileProtectionComplete,
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true,
NSPersistentStoreUbiquitousContentNameKey: "TestAppiCloudStore"
]

var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."

if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: iCloudStoreUrl, options: iCloudOptions, error: &error) == nil {
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}

// Possible old store migration

let existingStoreUrl = self.applicationDocumentsDirectory.URLByAppendingPathComponent("testapp.sqlite")
let existingStorePath = existingStoreUrl.path

// check if old store exists, then ...
if NSFileManager.defaultManager().fileExistsAtPath(existingStorePath!) {
// ... migrate
var existingStoreOptions = [NSReadOnlyPersistentStoreOption: true]
var migrationError: NSError? = nil

var existingStore = coordinator!.persistentStoreForURL(existingStoreUrl)
coordinator!.migratePersistentStore(existingStore!, toURL: iCloudStoreUrl, options: existingStoreOptions, withType: NSSQLiteStoreType, error: &migrationError)
}

// iCloud Notifications
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self,
selector: "storeWillChange",
name: NSPersistentStoreCoordinatorStoresWillChangeNotification,
object: coordinator!)
notificationCenter.addObserver(self,
selector: "storeDidChange",
name: NSPersistentStoreCoordinatorStoresDidChangeNotification,
object: coordinator!)
notificationCenter.addObserver(self,
selector: "storeDidImportUbiquitousContentChanges",
name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
object: coordinator!)

return coordinator
}()

但是我遇到了一个异常,当迁移从协调器开始时!.migratePersistentStore:

var existingStore = coordinator!.persistentStoreForURL(existingStoreUrl)//无

但是文件管理器说,它存在!

我做错了什么?这个想法是否正确?请帮忙。

最佳答案

我遇到了与“persistentStoreForURL”完全相同的问题。事实证明,我正在寻找的是“persistenStoreWITHUrl”之类的东西。我错误地认为它实际上会加载商店,但事实证明,它不会。当商店已经加载到协调器中时,此功能有效。我知道你刚才问过这个问题,但我会把它留在这里以防其他人遇到同样的问题。如此更改代码将使其按预期工作:

    let coordinator = self.persistentStoreCoordinator
let existingStore = coordinator.persistentStores.first

var options = Dictionary<NSObject, AnyObject>()
options[NSPersistentStoreRemoveUbiquitousMetadataOption] = true
options[NSMigratePersistentStoresAutomaticallyOption] = true
options[NSInferMappingModelAutomaticallyOption] = true


do {
try coordinator?.migratePersistentStore(existingStore!, to: url2, options: [NSMigratePersistentStoresAutomaticallyOption:true, NSInferMappingModelAutomaticallyOption:true], withType: NSSQLiteStoreType)

}
catch {

print(error)

}

关于swift - 使用 Swift 将现有项目的本地核心数据存储迁移到 iCloud,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31682806/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com