coredata - 移动到应用组目标 [英] coredata - move to app group target

查看:14
本文介绍了coredata - 移动到应用组目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不熟悉 Today 扩展并使用嵌入式框架.

I am new to the Today extension and using an embedded framework.

我们的应用目前使用由 sqlite 支持的核心数据.如果我想在应用程序和今天的扩展程序之间共享它,我是否应该将它移动到一个由两者共享的框架中?

Our app currently uses core data backed by sqlite. If I want to share this between the app and the today extension, should I move this to a framework to be shared by both?

如何迁移我们在应用商店中的当前版本以升级到新结构?

How can I migrate our current version in the app store to be able to upgrade to a new structure?

推荐答案

如果有人想要快速解决方案,只需在 didFinishLaunchingWithOptions 中添加以下函数即可.

In case someone wants the solution in swift just add below function in didFinishLaunchingWithOptions.

 func migratePersistentStore(){

    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    var storeOptions = [AnyHashable : Any]()
    storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
    storeOptions[NSInferMappingModelAutomaticallyOption] = true
    let oldStoreUrl = self.applicationDocumentsDirectory.appendingPathComponent("YourApp.sqlite")!
    let newStoreUrl = self.applicationGroupDirectory.appendingPathComponent("YourApp.sqlite")!
    var targetUrl : URL? = nil
    var needMigrate = false
    var needDeleteOld = false

    if FileManager.default.fileExists(atPath: oldStoreUrl.path){
        needMigrate = true
        targetUrl = oldStoreUrl
    }

    if FileManager.default.fileExists(atPath: newStoreUrl.path){
        needMigrate = false
        targetUrl = newStoreUrl

        if FileManager.default.fileExists(atPath: oldStoreUrl.path){
            needDeleteOld = true
        }
    }
    if targetUrl == nil {
        targetUrl = newStoreUrl
    }
    if needMigrate {
        do {
            try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: targetUrl!, options: storeOptions)
            if let store = coordinator.persistentStore(for: targetUrl!) 
             {
                do {
                    try coordinator.migratePersistentStore(store, to: newStoreUrl, options: storeOptions, withType: NSSQLiteStoreType)

                } catch let error {
                    print("migrate failed with error : (error)")
                }
            }
        } catch let error {
            CrashlyticsHelper.reportCrash(err: error as NSError, strMethodName: "migrateStore")
        }
    }
  if needDeleteOld {
        DBHelper.deleteDocumentAtUrl(url: oldStoreUrl)
        guard let shmDocumentUrl = self.applicationDocumentsDirectory.appendingPathComponent("NoddApp.sqlite-shm") else { return }
        DBHelper.deleteDocumentAtUrl(url: shmDocumentUrl)
        guard let walDocumentUrl = self.applicationDocumentsDirectory.appendingPathComponent("NoddApp.sqlite-wal") else { return }
        DBHelper.deleteDocumentAtUrl(url: walDocumentUrl)
    }
}

我的 PersistentStoreCoordinator 看起来像这样:

My PersistentStoreCoordinator Looks like this:

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationGroupDirectory.appendingPathComponent("YourApp.sqlite")
    var storeOptions = [AnyHashable : Any]()
    storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
    storeOptions[NSInferMappingModelAutomaticallyOption] = true
    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:storeOptions)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
        dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        NSLog("Unresolved error (wrappedError), (wrappedError.userInfo)")
        abort()
    }
    return coordinator
}()

如果应用商店中已有应用,并且您希望将 coreData 持久存储文件从您的默认商店位置迁移到您的应用组位置,就会出现这种情况.

This is the case when there is already an app in appstore and you want to migrate the coreData persistent store file from your default store location to your App Group Location.

Edit : 对于从旧位置删除文件,建议我们使用 NSFileCoordinator 来执行任务.

Edit : For Deleting the file from the old location it is recommended that we use NSFileCoordinator to perform the task.

static func deleteDocumentAtUrl(url: URL){
    let fileCoordinator = NSFileCoordinator(filePresenter: nil)
    fileCoordinator.coordinate(writingItemAt: url, options: .forDeleting, error: nil, byAccessor: {
        (urlForModifying) -> Void in
        do {
            try FileManager.default.removeItem(at: urlForModifying)
        }catch let error {
            print("Failed to remove item with error: (error.localizedDescription)")
        }
    })
}

请注意使用 NSFileCoordinator 删除文件的原因是因为 NSFileCoordinator 允许我们确保文件相关的任务(例如打开读写)以不会干扰系统上尝试使用的任何其他任务的方式完成同一个文件.例如,如果您想打开一个文件并同时删除它,您不希望这两个操作同时发生.

Please note the reason why NSFileCoordinator is used to delete the file is because NSFileCoordinator allows us to ensure that file related tasks such as opening reading writing are done in such a way that wont interfere with anyother task on the system trying to work with the same file.Eg if you want to open a file and at the same time it gets deleted ,you dont want both the actions to happen at the same time.

请在商店迁移成功后调用上述函数.

Please call the above function after the store is successfully migrated.

这篇关于coredata - 移动到应用组目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆