首页 > 解决方案 > 保存在 Core Data 中的 iOS 数据无法在启动后保存

问题描述

编辑*****

2020 年 7 月 9 日下午 1:39(太平洋标准时间)

我有我认为足以作为应用程序的最小工作可复制版本的内容,可在以下位置获得:

https://github.com/Rattletrap99/penny-game-test

编辑*****

我正在构建一个游戏,用户在其中创建硬币作为各种成就的奖励。硬币在 Core Data 中保存为托管对象,具有各种属性。在玩游戏期间,出于各种原因检索它们、修改它们的属性等。

一切都完美地保存和检索,直到我退出并重新启动,此时持久存储中不存在任何数据。无论是使用模拟器还是设备,情况都是如此。

我通常保存到 Core Data 的方法是:

func saveIt(){
    guard let appDelegate =
        UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    appDelegate.saveContext()
}

哪个电话:

func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
            savedFlag += 1
            
            let coinFetchRequest =
                NSFetchRequest<NSManagedObject>(entityName: "Coin")

            let savedCoins = try context.fetch(coinFetchRequest) as! [Coin]
            
            print("In appDelegate, saveContext, after context.save, there are \(savedCoins.count) coins.")
            print("Successfully saved in appDelegate \(String(describing: savedFlag)) times")

            
            
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

我在代码中输入的每条print()语句都确认保存,但是当我检索(重新启动时)时,通过类似于以下的代码:

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let issuerFetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Issuer")
    let coinFetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Coin")

    
    do {
        let issuers = try context.fetch(issuerFetchRequest) as! [Issuer]
        print(" ###   Upon startup, there are \(issuers.count) Issuers in CD")
        
        let coins = try context.fetch(coinFetchRequest) as! [Coin]
        print(" ####   Upon startup, there are \(coins.count) Coins in CD")

    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }

我得到:

 ###   Upon startup, there are 0 Issuers in CD
 ####   Upon startup, there are 0 Coins in CD

另外,我尝试保存applicationWillTerminate以确保在退出之前保存数据:

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground.
    // Saves changes in the application's managed object context before the application terminates.
    
    
    self.saveContext()
    
    let issuerFetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Issuer")
    let coinFetchRequest =
        NSFetchRequest<NSManagedObject>(entityName: "Coin")

    do {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

        let issuers = try context.fetch(issuerFetchRequest) as! [Issuer]
        let coins = try context.fetch(coinFetchRequest) as! [Coin]

        print("\\\\ Upon quit, there are \(issuers.count) Issuers in CD")
        print("\\\\ Upon quit, there are \(coins.count) Coins in CD")

    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
    }
}

但是,print()声明没有打印出来,让我相信applicationWillTerminate永远不会被解雇。

我应该提到它Issuer与 有to many关系Coin,并且我确保Issuer在创建和保存之前存在 s Coin

非常感谢任何帮助!

标签: iosswiftcore-data

解决方案


在将自己打得半死的时间超过了我承认的时间之后,我发现了以下三行中的错误AppDelegate.swift

    description.shouldInferMappingModelAutomatically = true
    description.shouldMigrateStoreAutomatically = true
    container.persistentStoreDescriptions = [description]

一旦这些被删除,一切都恢复正常。我想说我理解为什么,但老实说,删除这些线条是一种绝望的行为。具有讽刺意味的是,我添加了这些行是为了纠正早期从 Core Data 获取的问题。

非常感谢所有贡献的人!


推荐阅读