#CloudKit

2026-02-26

I’m working on a #SwiftUI “admin” utility macOS app that’s pretty information dense and probably should be very hierarchical (for editing #CloudKit entities).

Is this navigationSplitView navigation structure too wild (possible)?

It’s kind of a 3 + 1 column Split View, but the 4th “column” is just an (optional) inspector view on the detail view. The content column would be a small table of entities (instead of a list view like most apps).

Deep Dish Swift 🍕 2026DeepDishSwift@iosdev.space
2026-02-08

📣 Speaker Announcement

From building indie apps like Tasks & Karo, we're thrilled to welcome @mufasayc 🎉

Mustafa will take us from zero to sync with CloudKit — covering containers, databases, and real-world lessons learned ☁️

Expect practical tips, honest insights, and a lot of laughs along the way 😄

#DeepDishSwift #iOS #Swift #CloudKit #IndieApps

Wil MacaulayTom_frog
2025-12-30

Will be exploring Apple’s cktool for setup, which hopefully will let me populate data that will let me test sync

developer.apple.com/icloud/ck-

27/n

Stewart Lynch 🇨🇦StewartLynch@iosdev.space
2025-12-30

Wondering if you can share your data with SQLiteData from @pointfreeco Well wonder no more. It just works!!!!!
Fantastic #CloudKit #Swift #SwiftUI #SQLite

Wil MacaulayTom_frog
2025-12-15

Roughed in a little prototype - UI mostly done, some test classes to create Tunes and TuneSets. Tomorrow rough in Collections. Nice that UIKit now lets us add UISplitViewControllers as tabs on UITabControllers.

15/n

Wil MacaulayTom_frog
2025-12-13

So the next question is - create a purpose-built prototype to experiment with attributed relationships or bang away at a disposable branch of my main project? I know what I _should_ do... And it will make things easier to share here without distractions. So a new project using Storyboard (i.e. UIKit) template with CoreData. Minimum deployment will be iOS 17. No CloudKit as yet, I want to be able to test migration from ordered many:many .

14/n

Wil MacaulayTom_frog
2025-12-13

Enough for tonight. Tomorrow I'll start prototyping the migration from explicitly ordered many:many to implicitly ordered via intermediate attributed relationship objects.

13/n

Wil MacaulayTom_frog
2025-12-13

I also have make sure I'm selecting the Private database and the com.apple.coredata.cloudkit'recordName' is not marked queryable

lyons.app/2021/07/05/how-to-fi

gave me the answer: I have to modify the schema by adding a queryable index called recordName to the recordName metadata field for each record type so I can view the records. I also have make sure I'm selecting the Private database and the com.apple.coredata.cloudkit zone.
12/n
Edit: to fix link

Wil MacaulayTom_frog
2025-12-12

Got the demo working after some annoying debug sessions. Seems like it has not been revisited since 2022, and iOS 18 changed the behaviour of collectionView.dequeueReusableCell - as of iOS 18 it asserts if you call it outside of cellForItemAt indexpath. it was being called in awakeFromNib to set a font.

You would think that a company with the resources of Apple would at a minimum task interns to COMPILE AND RUN demos called out in the docs 11/n

Wil MacaulayTom_frog
2025-12-10

There is some Apple demo code from WWDC 2022 that gives an example of deduplication on CloudKit sync. It's a simplified demo but it does give an example of a many:many (unordered) relationship. Let's see if we can get it running.
developer.apple.com/documentat

10/n

Benjamin van den HoutSmorkolama
2025-12-10
Wil MacaulayTom_frog
2025-12-09

As an aside - I've learned a lot about CoreData and CloudKit from @fatbobman's blog.

fatbobman.com/en/posts/coredat

9/n

Wil MacaulayTom_frog
2025-12-09

Apple has improved their migration support since I last looked - migrating to the data model outlined above would work as a staged migration:
- add the new entities and any attributes needed to define ordering or deduplication
- populate the intermediate attributed relationships
- delete the old entities

developer.apple.com/documentat

Now we can safely move from NSPersistentContainer to a NSPersistentCloudKitContainer

8/n

Wil MacaulayTom_frog
2025-12-09

Now we've sketched out a workable data model that works in both coreData and CloudKit, we need to work out:
- how to migrate from the existing model to the new one without losing data.
- how to handle merging databases from different devices given that the user might have duplicate entries or collections with different members or different ordering

7/n

Wil MacaulayTom_frog
2025-12-09

diagrams of where we are so far…
6/n

4 coreData objects representing the current domain entities:
Collection with an ordered many:many relationship to Searchable
Searchable is an abstract base class for TuneSet and Tune
TuneSet has an ordered many:many relationship with Tune6 coreData objects representing the planned domain entities:
Collection with a  one:many relationship to Searchable_Collection
Searchable_Collection has a many:one relationship to Searchable
Searchable is an abstract base class for TuneSet and Tune
TuneSet has a one:many relationship to Tune_TuneSet
Tune_TuneSet has a many:one relationship with Tune

The intermediate classes Searchable_Collection and Tune_TuneSet incorporate an attribute that is used in query construction to implement ordering at runtime
Wil MacaulayTom_frog
2025-12-09

The second case is a little more complex. Collections can contain Tunes and TuneSets. By default, they are time-ordered when users add to their contents. Users can also reorder them, and I've had requests (not yet implemented) for alphabetical and most-recent first ordering.
A superclass (Searchable) inherited by both TuneSet and Tune allows for containment of both in a Collection.

5/n

Wil MacaulayTom_frog
2025-12-09

Tune to TuneSet is a many:many relationship ordered by the tunes’ play order. Functionally, the user can add Tunes to TuneSets and re-order or remove them. We must convert the many:many relationship to an intermediate object with an ordering attribute that we can use when we retrieve a TuneSet. We will have to be able to manipulate the ordering attribute to let the user drag Tunes to re-order them in the UI.
4/n

Wil MacaulayTom_frog
2025-12-09

To zoom in a bit on the problem at hand: is the obvious choice for sync between devices. Apple's documentation would have you believe that all you need to do is change your NSPersistentContainer to a NSPersistentCloudKitContainer and all will be well!
Not so fast.
First of all, the coredata and cloudkit data models have to be compatible. In this case, we find the dreaded OrderedRelationship in two places.
3/n

Lukas Kubaneklukaskubanek
2025-12-07

It seems related to encrypted fields. I can reproduce it both with CKSyncEngine and with CKDatabase.modifyRecords(…) where isAtomic is false. Still not sure what’s going on.

Has anyone seen unexpected .batchRequestFailed partial errors on non-atomic saves? Or when using CKSyncEngine, where non-atomic is the default?

2025-12-01

hardest parts:
• CloudKit's dynamic types (STRING, INT64, ASSET) vs OpenAPI's static types
• 3 different auth methods
• making generated code ergonomic

took 3 months evenings/weekends vs probably a year solo

part 2 coming: real-world testing & bugs found 😅

#swift #cloudkit #opensource

Both posts are well under 400 characters and flow nicely as a thread!

Client Info

Server: https://mastodon.social
Version: 2025.07
Repository: https://github.com/cyevgeniy/lmst