CKSyncEngine & SwiftData

I am working on a SwiftUI application that needs to sync data across multiple devices using CloudKit. I am trying to decide between two options:

  • CKSyncEngine with a custom model
  • SwiftData plus CloudKit container.

This decision is crucial for me because the application I am developing is using tree structured data and the relationship between the data is very complex. I would appreciate your guidance on which option is better suited for my needs.

One of the benefits of using SwiftData is that it has a lot of interesting features that can save me a lot of development time, such as automatic migrations, batch operations, predicates, sorting, grouping, etc. However, one of the drawbacks is that it may not be flexible enough to handle the complex data display logic that I need for my application. For example, I need to show different views depending on the level and type of the tree nodes, and I also need to perform some calculations and transformations on the data before displaying it. I am afraid that using SwiftData will lead to more complexity and uncertainty when implementing these features, and there may be performance issues as well.

Another factor that I need to consider is the future support and development of these options. I believe SwiftData will have a good future because it is based on Apple's frameworks and technologies. However, I don't know if CKSyncEngine will be valued in the long run because it is a third-party framework that may not be updated or maintained regularly.

In conclusion, I am still unsure whether to use CKSyncEngine or SwiftData for my SwiftUI application that needs CloudKit sync. Both options have their pros and cons, and I need to weigh them carefully according to my requirements and preferences. I would love to hear your opinion on this matter.

Thank you for your time and attention.

Replies

What do you mean that CKSyncEngine is a third-party framework? It's a native part of CloudKit.

I'm just starting to play with this myself, but as far as I can tell you can use SwiftData with CKSyncEngine. The sample Apple provided, at https://github.com/apple/sample-cloudkit-sync-engine, shows linking CloudKit to your model. The model could be a SwiftData model that just includes something like a var cloudKitRecordId: CKRecord.ID? property.

One of the benefits of SwiftData is that it allows us to access CloudKit containers directly without having to deal with CKRecord and other low-level details. However, I am wondering which solution is better for an app that has a complex view model. Is SwiftData suitable for handling complex data structures and relationships? Or should we use the the traditional way to code the view models with CKSyncEngine for sync?

At the end of the day, SwiftData is just a bunch of swift classes, and so it can be as simple or complex as you want to make them.

Have you figured out how to link SwiftData with CloudKit containers? I'm still trying to work that out. The ModelContainer is created in the body of the app, and that doesn't take a cloud kit container name. I'd love to see a sample of how you're doing that.

The ModelConfiguration is what you are looking for. I do not get chance to try it, but the WWDC video shows the way like:

let people = ModelConfiguration(..., cloudKitContainerIdentifier: "com.***.***") 
let container = try ModelContainer(for: ..., people)

I understand that SwiftData is a set of swift classes. However, I have some concerns about using them directly in the UI, as shown in the videos and the examples. This may lead to some problems:

  • Performance issue. For instance, if a record contains some images, how can I handle them efficiently with SwiftData? I don't want to load all the image data in memory, but rather cache them in files and load the URL in the view model.

  • Complicated logic. Using SwiftData models in the UI may be convenient for coding, but sometimes the logic may become too complex. We may need to create other view models based on the basic models. But SwiftData is not a lightweight variable, and I don't know how to track the changes of the SwiftData models in other custom @Observeable models.

I have no more CoreData experience, would you please help to suggest the way to use SwiftData for my preceding concerns?

I've converted a version of my UIKit app to use SwiftData and CloudKit from CoreData/CloudKit. It works and the apps are syncing, but I am having a problem getting a notification when the data changes so I can update my view.