According to my experiments SwiftData does not work with model attributes of primitive type UInt64. More precisely, it crashes in the getter of a UInt64 attribute invoked on an object fetched from the data store.
With Core Data persistent UInt64 attributes are not a problem. Does anyone know whether SwiftData will ever support UInt64?
iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a @Model class that is comprised of a String and a custom Enum. It was working until I added raw String values for the enum cases, and afterwards this error and code displays when opening a view that uses the class:
{
@storageRestrictions(accesses: _$backingData, initializes: _type)
init(initialValue) {
_$backingData.setValue(forKey: \.type, to: initialValue)
_type = _SwiftDataNoType()
}
get {
_$observationRegistrar.access(self, keyPath: \.type)
return self.getValue(forKey: \.type)
}
set {
_$observationRegistrar.withMutation(of: self, keyPath: \.type) {
self.setValue(forKey: \.type, to: newValue)
}
}
}
Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1cc165d0c)
I removed the String raw values but the error persists. Any guidance would be greatly appreciated. Below is replicated code:
@Model
class CopingSkillEntry {
var stringText: String
var case: CaseType
init(stringText: String, case: CaseType) {
self.stringText = stringText
self.case = case
}
}
enum CaseType: Codable, Hashable {
case case1
case case1
case case3
}
I’m trying to build a CRUD app using SwiftData, @Query model and multidatepicker.
The data from a multidatepicker is stored or persists in SwiftData as Set = [].
My current dilemma is how to use SwiftData and @Query model Predicate to find all records on the current date.
I can’t find any SwiftData documentation or examples @Query using Set = [].
My CRUD app should retrieve all records for the current date. Unfortunately, I don’t know the correct @Query model syntax for Set = [].
I have an app that uses Core Data. I'm switching to SwiftData but it looks like the sqlite files are stored in separate places in the application file directory so my SwiftData files aren't reading the CoreData store. I'm not sure why it's not reading from the same location. Is there something I'm missing? Here's an example of the paths that I see when I write information to the debug console:
SwiftData Path: file:///Users/dougthiele/Library/Developer/CoreSimulator/Devices/52CE32F8-F6A9-4825-8027-994DBE47173C/data/Containers/Data/Application/63E9B61D-64B8-4D2D-A02C-3C306688F354/Documents/[Data File Name].sqlite
Core Data Path:
file:///Users/dougthiele/Library/Developer/CoreSimulator/Devices/52CE32F8-F6A9-4825-8027-994DBE47173C/data/Containers/Data/Application/96A5961B-54DD-43A9-A4C3-661B439D91AE/Documents/[Data File Name].sqlite
Topic:
App & System Services
SubTopic:
iCloud & Data
My question
Is there a way to perform an iCloud keychain reset in order to be able to test CKErrorUserDidResetEncryptedDataKey ?
I found this section in the CloudKit documentation
https://developer.apple.com/documentation/cloudkit/encrypting-user-data#Handle-a-User-Keychain-Reset
I want to be prepared for the zoneNotFound / CKErrorUserDidResetEncryptedDataKey case.
However, I can't find a way to actually reproduce this error with an iCloud (test-) user and can't find any Apple documentation on how to perform sucha "User Keychain Reset".
The only thing that almost looked like it I came across was in the Keychain.app's Settings "Reset Default Keychains…". However, performing this didn't seem to affect the CloudKit data used in our App at all.
I've been trying to do this with an Apple account that has 2FA active and a recovery account assigned.
We're only targetting >= iOS 18, macOS >= 15.
I created a new index on two record types on Oct 12th. I still cannot query the records using the new queryable index on records that were created before that date. There is no indication in the schema history that the reindexing has started, completed, failed, or still in progress.
What is the expectation for new indices being applied to existing records? Well over a week seems unacceptable for a database that has maybe 5000 records across a few record types.
When I query my data using an old index and an old record field, I get hundreds of matching results so I know the data is there.
FB15554144 - CloudKit / CloudKit Console: PRODUCTION ISSUE - Query against index created two weeks ago not returning all data as expected
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags:
App Store
CloudKit
CloudKit Console
CloudKit Dashboard
Something has caused my CloudKit queries to fail. On the dashboard I get an error message "Failed to execute query" when I try to "SORT BY" a field. The field is listed under Indexes as "sortable". For a different field, when I enter the field under "FILTER BY", and before I tap "Query", I get "No results". That field is listed under the Indexes as "queryable".
It used to work fine.
I have described this further, with screenshots at FB16114560
Hello. I am re-writing our way of storing data into Core Data in our app, so it can be done concurrently.
The solution I opted for is to have a singleton actor that takes an API model, and maps it to a Core Data object and saves it.
For example, to store an API order model, I have something like this:
func store(
order apiOrder: APIOrder,
currentContext: NSManagedObjectContext?
) -> NSManagedObjectID? {
let context = currentContext ?? self.persistentContainer.newBackgroundContext()
// …
}
In the arguments, there is a context you can pass, in case you need to create additional models and relate them to each other. I am not sure this is how you're supposed to do it, but it seemed to work.
From what I've understood of Core Data and using multiple contexts, the appropriate way use them is with context.perform or context.performAndWait.
However, since my storage helper is an actor, @globalActor actor Storage2 { … }, my storage's methods are actor-isolated.
This gives me warnings / errors in Swift 6 when I try to pass the context for to another of my actor's methods.
let context = …
return context.performAndWait {
// …
if let apiBooking = apiOrder.booking {
self.store(booking: apiBooking, context: context)
/* causes warning:
Sending 'context' risks causing data races; this is an error in the Swift 6 language mode
'self'-isolated 'context' is captured by a actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses
Access can happen concurrently
*/
}
// …
}
From what I understand this is because my methods are actor-isolated, but the closure of performAndWait does not execute in a thread safe environment.
With all this, what are my options? I've extracted the store(departure:context:) into its own method to avoid duplicated code, but since I can't call it from within performAndWait I am not sure what to do.
Can I ditch the performAndWait? Removing that makes the warning "go away", but I don't feel confident enough with Core Data to know the answer.
I would love to get any feedback on this, hoping to learn!
I'm trying to safely perform the apparently complex task for a cloud storage API, namely "downloading files", but it seems like iCloud APIs are comically broken beyond repair:
-[NSFileCoordinator coordinateAccessWithIntents:queue:byAccessor:] calls the accessor block before all files have finished downloading.
The same API will also return success (called the block with error == nil) even if the download fails (e.g. the phone is in airplane mode). I both cases, the files requested by the intents will not exist.
-[NSFileManager startDownloadingUbiquitousItemAtURL:error:] does not have a completion block (Why?!?!)
Similarly, this API will return success even if it fails (e.g. airplane mode)
Manually checking NSURLUbiquitousItemIsDownloadingKey is broken as well, failed downloads (e.g. Airplane mode again) will retain their "Downloading" status, and NSURLUbiquitousItemDownloadingErrorKey is never updated.
How can one safely download a file from iCloud if all of the APIs are broken?
Topic:
App & System Services
SubTopic:
iCloud & Data
In a document based SwiftData app for macOS, how do you go about opening a (modal) child window connected to the ModelContainer of the currently open document?
Using .sheet() does not really result in a good UX, as the appearing view lacks the standard window toolbar.
Using a separate WindowGroup with an argument would achieve the desired UX. However, as WindowGroup arguments need to be Hashable and Codable, there is no way to pass a ModelContainer or a ModelContext there:
WindowGroup(id: "myWindowGroup", for: MyWindowGroupArguments.self) { $args in
ViewThatOpensInAWindow(args: args)
}
Is there any other way?
Am developing an iOS App, which uses a ZipFoundation wrapper around Compression. In XCode, have exported a document type with extension '.MU' in the Info.plist.
On iPhone, when attempting to open archive called: 'Snapshot-test.mu'
can OPEN as a mobile email attachment
but FAILED via Files App referring to "iCloud Drive/Desktop"
Here are the respective URLS
"file:///private/var/mobile/Containers/Data/Application/<UniqueID>/Documents/Inbox/Snapshot-test.mu"
"file:///private/var/mobile/Library/Mobile%20Documents/com~apple~CloudDocs/Desktop/Snapshot-test1.mu"
Two questions:
Is it possible to grant access to files residing remotely in iCloud?
Is "iCloud Drive/Desktop" unique, whereas other iCloud locations would be OK?
I'm trying to set up an application using SwiftData to have a number of models backed by a local datastore that's not synced to CloudKit, and another set of models that is. I was able to achieve this previously with Core Data using multiple NSPersistentStoreDescription instances.
The set up code looks something like:
do {
let fullSchema = Schema([
UnsyncedModel.self,
SyncedModel.self,
])
let localSchema = Schema([UnsyncedModel.self])
let localConfig = ModelConfiguration(schema: localSchema, cloudKitDatabase: .none)
let remoteSchema = Schema([SyncedModel.self])
let remoteConfig = ModelConfiguration(schema: remoteSchema, cloudKitDatabase: .automatic)
container = try ModelContainer(for: fullSchema, configurations: localConfig, remoteConfig)
} catch {
fatalError("Failed to configure SwiftData container.")
}
However, it doesn't seem to work as expected. If I remove the synced/remote schema and configuration then everything works fine, but the moment I add in the remote schema and configuration I get various different application crashes. Some examples below:
A Core Data error occurred." UserInfo={Reason=Entity named:... not found for relationship named:...,
Fatal error: Failed to identify a store that can hold instances of SwiftData._KKMDBackingData<...>
Has anyone ever been able to get a similar setup to work using SwiftData?
While reading CkSyncEngine demo project code, I don't find the code to remove items in syncEngine.state.pendingRecordZoneChanges explicitly. I suspect it might occur in two possible places: nextRecordZoneChangeBatch() or ``nextRecordZoneChangeBatch()`, but I can't figure out how it occurs.
nextRecordZoneChangeBatch() has the following code:
let batch = await CKSyncEngine.RecordZoneChangeBatch(pendingChanges: changes) { recordID in
if let contact = contacts[recordID.recordName] {
let record = contact.lastKnownRecord ?? CKRecord(recordType: Contact.recordType, recordID: recordID)
contact.populateRecord(record)
return record
} else {
// We might have pending changes that no longer exist in our database. We can remove those from the state.
syncEngine.state.remove(pendingRecordZoneChanges: [ .saveRecord(recordID) ])
return nil
}
}
(I'll ignore the syncEngine.state.remove(pendingRecordZoneChanges:) in the else clause, because it's unrelated)
Could it be that CKSyncEngine.RecordZoneChangeBatch.init(pendingChanges:,recordProvider:) automatically remove a CKRecord when the recordProvider: closure returns a non-nil value? I checked its document, but it doesn't say anything about this.
Thanks for any help.
Hi everyone,
I’ve been working on migrating my app (SwimTimes, which helps swimmers track their times) to use Core Data + CKSyncEngine with Swift 6.
After many iterations, forum searches, and experimentation, I’ve created a focused sample project that demonstrates the architecture I’m using.
The good news:
👉 I believe the crashes I was experiencing are now solved, and the sync behavior is working correctly.
👉 The demo project compiles and runs cleanly with Swift 6.
However, before adopting this as the final architecture, I’d like to ask the community (and hopefully Apple engineers) to validate a few critical points, especially regarding Swift 6 concurrency and Core Data contexts.
Architecture Overview
Persistence layer: Persistence.swift sets up the Core Data stack with a main viewContext and a background context for CKSyncEngine.
Repositories: All Core Data access is abstracted into repository classes (UsersRepository, SwimTimesRepository), with async/await methods.
SyncEngine: Wraps CKSyncEngine, handles system fields, sync tokens, and bridging between Core Data entities and CloudKit records.
ViewModels: Marked @MainActor, exposing @Published arrays for SwiftUI. They never touch Core Data directly, only via repositories.
UI: Simple SwiftUI views bound to the ViewModels.
Entities:
UserEntity → represents swimmers.
SwimTimeEntity → times linked to a user (1-to-many).
Current Status
The project works and syncs across devices. But there are two open concerns I’d like validated:
Concurrency & Memory Safety
Am I correctly separating viewContext (main/UI) vs. background context (used by CKSyncEngine)?
Could there still be hidden risks of race conditions or memory crashes that I’m not catching?
Swift 6 Sendable Compliance
Currently, I still need @unchecked Sendable in the SyncEngine and repository layers.
What is the recommended way to fully remove these workarounds and make the code safe under Swift 6’s stricter concurrency rules?
Request
Please review this sample project and confirm whether the concurrency model is correct.
Suggest how I can remove the @unchecked Sendable annotations safely.
Any additional code improvements or best practices would also be very welcome — the intention is to share this as a community resource.
I believe once finalized, this could serve as a good reference demo for Core Data + CKSyncEngine + Swift 6, helping others migrate safely.
Environment
iOS 18.5
Xcode 16.4
macOS 15.6
Swift 6
Sample Project
Here is the full sample project on GitHub:
👉 [https://github.com/jarnaez728/coredata-cksyncengine-swift6]
Thanks a lot for your time and for any insights!
Best regards,
Javier Arnáez de Pedro
After the significant issues with the ModelActor in iOS 18, it seemed like the ModelActor became more stable with iOS 18.1 and macOS 15.1.
However, I’m still encountering problems and crashes. I wanted to ask if these issues are related to my persistence layer architecture or if they’re still inherent to the ModelActor itself.
I’ve generally followed the blog posts:
https://fatbobman.com/en/posts/practical-swiftdata-building-swiftui-applications-with-modern-approaches/
and
https://brightdigit.com/tutorials/swiftdata-modelactor/
and aim to achieve the following:
I have a single DataProvider that holds the ModelContainer and uses it to configure and initialize a single DataHandler. These are created once at app launch and injected into the SwiftUI view hierarchy as EnvironmentObjects. Since I need to access the SwiftData models not only in SwiftUI but also indirectly in ViewModels or UIKit views, all read operations on the models should go through the DataProvider (and its MainContext), while all other CRUD operations are handled centrally via the single DataHandler (executed within a single ModelActor).
Additionally, I want to monitor the entire container using another ModelActor, initialized in the DataProvider, which tracks changes to objects using TransactionHistory.
I’ve managed to implement this to some extent, but I’m facing two main issues:
1. ModelActor and Main Actor Requirement
The ModelActor only updates SwiftUI views when initialized via the maincontext of the ModelContainer and therefore runs on the Main Actor. It would be ideal for this to work in the background, but the issue with the ModelActor that existed previously doesn’t seem to have been resolved in iOS 18.1/macOS 15.1—am I wrong about this?
2. Frequent Crashes (more severe)
Crashes occur, especially when multiple windows on macOS or on iPad access the same DataHandler to update models. This often leads to crashes during read operations on models by a SwiftUI view (but not only), with logs like:
error: the replacement path doesn't exist: "/var/folders/gs/8rwdjczj225d1pj046w3d97c0000gn/T/swift-generated-sources/@__swiftmacro_12SwiftDataTSI3TagC4uuID18_PersistedPropertyfMa_.swift"
Can't show file for stack frame : <DBGLLDBStackFrame: 0x34d28e170> - stackNumber:1 - name:Tag.uuID.getter. The file path does not exist on the file system: /var/folders/gs/8rwdjczj225d1pj046w3d97c0000gn/T/swift-generated-sources/@__swiftmacro_12SwiftDataTSI3TagC4uuID18_PersistedPropertyfMa_.swift
This error usually happens when there are multiple concurrent accesses to the DataHandler/ModelActor. However, crashes also occur sporadically during frequent accesses from a single view with an error like "the replacement path doesn't exist."
It also seems like having multiple ModelActors, as in this case (one for observation and one for data changes), causes interference and instability. The app appears to crash less frequently when the observer is not initialized, but I can’t verify this—it might just be a coincidence.
My Question:
Am I fundamentally doing something wrong with the ModelActors or the architecture of my persistence layer?
When I try to promote schema to production, I get following error:
Cannot promote schema with empty type 'workspace', please delete the record type before attempting to migrate the schema again
However, in hierarchical root record sharing, I think it should be completely legit use case where there is empty root record (in my case workspace) to which other records reference through ->parent reference.
Am I missing something? Is this weird constraint imposed on CloudKit?
I'm studying sharing through this link. I followed the first steps by changing the bundle identifier of the project, the tests and placing my own container in the config and in the info.plist.
https://github.com/apple/sample-cloudkit-zonesharing
The app appears and in the log it appears that it has managed to access my iCloud, but when I click on share and share something, the following message appears in the console, on the simulator and on the iPhone:
"No options were found, providing default value for access type"
"No options were found, providing default values for permissions"
"connection invalidated"
And finally, when I click on the shared link, the following message appears:
"Item unavailable
The owner stopped sharing, or you don't have permission to open it."
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags:
CloudKit
Privacy
iCloud Drive
iCloud Keychain Verification Codes
I have an iOS app using SwiftData with VersionedSchema. The schema is synchronized with an CloudKit container.
I previously introduced some model properties that I have now removed, as they are no longer needed. This results in the current schema version being identical to one of the previous ones (except for its version number).
This results in the following exception:
'NSInvalidArgumentException', reason: 'Duplicate version checksums across stages detected.'
So it looks like we cannot have a newer schema version with an identical content to an older schema version.
The intuitive way would be to re-add the old (identical) schema version to the end of the "schemas" list property in the SchemaMigrationPlan, in order to signal that it is the newest one, and to add a migration stage back to it, thus:
public enum MySchemaMigrationPlan: SchemaMigrationPlan {
public static var schemas: [any VersionedSchema.Type] {
[
SchemaV100.self,
SchemaV101.self,
SchemaV100.self
]
}
public static var stages: [MigrationStage] {
[
migrateV100toV101,
migrateV101toV100
]
}
However, I am not sure if this is the right way to go, as previously, as I wanted to write unit tests for schema migration and rollback, I tried defining an inverse for each migration stage, so that I could trigger a migration and a rollback from a unit test, which resulted in an exception saying that it is not supported to downgrade a VersionedSchema.
I must admit that I solved the original problem by introducing a dummy model property that I will later remove. What would have been the correct approach?
Is it possible to reset SwiftData to a state identical to that of a newly installed app?
I have experienced some migration issues where, when I add a new model, I need to reinstall the entire application for the ModelContainer creation to work.
Deleting all existing models does not seem to make any difference.
A potential solution I currently have, which appears to work but feels quite hacky, is as follows:
let _ = try! ModelContainer()
modelContainer = try! ModelContainer(for: Student.self, ...)
This seems to force out this error CoreData: error: Error: Persistent History (66) has to be truncated due to the following entities being removed: (...) which seems to reset SwiftData.
Any other suggestions?
I have two recordTypes in CloudKit: Author and Book. The Book records have their parent property set to an Author, enabling hierarchical record sharing (i.e., if an Author record is shared, the participant can see all books associated with that author in their shared database).
When syncing with CKSyncEngine, I was expecting handleFetchedRecordZoneChanges to deliver all Author records before their associated Book records. However, unless I’m missing something, the order appears to be random.
This randomness forces me to handle two codepaths in my app (opposed to just one) to replicate CloudKit references in my local persistency storage:
Book arrives before its Author → I store the Book but defer setting its parent reference until the corresponding Author arrives.
Author arrives before its Books → I can immediately set the parent reference when each Book arrives.
Is there a way to ensure that Author records always arrive before Book records when syncing with CKSyncEngine? Or is this behavior inherently unordered and I have to implement two codepaths?