Reputation: 639
I have several functions that look similar to below. They all run fine and complete normally. However, the below function doesn't ever seem to run the part where lineCount >= rows.count. The function just hangs. When I print out the lineCount, it sometimes displays the same number several times in a row. Am I doing something obviously wrong? What's even more bizarre, is that if I take out the 2nd part in each of the NSPredicates (i.e. the itemNumber) it works fine.
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)")
}
}
}
}
}
}
Upvotes: 0
Views: 98
Reputation: 4376
Do not create predicates as strings, that is bound to fail in any but trivial cases which is probably your problem here. Create the predicate as follows:
NSPredicate(format: "(aNumberField == %@) AND (itemNumber == %@)", popNo.int64Value, lineNumber.int64Value)
or use compound predicate:
NSCompoundPredicate(
type: .and,
subpredicates: [
NSPredicate(format: "aNumberField == %@", popNo.int64Value),
NSPredicate(format: "itemNumber == %@", lineNumber.int64Value)
]
)
()
brackets in predicate with several conditions.
Upvotes: 1