Выполнение сохранения фона в Swift - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть несколько функций, которые похожи на ниже.Все они работают нормально и завершают нормально.Однако приведенная ниже функция, кажется, никогда не запускает ту часть, где lineCount> = rows.count.Функция просто зависает.Когда я распечатываю lineCount, он иногда отображает одно и то же число несколько раз подряд.Я делаю что-то явно неправильно?Что еще более странно, так это то, что если я уберу 2-ю часть в каждом из NSP-предикатов (то есть 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)")
                    }
                }
            }
        }
    }
}

1 Ответ

1 голос
/ 18 апреля 2019

Не создавайте предикаты в виде строк, которые могут потерпеть неудачу в любых, кроме тривиальных случаях, что, вероятно, является вашей проблемой здесь. Создайте предикат следующим образом:

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

или используйте составной предикат:

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

<ч /> Постскриптум не забывайте () скобки в предикате с несколькими условиями. <Ч /> Удачи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...