CKSyncEngine keeps attempting to sync the same record

I am attempting to migrate a cloudkit module that calls on manual cloudkit methods for fetching record zone changes, modifying records, etc to one that utilizes CKSyncEngine. I've got a basic implementation working with just a create method for one of my data models, however it seems like the sync engine keeps calling sync events on the same pending changes.

Here is my current flow:

  1. The user will hit some button that lets them fill out a form to create a data model.
  2. The user saves the form. This triggers a method that takes the resulting data model and queues it to the sync engine's state (engine.state.add(pendingRecordZoneChanges: pendingChanges)
  3. I have my delegate method nextRecordZoneChangeBatch(_ context:...) implemented where it fetches the corresponding data model using the record ID and returns a batch containing the corresponding populated record from the data model.
  4. I have the handleEvent(_ event:...) delegate method implemented where I handle both .fetchRecordZoneChanges and .sentRecordZoneChanges. I have set up .sentRecordZoneChanges to merge the server record into my local record (and persisted locally) so that the record change tags are the same.

After this last portion, it seems that the sync engine continues to keep pushing syncs/updates and I end up with numerous handleEvent(_ event:) calls that keep returning savedRecords (and occasionally failedRecordSaves).

Am I missing some step to remove the record from the changes after the sync engine recognizes that I have properly saved the record to the server?

Answered by kvdcm in 822231022

I've found the source of my issue and thus resolved it.

In my method that adds my domain models to the sync engine's state as PendingRecordZoneChanges, I was mapping my model's IDs to a CKRecord.ID's record name, but I forgot to include the zoneID in the initializer for the record ID. This is what caused the sync engine to continuously send sync events.

My guess is that because my pending changes did not include the zone ID, the local and server records were considered different and thus the engine would keep trying to sync. Curiously, it still populated in the proper zone when I checked the cloudkit console.

Some more information on this issue:

After some additional troubleshooting, one thing I did forget to do is to update the serialization state in the .stateUpdate event case in handleEvent(_event:CKSyncEngine.Event,...) method. However, even after fixing this where I cache the serialization state and set our local state to that new state, I am still encountering the issue where the sync engine continues sending the next record zone batch. No properties are being saved on the record between syncs either.

Accepted Answer

I've found the source of my issue and thus resolved it.

In my method that adds my domain models to the sync engine's state as PendingRecordZoneChanges, I was mapping my model's IDs to a CKRecord.ID's record name, but I forgot to include the zoneID in the initializer for the record ID. This is what caused the sync engine to continuously send sync events.

My guess is that because my pending changes did not include the zone ID, the local and server records were considered different and thus the engine would keep trying to sync. Curiously, it still populated in the proper zone when I checked the cloudkit console.

CKSyncEngine keeps attempting to sync the same record
 
 
Q