我正在使用iOS 9 / Xcode 7 / Swift 2构建iOS应用
主数据存储区是Cloudkit,这种方法很好(但速度很慢),并允许用户之间共享数据。
为了加快大多数查询的过程,Core Data正在本地使用。
更新核心数据时,会出现两种状态 - 1.从CloudKit向Core数据添加一条新记录(这似乎工作正常) 2.从CloudKit更新现有核心数据记录(这是有问题的步骤!)
是否应删除现有核心数据记录,然后创建新记录或其他解决方案?
这是迄今为止的代码 -
from importlib import import_module
答案 0 :(得分:1)
这是这一行:
let localFoodItem = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: self.managedObjectContext)
创建新的CoreData记录。后续for循环的每次迭代只会更改这一条记录的属性值,因此即使从CloudKit有几个要同步的项目,也只会创建一个新的CoreData记录。上面的行应该在for循环中。由于您只想创建一个新的CoreData对象,如果没有相同upc
的预先存在的对象,则上面的行应该在else
子句中。如果存在预先存在的对象,我假设您只想使用CloudKit中的新值更新该对象的其他属性:
let entityDescription = NSEntityDescription.entityForName("FoodItem", inManagedObjectContext: self.managedObjectContext)
let syncpredicate = NSPredicate(value: true)
let syncquery = CKQuery(recordType: "Food", predicate: syncpredicate)
publicDatabase.performQuery(syncquery, inZoneWithID: nil) { results, error in
if error == nil { // There is no error
var numberAdded = 0
var numberUpdated = 0
for entry in results! {
let cloudUPC = entry["UPC"] as? String
//print("UPC from CloudKit \(cloudUPC)")
let cloudFoodName = entry["foodName"] as? String
//print("Name from CloudKit \(cloudFoodName)")
let cloudIngredients = entry["ingredients"] as? String
//print("Ingredients from CloudKit \(cloudFoodName)")
let corepredicate = NSPredicate(format: "upc = %@", cloudUPC!)
// Initialize Fetch Request
let fetchRequest = NSFetchRequest()
fetchRequest.predicate = corepredicate
fetchRequest.entity = entityDescription
var error: NSError?
do {
let result = try self.managedObjectContext.executeFetchRequest(fetchRequest)
if result.count > 0 {
let match = result[0] as! NSManagedObject
print("FoodItem Found in CoreData")
// The next three lines seem superfluous?
let upcNumber = match.valueForKey("upc") as! String
let iList = match.valueForKey("ingredients") as! String
let coreName = match.valueForKey("productName") as! String
print("Item UPDATED in CoreData")
match.setValue(cloudFoodName, forKey: "productName")
match.setValue(cloudIngredients, forKey: "ingredients")
numberUpdated++
} else {
print("IMPORTED New Item from CloudKit")
let localFoodItem = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: self.managedObjectContext)
localFoodItem.setValue(cloudUPC, forKey: "upc")
localFoodItem.setValue(cloudFoodName, forKey: "productName")
localFoodItem.setValue(cloudIngredients, forKey: "ingredients")
numberAdded++
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
do {
try self.managedObjectContext.save()
print("Database Additions: \(numberAdded)")
print("Database Updates: \(numberUpdated)")
} catch {
print(error)
}
}else {
print(error)
}
}
请注意,我会移动save
操作,使其在for循环之后,而不是在for循环之内。另外,如果没有在主线程上执行CloudKit完成处理程序,你可能会发现你有CoreData线程/并发问题(我不熟悉CK所以不能建议)。