【问题标题】:performBackgroundTask not saving when app in background Swift当应用程序在后台 Swift 中时,performBackgroundTask 不保存
【发布时间】:2019-02-05 03:02:30
【问题描述】:

我正在使用 Xcode 9 和 Swift 4。当应用程序在前台时,我开始下载多个 JSON 文件。然后应用程序解析这些文件并将它们保存到 CoreData。当应用程序在前台时,这很有效。但是,如果应用程序在后台,文件仍然可以正确下载,但数据不会被解析并保存到 CoreData。只有当用户返回前台时,数据的解析和保存才会继续。

我开启了后台模式 - 后台获取和远程通知。

我有大约 10 个函数,与下面的函数类似,它同时处理 JSON 文件:

func populateStuff(json: JSONDictionary) -> Void {
    let results = json["result"] as! JSONDictionary
    let stuffData = results["Stuff"] as! [JSONDictionary]

    let persistentContainer = getPersistentContainer()

    persistentContainer.performBackgroundTask { (context) in
        for stuff in stuffData {
            let newStuff = Stuff(context: context)
            newStuff.stuffCode = stuff["Code"] as? String
            newStuff.stuffDescription = stuff["Description"] as? String

            do {
                try context.save()
            } catch {
                fatalError("Failure to save context: \(error)")
            }
        }
    }
}

func getPersistentContainer() -> NSPersistentContainer {
    let persistentContainer = NSPersistentContainer(name: "MyProjectName")
    persistentContainer.loadPersistentStores { (_, error) in
        if let error = error {
            fatalError("Failed to load core data stack: \(error.localizedDescription)")
        }
    }
    persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
    persistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
    return persistentContainer
}

谁能告诉我为什么会发生这种情况以及如何克服这种情况?

TIA

【问题讨论】:

    标签: ios json swift core-data background


    【解决方案1】:

    使用beginBackgroundTaskWithName:expirationHandler: 方法:

    func populateStuff(json: JSONDictionary) -> Void {
    
        // Perform the task on a background queue.
        DispatchQueue.global().async {
    
            // Request the task assertion and save the ID.
            self.backgroundTaskID = UIApplication.shared.beginBackgroundTask (withName: "Finish Network Tasks") {
    
            // End the task if time expires.
            UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
            self.backgroundTaskID = UIBackgroundTaskInvalid
        }
    
        // Parse the json files 
        let results = json["result"] as! JSONDictionary
        let stuffData = results["Stuff"] as! [JSONDictionary]
    
        let persistentContainer = getPersistentContainer()
    
        persistentContainer.performBackgroundTask { (context) in
            for stuff in stuffData {
                let newStuff = Stuff(context: context)
                newStuff.stuffCode = stuff["Code"] as? String
                newStuff.stuffDescription = stuff["Description"] as? String
    
                do {
                    try context.save()
                } catch {
                    fatalError("Failure to save context: \(error)")
                }
            }
        }
    
        // End the task assertion.
        UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
        self.backgroundTaskID = UIBackgroundTaskInvalid
    }
    

    调用此方法可为您提供额外的时间来执行重要任务。请注意在任务完成后立即使用endBackgroundTask: 方法。它让系统知道你已经完成了。如果您没有及时结束任务,系统将终止您的应用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      相关资源
      最近更新 更多