mentrena / SyncKit

Automatic CloudKit synchronization
https://mentrena.github.io/SyncKit/
MIT License
507 stars 59 forks source link

Remote schema not reliably created/updated #179

Open nneubauer opened 2 years ago

nneubauer commented 2 years ago

If I start with a reset dev database/environment in my iCloud Console and created my first CloudKitSynchronizer, it will "lazily" create some record types.

Specifically it will create those that already exist at the time of the sync. However, if other records are created later, they don't get created and sometimes references are missing. I tried different combinations of resetting my local metadata and waiting with the first sync until I think I have all entities created locally but I never got it to reliably create all record types.

Is there a way to initialize the remote schema based on the local schema like explained in the Apple docs (https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/creating_a_core_data_model_for_cloudkit)?

mentrena commented 2 years ago

Those docs are specific to NSPersistentCloudKitContainer, which is Apple's implementation of a CloudKit backed CoreData container. I'd recommend looking at it before deciding on adopting SyncKit, I don't have experience with it myself but it could be that it meets your needs, and I won't pretend that I can provide the same level of maintenance as Apple 😅

SyncKit was created before NSPersistentCloudKitContainer was available, so the generic CloudKit documentation is a better reference for how to use CloudKit in the context of SyncKit: https://developer.apple.com/documentation/cloudkit/designing_and_creating_a_cloudkit_database

There are two ways to create the schema:

And eventually you would promote the schema to Production once you're sure it won't change. Hope that was helpful.

nneubauer commented 2 years ago

Hey, thanks for the reply. Of course I know that SyncKit is an alternative and not based on Apple's implementation but the bug I am mentioning is related to way two you describe:

just-in-time, running your app as you develop and letting CloudKit pick up the schema based on the records that you upload.

This does not work reliably and I don't know why.

For the alternative

manually, using the CloudKit dashboard.

I think some additional documentation on how to do that would be great -- like which Core Data data types map to which Cloud Kit types. Or maybe as a feature suggestion, you could generate something similar to what Apple provides to just initialize the Cloud Kit schema once by going through your Core Data model.

mentrena commented 2 years ago

This does not work reliably and I don't know why.

Are you actually creating and uploading all the possible objects/relationships in your schema while you develop? Or are you saying that you're creating the objects and syncing, but somehow CloudKit is not reflecting their schemas when you check the dashboard?

In my case I've never created the schema manually using the dashboard as I have never needed to.

I think some additional documentation on how to do that would be great -- like which Core Data data types map to which Cloud Kit types.

You're very right, I'll do that too.

sskjames commented 2 years ago

I, too, started facing this problem. Never faced this before. I have many record types in CloudKit and they are in production now. When I created a new Realm entity, got this error during sync: <CKError 0x60000217b7e0: "Invalid Arguments" (12/2006); server message = "Record type FooEntity is missing field fooField in schema, please update your schema"; > After I created the required RecordType and fields, the error went away. Never had to do this before. Could this be because of some changes in CloudKit?

I tried debugging a little, but it looks like the problem is not with SyncKit. SyncKit has correctly captured this new RecordType in it's SyncedEntity table.

aehlke commented 1 year ago

Anyone find resolution for this?