【问题标题】:Knowing when lightweight migration finished了解轻量级迁移何时完成
【发布时间】:2021-11-23 07:27:15
【问题描述】:

设置: 我正在尝试在我的应用程序中进行轻量级核心数据迁移。我添加了一个新的 Core Data 模型版本并添加了新的改进(为现有实体添加了 9 个属性、2 个新实体、新实体和现有实体之间的关系)。

问题: 从使用旧数据库的构建切换到新数据库会导致应用程序没有数据。但是一旦我退出应用程序并返回,数据就在那里(我假设它只是被迁移)。

问题: 有没有办法知道核心数据何时开始迁移(让用户知道)以及迁移何时完成(用新数据刷新他们的视图)?在过去的几周里,我做了很多搜索,但没有找到太多。

提前谢谢你!

代码: 这就是我设置 Core Data 的方式(特别是 setupContainer() 代码):

final class CoreDataManager {
    static let sharedManager = CoreDataManager()
    lazy var persistentContainer: NSPersistentContainer = {
        setupContainer()
    }()

    private func setupContainer() -> NSPersistentContainer {
        useCloudSync = UserDefaults.standard.bool(forKey: UserDefaults.Keys.useCloudSync)

        let containerToUse: NSPersistentContainer?
        if useCloudSync {
            containerToUse = NSPersistentCloudKitContainer(name: "appName")
        } else {
            containerToUse = NSPersistentContainer(name: "appName")
        }

        //check if we have a container
        guard let container = containerToUse else {
            fatalError("Hey Listen! Could not get a container!!")
        }

        // Enable history tracking and remote notifications
        guard let description = container.persistentStoreDescriptions.first else {
            fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
        }
        
        //be notified of change
        description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
        description.setOption(true as NSNumber, forKey: NSMigratePersistentStoresAutomaticallyOption)
        description.setOption(true as NSNumber, forKey: NSInferMappingModelAutomaticallyOption)
        
        //set tracking history if we're using local container
        if !useCloudSync {
            description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
        }

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Hey Listen! Couldn't load persistent store. Unresolved error \(error), \(error.userInfo)")
            }
        })

        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        container.viewContext.transactionAuthor = appTransactionAuthorName
        container.viewContext.automaticallyMergesChangesFromParent = true        

        //Remote changes notification
        NotificationCenter.default.addObserver(
            self, selector: #selector(type(of: self).storeRemoteChange(_:)),
            name: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator)
        
        return container

    }//end of setup container

}

【问题讨论】:

    标签: swift core-data core-data-migration


    【解决方案1】:

    大概你在NSPersistentContainer 上调用loadPersistentStores。该方法接受完成处理程序(闭​​包)。您将在此处收到迁移已完成(或已失败)的回调。您可以通过在 loadPersistentStores 之前添加一个调用来判断迁移何时开始。

    如果您创建自己的NSPersistentStoreDescription 实例并将其添加到NSPersistentContainer,您可以控制迁移是否发生以及它是同步运行还是异步运行。

    有关使用完成处理程序的示例,请参阅 Enabling core data lightweight migration in Swift 3(特别是回答 https://stackoverflow.com/a/53607127/719690)。

    Does the completionHandler of loadPersistentStores of NSPersistentContainer run synchronously? 也有助于理解流程。

    根据您的代码示例,您可能会将其修改为(我已切换到缩短的闭包语法):

        container.loadPersistentStores { storeDescription, error in
            if let error = error as NSError? {
                // error path, but should be nicer than just crashing
                fatalError("Hey Listen! Couldn't load persistent store. Unresolved error \(error), \(error.userInfo)")
            } else {
                // happy path
                print("unicorns and rainbows, migration succeeded, load the tableview")
            }
        }
    

    (在浏览器中输入,注意拼写错误)

    Swiftier 版本会在错误检查中使用 guard let,但我想尽量减少对您的示例所做的更改。

    【讨论】:

    • 嗨哈尔!谢谢你的快速反应!您的链接帮助我了解了加载过程。幸运的是,我已经使用了完成处理程序,但我不知道如何判断处理程序内部发生了迁移。我只需要在发生迁移时重新加载视图并保持它们不变,但我似乎找不到检测迁移的方法。 您有什么建议吗?
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多