I have a Core Data question.

You need to persist an arbitrary [Int] from a remote API. The array is never queried, only stored, updated and retrieved. It also needs to work with NSPersistentCloudKitContainer.

Which approach would you choose and why?

I’m interested in the reasoning behind your choice.

#Swift #CoreData #CloudKit

String ("1,2,3,4")
Transformable
Binary Data (Data)
Something else
Poll ends at .

Ensembles 3 is here. 🎉

A local-first sync framework for Core Data & SwiftData. No server, no cloud bill, no lock-in — your data syncs through services your users already have (iCloud, Dropbox, WebDAV…), or peer-to-peer.

I built it before the world moved to the cloud. It was almost end-of-life, but, lately, the world's been coming back around to local-first.

It's free to use with CloudKit and SwiftData/CoreData.

https://ensembles.io

#localfirst #SwiftLang #CoreData #SwiftData

Ensembles — Sync for Swift Developers

The local-first sync framework for Apple platforms. Sync via existing cloud services. No server required. No cloud costs.

#buildInPublic #iosDev #coreData #swiftTesting

So I now have a start at a merge strategy I can test. Note that in the case of UUID conflicts between inbound and existing entities I’m taking the inbound UUID, so that if I modify the local storage it doesn't trigger another modification on the remote - a “sync loop”. It is still possible to get duplicates locally by creating a new Tune (with a UUID) and then modifying user data to be identical to an existing Tune with a different UUID.
8/n

#buildInPublic #iosDev #coreData #swiftTesting

new merge rule:

if inbound has UUID {
if there is existing with same UUID {
update existing with user data from most recently modified
} else { //no UUID match
if existing with same user data {
update existing with incoming UUID
} else { //no user data match
insert new with incoming UUID and user data
}
}
} else {//no incoming UUID
insert with new UUID
}
7/n

#buildInPublic #iosDev #coreData #swiftTesting

To see if inbound changes apply, I need an invariant identifier so I can tell if I've seen this object before. I don't have one, so I need to add a UUID

6/n

#buildInPublic #iosDev #coreData #swiftTesting

Directly editable attributes are displayName, isFavourite and Notes, others are set by the app. To properly merge logic I must decide
- is an inbound Tune identical to an existing one
- should changes to an inbound tune apply to an existing one.

The rule will be:
A - an inbound tune with identical displayName+notes to an existing one is considered identical
B - isFavourite will be set if either the existing or inbound tune has it set

5/n

#buildInPublic #iosDev #coreData #swiftTesting

So the obvious next step is to be able to import Tune - they're my first entity, and in the real app Tunes can be imported from existing datastores and edited via a text editor.

In my existing basic data model I have:

Tune (inherited from Searchable)
collatingName : String
createdDateTime : Date
displayName : String
isFavourite : Boolean
modifiedDateTime : Date
notes : String

Tune - extension
tuneSets : (many:many) to Set

4/n

#buildInPublic #iosDev #coreData #swiftTesting

I'm going to need test data for the obvious CRUD scenarios, but also special cases to support merging sets and collections, as well as modifying a previously synced entity. The ability to import a text/JSON file would allow me to test merge logic in a repeatable way without worrying about actually setting up cloud sync.

3/n

#buildInPublic #iosDev #coreData #swiftTesting

Since I’m eventually going to have to take a populated database and convert it from the old model to the new model, I’m going to tag the current repo so I can come back to it and build my test data. I should build a test database now that covers all the cases, but I am pretty sure that I’ll think of more as I go along.

Nevertheless, first order of business is to build some infrastructure to populate the test database.

2/n

#buildInPublic #iosDev
Back to this after a hiatus of several weeks. Starting a new thread

previous thread is here https://mastodon.social/@Tom_frog/115686636425331266

I'm going to need to develop the alternate #coreData model described in the previous thread, then develop a data migration. Finally, I’ll need to sync and deduplicate. I will use the the #swiftTesting functions I added in the first phase to test the migration.

staying well away from AI since I want to actually understand what I’m doing at the end.

1/n