将Cloudkit专用数据库与Core Data同步会创建重复的已保存记录

时间:2017-12-31 08:59:09

标签: ios swift core-data cloudkit

编辑:使用代码编辑,将记录保存到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)
    }



}

以下是概述序列,以便更清楚地说明问题:

  1. 创建一个新的&#34; Deck&#34;在应用程序中记录成功保存到 核心数据和我的Cloudkit专用数据库。

  2. 重新打开应用以触发私有数据库上的Cloudkit提取。

  3. 获取运行并成功显示,唯一的重复是刚创建并保存在设备上的记录。

  4. 提前感谢您的帮助。

0 个答案:

没有答案