编辑:使用代码编辑,将记录保存到Core Data和Cloudkit,以防它有助于诊断问题。
Hello all and Happy Holidays,
使用Core Data和Cloudkit时遇到了一些麻烦。在启动我的应用程序后,我运行Cloudkit fetch以从私有数据库获取所有已保存的记录,以便跨设备同步这些记录,并在需要时将它们保存到Core Data。因此,在完成提取后,我尝试运行检查,以便应用程序只在Core Data中创建一条新记录,如果它还没有在同步时避免重复。
以下是代码:
func fetchZoneChanges(database: CKDatabase, databaseTokenKey: String, zoneIDs: [CKRecordZoneID], completion: @escaping () -> Void) {
// Look up the previous change token for each zone
var optionsByRecordZoneID = [CKRecordZoneID: CKFetchRecordZoneChangesOptions]()
for zoneID in zoneIDs {
let options = CKFetchRecordZoneChangesOptions()
options.previousServerChangeToken = nil //TODO: Read change token from disk
optionsByRecordZoneID[zoneID] = options
}
let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: zoneIDs, optionsByRecordZoneID: optionsByRecordZoneID)
operation.recordChangedBlock = { (record) in
print("Record changed:", record)
// Write this record change to memory - core data
DispatchQueue.main.async {
if record.recordType == "Deck" {
let ckRecordID = record.recordID.recordName
let fetchRequest = NSFetchRequest<Deck>(entityName: "Deck")
fetchRequest.predicate = NSPredicate(format: "ckRecordID = %@", ckRecordID)
let fetchRequestResults = try? self.managedContext.fetch(fetchRequest)
if let existingDeck = fetchRequestResults?.first {
// We already have the deck in Core Data, just need to update it!
existingDeck.cKRecordToDeck(record)
} else {
// We don't have the deck in Core Data, so make a new one!
let deckEntity = NSEntityDescription.entity(forEntityName: "Deck", in: self.managedContext)
let deckName = Deck(entity: deckEntity!, insertInto: self.managedContext)
deckName.isCreatedByMe = true
deckName.cKRecordToDeck(record)
}
} else {
尝试调试我在else块中设置了一个断点来创建一个新的Core Data&#34; Deck&#34;实体并注意到,当fetch返回我刚刚在设备上创建并保存到Core Data的Cloudkit记录时,它会触发。然而,该应用程序认为它不在Core Data中并创建了一个新的重复记录。
保存记录代码:
func saveItem(_ name: String) {
guard let entity = NSEntityDescription.entity(forEntityName: "Deck", in: managedContext) else{
print("Could not save item")
return
}
let deckName = Deck(entity: entity, insertInto: managedContext)
deckName.name = name
deckName.isCreatedByMe = true
do {
try managedContext.save()
}
catch {
let saveError = error as NSError
print(saveError)
}
let zoneID = CKManager.defaultManager.sharedZone?.zoneID
let deckSetToBeSaved = deckName.deckToCKRecord(zoneID)
privateDatabase.save(deckSetToBeSaved) { (record, error) in
print("New record saved")
print(error as Any)
}
}
以下是概述序列,以便更清楚地说明问题:
创建一个新的&#34; Deck&#34;在应用程序中记录成功保存到 核心数据和我的Cloudkit专用数据库。
重新打开应用以触发私有数据库上的Cloudkit提取。
获取运行并成功显示,唯一的重复是刚创建并保存在设备上的记录。
提前感谢您的帮助。