在Swift中执行后台保存

问题描述 投票:0回答:1

我有几个看起来类似于下面的功能。他们都运行良好,正常完成。但是,以下函数似乎永远不会运行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)")
                    }
                }
            }
        }
    }
}
ios swift core-data background
1个回答
1
投票

不要将谓词创建为字符串,这种情况在任何但很简单的情况下都会失败,这可能是你的问题。创建谓词如下:

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

或使用复合谓词:

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


P.S. do not forget () brackets in predicate with several conditions.
Good luck :)
© www.soinside.com 2019 - 2024. All rights reserved.