Ios 在Swift中执行后台保存

Ios 在Swift中执行后台保存,ios,swift,core-data,background,Ios,Swift,Core Data,Background,我有几个类似于下面的函数。它们运行良好,完成正常。但是,下面的函数似乎从未运行lineCount>=rows.count的部分。函数只是挂起。当我打印lineCount时,它有时会在一行中多次显示相同的数字。我是不是做错了什么?更奇怪的是,如果我去掉每个NSpredicate中的第二部分(即itemNumber),它就可以正常工作 func populatePurchaseLine(json: JSONDictionary) -> Void { guard let rows = j

我有几个类似于下面的函数。它们运行良好,完成正常。但是,下面的函数似乎从未运行lineCount>=rows.count的部分。函数只是挂起。当我打印lineCount时,它有时会在一行中多次显示相同的数字。我是不是做错了什么?更奇怪的是,如果我去掉每个NSpredicate中的第二部分(即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)
    ]
)

注意:不要忘记谓词中带有多个条件的括号
()

祝你好运:)