保存在Core Data中的iOS数据无法在启动后幸免 [英] iOS data saved in Core Data doesn't survive launch

查看:52
本文介绍了保存在Core Data中的iOS数据无法在启动后幸免的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑 *********

EDIT *********

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

7-09-2020 1:39 PM PST

我相信我可以满足该应用程序的最低工作可复制版本要求,该版本可在以下位置找到:

I've got what I believe will suffice as a minimal working reproducible version of the app available at:

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

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

编辑 *********

EDIT *********

我正在构建一个游戏,用户在其中创建硬币以作为各种成就的奖励。硬币及其各种属性被保存为托管数据中的托管对象。

I'm building a game in which users create coins as rewards for various achievements. The coins are saved as managed objects in Core Data, with their various attributes. They are retrieved for various reasons, have their attributes modified, etc., during game play.

所有内容都会保存并完全恢复,直到我退出并重新启动为止,此时在该位置没有任何数据。持久存储。

Everything saves and retrieves perfectly until I quit and relaunch, at which point no data is present in the persistent store. This is the case whether using a simulator or a device.

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

My usual means of saving to Core Data is:

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()语句都会确认保存,但是当我检索(重新启动时)时,通过类似于以下代码:

Every print() statement I put in the code confirms the save, but when I retrieve (upon relaunch), via code similar to:

    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 确定退出前已保存数据:

Also, I try to save in applicationWillTerminate to be certain the data is saved before quitting:

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 不会被触发。

However, the print() statements are not printed, leading me to believe applicationWillTerminate is never fired.

我应该提到 Issuer 对很多 >硬币,并且在创建和保存硬币发卡人 >。

I should mention that Issuer has a to many relationship with Coin, and I ensure that there are Issuers present before creating and saving a Coin.

任何帮助深表感谢!

推荐答案

比我承认的要长,我在 AppDelegate.swift 中发现了这三行的错误:

After beating myself half to death for longer than I care to admit, I found the fault in these three lines in AppDelegate.swift:

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

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

Once these were removed, everything went back to normal. I'd like to say I understand why, but honestly, removing these lines were an act of desperation. And the irony is that I had added these lines in an attempt to rectify an earlier problem with fetching from Core Data.

非常感谢所有贡献者!

这篇关于保存在Core Data中的iOS数据无法在启动后幸免的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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