ios - 在 Swift 中执行后台保存

标签 ios swift core-data background

我有几个类似于下面的函数。它们都运行良好并正常完成。但是,下面的函数似乎从未运行过 lineCount >= rows.count 的部分。该功能只是挂起。当我打印出 lineCount 时,它有时会连续多次显示相同的数字。我做错了什么吗?更奇怪的是,如果我在每个 NSPredicates(即 itemNumber)中取出第二部分,它就可以正常工作。

func populatePurchaseLine(json: JSONDictionary) -> Void {
    guard let rows = json["rows"] as? [JSONDictionary] else {
        return
    }
    var lineCount = 0
    persistentContainer!.performBackgroundTask { (context) in
        for row in rows {
            guard let action = row["action"] as? String else {
                return
            }

            if (action == "A") || (action == "C") {
                // add
                guard let aRecord = row["data"] as? JSONDictionary else {
                    return
                }

                var recordToSave: MyTable

                if let popNo = aRecord["AKey"] as? NSNumber, let lineNumber = aRecord["AnotherKey"] as? NSNumber {
                    let predicate = NSPredicate(format: "aNumberField == \(popNo.int64Value) AND itemNumber == \(lineNumber.int64Value)")
                    let result = DatabaseHelper.fetchRecordsForEntity(entity: "MyTable",
                                                                      managedObjectContext: context,
                                                                      predicate: predicate) as! [MyTable]

                    if result.isEmpty {
                        recordToSave = MyTable(context: context)
                    } else {
                        recordToSave = result.first!
                    }
                } else {
                    recordToSave = MyTable(context: context)
                }

                if let popNo = aRecord["AKey"] as? NSNumber {
                    recordToSave.aNumberField = popNo.int64Value
                }

                if let anItem = aRecord["AnotherKey"] as? NSNumber {
                    recordToSave.itemNumber = anItem.int64Value

                do {
                    try context.save()
                    lineCount += 1
                    if (lineCount >= rows.count) {
                        if self.hasCancelled {
                            self.abortDownload()
                        } else {
                            self.downloadStage = .downloadNextOne
                            self.startDownloadViaCloud(fileName: nil)
                        }
                    }
                } catch {
                    print("Failure to save context: \(error)")
                }
            } else if action == "D" {
                guard let theData = row["data"] as? JSONDictionary else {
                    return
                }
                guard let popNo = theData["AKey"] as? NSNumber else {
                    return
                }
                guard let lineNumber = theData["AnotherKey"] as? NSNumber else {
                    return
                }
                self.persistentContainer!.performBackgroundTask { (context) in
                    let predicate = NSPredicate(format: "aNumberField == \(popNo.int64Value) AND itemNumber == \(lineNumber.int64Value)")

                    let result = DatabaseHelper.fetchRecordsForEntity(entity: "MyTable",
                                                                      managedObjectContext: context,
                                                                      predicate: predicate) as! [MyTable]

                    if let theLine = result.first {
                        context.delete(theLine)
                    }

                    do {
                        try context.save()
                        lineCount += 1
                        if (lineCount >= rows.count) {
                            if self.hasCancelled {
                                self.abortDownload()
                            } else {
                                self.downloadStage = .downloadNextOne
                                self.startDownloadViaCloud(fileName: nil)
                            }
                        }
                    } catch {
                        print("Failure to save context: \(error.localizedDescription)")
                    }
                }
            }
        }
    }
}

最佳答案

不要将谓词创建为字符串,这在任何情况下都必然会失败,但可能是您的问题所在。按如下方式创建谓词:

NSPredicate(format: "(aNumberField == %@) AND (itemNumber == %@)", popNo.int64Value, lineNumber.int64Value)

或者使用复合谓词:

NSCompoundPredicate(
    type: .and,
    subpredicates: [
        NSPredicate(format: "aNumberField == %@", popNo.int64Value),
        NSPredicate(format: "itemNumber == %@", lineNumber.int64Value)
    ]
)


附言不要忘记带有多个条件的谓词中的 () 括号。
祝你好运:)

关于ios - 在 Swift 中执行后台保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55743786/

相关文章:

iphone - 从 Core Data 中的 View 传递数据

ios - 使用从服务器检索的实际数据创建核心数据实体的最佳实践

swift - 如何通过代码在 SceneKit 中设置基于物理的渲染?

iOS 7 在框架更改后呈现 navcontroller 导航栏高度 64px

ios - 在 mac 上安装配置文件时出错。 (未能在此设备上安装一个或多个配置文件)

ios - 如何使用 Square Point of Sale 应用程序的其他付款功能调用我的应用程序?

swift - 如何从 firebase 异步加载数据并将其显示在 UICollectionView 中

ios - 强制 Nib 加载器使用 init?(带有 :) for custom subclass of NSObject in iOS

iphone - 核心数据获取值的总和。获取的属性与传播

ios - 什么是深层链接?如何为App Store创建深层链接?