Hi. I'm hoping someone might be able to help us with an issue that's been affecting our standalone watchOS app for some time now.
We've encountered consistent crashes on Apple Watch devices when the app enters the background while the device is offline (i.e., no Bluetooth and no Wi-Fi connection). Through extensive testing, we've isolated the problem to the use of NSPersistentCloudKitContainer. When we switch to NSPersistentContainer, the crashes no longer occur.
Interestingly, this issue only affects our watchOS app. The same CloudKit-based persistence setup works reliably on our iOS and macOS apps, even when offline. This leads us to believe the issue may be specific to how NSPersistentCloudKitContainer behaves on watchOS when the device is disconnected from the network.
We're targeting watchOS 10 and above. We're unsure if this is a misconfiguration on our end or a potential system-level issue, and we would greatly appreciate any insight or guidance.
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
After updating to 15.2 I am seeing frequent crashes in my in-development app related to SwiftData.
For instance, I have a 100% reproducible crash when I make the app lose and regain focus.
There is also a crash that seem to be triggered by a modelContext.save() call in one of my ModelActors.
With both of these crashes, the issue seems to be around keeping SwiftData models up to date. The first item in the stacktrace that is not machinecode is always some getter on a SwiftData collection or object.
In the console, these crashes are accompanied by output along the lines of:
=== AttributeGraph: cycle detected through attribute 820680 ===
precondition failure: setting value during update: 930592
error: the replacement path doesn't exist: "/var/folders/b7/0dw7ztp13fgfxlj19by851tw0000gn/T/swift-generated-sources/@__swiftmacro_10SpaceDebug8TodoListV5todos33_5575DE008494C519BB9FA49C405133E1LL5QueryfMa_.swift"
error: the replacement path doesn't exist: "/var/folders/b7/0dw7ztp13fgfxlj19by851tw0000gn/T/swift-generated-sources/@__swiftmacro_10SpaceDebug8TodoListV5todos33_5575DE008494C519BB9FA49C405133E1LL5QueryfMa_.swift"
Can't show file for stack frame : <DBGLLDBStackFrame: 0x35a57c4e0> - stackNumber:27 - name:TodoList.todos.getter. The file path does not exist on the file system: /var/folders/b7/0dw7ztp13fgfxlj19by851tw0000gn/T/swift-generated-sources/@__swiftmacro_10SpaceDebug8TodoListV5todos33_5575DE008494C519BB9FA49C405133E1LL5QueryfMa_.swiftCan't show file for stack frame : <DBGLLDBStackFrame: 0x35a57c4e0> - stackNumber:27 - name:TodoList.todos.getter. The file path does not exist on the file system: /var/folders/b7/0dw7ztp13fgfxlj19by851tw0000gn/T/swift-generated-sources/@__swiftmacro_10SpaceDebug8TodoListV5todos33_5575DE008494C519BB9FA49C405133E1LL5QueryfMa_.swiftCan't show file for stack frame : <DBGLLDBStackFrame: 0x35a5a82f0> - stackNumber:62 - name:TodoList.todos.getter. The file path does not exist on the file system: /var/folders/b7/0dw7ztp13fgfxlj19by851tw0000gn/T/swift-generated-sources/@__swiftmacro_10SpaceDebug8TodoListV5todos33_5575DE008494C519BB9FA49C405133E1LL5QueryfMa_.swift
Has anyone run into something similar? I'm looking for suggestions on how to debug this.
Cheers,
Bastiaan
If I set my build settings "default actor isolation" to MainActor, how do my @ModelActor actors and model classes need to look like ?
For now, I am creating instances of my @ModelActor actors and passing my modelContext container and processing all data there. Everything stays in this context. No models are transferred back to MainActor.
Now, after changing my project settings, I am getting a huge amount of warnings.
Do I need to set all my model classes to non-isolated and the @ModelActor actor as well?
Is there any new sample code to cover this topic ... did not find anything for now.
Thanks in advance, Marc
As far as I can tell, there’s no equivalent to Core Data’s NSFetchedResultsController in SwiftData. It would be very helpful to have a way to respond to sets of changes in a ModelContext outside of a SwiftUI view. For instance, this is very helpful when using a Model-View-ViewModel architecture.
The @Query property wrapper is great for use in a SwiftUI view, but sometimes it’s helpful to process data outside of the view itself. The fetch() method on ModelContext is helpful for one-time operations, but as far as I can't tell it doesn't address receiving changes on an ongoing basis.
Am I missing some equivalent for this use case?
Also filed as feedback FB12288916
Hello,
When attempting to create a CKShare on a personal device linked to a Family iCloud plan (non-primary account holder), the operation fails with a quotaExceeded error. This occurs with the Family plan having 1.5TB available storage space.
This is also causing a data loss for the object(s) that were attempted to be shared.
Details
Account Type: Family iCloud Plan (2TB total storage)
Current Family Usage: 399GB
iCloud Account Usage: 70 GB
Steps to Reproduce:
Have an iCloud account with storage over the 5GB free space limit.
Be on a part of a iCloud Family Plan as the non-primary account holder.
Have storage space available in the Family Plan
Attempt to start a CloudKit Share/Collaboration on the device.
Observe that the CKShare creation fails with a quotaExceeded error.
Expected Behavior:
The CKShare should be successfully created, reflecting the total available storage of the Family plan.
Observed Behavior:
The CKShare fails to be created with quotaExceeded.
Additional Testing
On a test device using an iCloud account with no stored data, the CKShare was created successfully and shared without issue.
Suspected Cause
The CKShare functionality is verifying the personal storage allocation of the iCloud account and failing without checking total available storage provided by the Family plan.
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?
I have encountered an issue with a customer’s data access after they migrated to a different iCloud account, and I’m looking for guidance.
The Situation:
The customer was logged into their account on my app, which was associated with a specific iCloud account (iCloud A).
They had all their app data available while using iCloud A.
The customer then switched to a new iCloud account (iCloud B) on the same device, while still using the same app account.
After switching iCloud accounts, their data is no longer visible in the app or my CloudKit dashboard.
My Investigation:
I accessed the customer’s CloudKit data via the CloudKit Console, acting as their iCloud account.
I couldn’t find the private database zone or any of their records when accessing iCloud A through the console.
I don’t believe the data was deleted since actions performed under iCloud B shouldn’t affect data stored in iCloud A.
My Hypothesis:
I suspect that the customer’s old iCloud account (iCloud A) may have downgraded or stopped paying for iCloud storage.
If the iCloud subscription is inactive or expired, could that prevent me from accessing their CloudKit data?
Would renewing the iCloud subscription for iCloud A restore access to the missing data?
Questions:
Does an unpaid or expired iCloud account restrict access to CloudKit records, even if they weren’t deleted?
Would paying for iCloud storage again restore the data previously stored in CloudKit?
Is there any way to recover the customer’s CloudKit data if they are unable to access their old iCloud account?
If anyone has a simpler approach to recovering the customer’s iCloud-stored app data or has experience dealing with iCloud migrations like this, I’d appreciate your insights. Thank you in advance for any advice!
I have a CKRecord that references an CKAsset. If I understand it correctly, CKSyncEngine would download the asset every time the record has changed on the server. (Of course it would try to use the local asset cache, but worst-case it might be already flushed)
The documentation for CKAsset says that asset downloads can be prevented by limiting the requested record keys using the desiredKeys property on the fetch operation. But I don't see any possibility to set this property when using CKSyncEngine.
Did I miss something? Are there any alternatives?
I get the following fatal error when the user clicks Save in AddProductionView.
Fatal error: Duplicate keys of type 'AnyHashable' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
As far as I’m aware, SwiftData automatically makes its models conform to Hashable, so this shouldn’t be a problem.
I think it has something to do with the picker, but for the life of me I can’t see what.
This error occurs about 75% of the time when Save is clicked.
I'm using Xcode 16.2 and iPhone SE 2nd Gen. Any help would be greatly appreciated…
Here is my code:
import SwiftUI
import SwiftData
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: Character.self, isAutosaveEnabled: false)
}
}
}
@Model
final class Character {
var name: String
var production: Production
var myCharacter: Bool
init(name: String, production: Production, myCharacter: Bool = false) {
self.name = name
self.production = production
self.myCharacter = myCharacter
}
}
@Model
final class Production {
var name: String
init(name: String) {
self.name = name
}
}
struct ContentView: View {
@State private var showingSheet = false
var body: some View {
Button("Add", systemImage: "plus") {
showingSheet.toggle()
}
.sheet(isPresented: $showingSheet) {
AddProductionView()
}
}
}
struct AddProductionView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) var modelContext
@State var production = Production(name: "")
@Query var characters: [Character]
@State private var characterName: String = ""
@State private var selectedCharacter: Character?
var filteredCharacters: [Character] {
characters.filter { $0.production == production }
}
var body: some View {
NavigationStack {
Form {
Section("Details") {
TextField("Title", text: $production.name)
}
Section("Characters") {
List(filteredCharacters) { character in
Text(character.name)
}
HStack {
TextField("Character", text: $characterName)
Button("Add") {
let newCharacter = Character(name: characterName, production: production)
modelContext.insert(newCharacter)
characterName = ""
}
.disabled(characterName.isEmpty)
}
if !filteredCharacters.isEmpty {
Picker("Select your role", selection: $selectedCharacter) {
Text("Select")
.tag(nil as Character?)
ForEach(filteredCharacters) { character in
Text(character.name)
.tag(character as Character?)
}
}
.pickerStyle(.menu)
}
}
}
.toolbar {
Button("Save") { //Fatal error: Duplicate keys of type 'AnyHashable' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
if let selectedCharacter = selectedCharacter {
selectedCharacter.myCharacter = true
}
modelContext.insert(production)
do {
try modelContext.save()
} catch {
print("Failed to save context: \(error)")
}
dismiss()
}
.disabled(production.name.isEmpty || selectedCharacter == nil)
}
}
}
}
We are trying to solve for the following condition with SwiftData + CloudKit:
Lots of data in CloudKit
Perform "app-reset" to clear data & App settings and start fresh.
Reset data models with try modelContext.delete(model:_) myModel.count() confirms local deletion (0 records); but iCloud Console shows expectedly slow process to delete.
Old CloudKit data is returning during the On Boarding process.
Questions:
• Would making a new iCloud Zone for each reset work around this, as the new zone would be empty? We're having trouble finding details about how to do this with SwiftData.
• Would CKSyncEngine have a benefit over the default SwiftData methods?
Open to hearing if anyone has experienced a similar challenge and how you worked around it!
I am trying out the new AttributedString binding with SwiftUI’s TextEditor in iOS26. I need to save this to a Core Data database. Core Data has no AttributedString type, so I set the type of the field to “Transformable”, give it a custom class of NSAttributedString, and set the transformer to NSSecureUnarchiveFromData
When I try to save, I first convert the Swift AttributedString to NSAttributedString, and then save the context. Unfortunately I get this error when saving the context, and the save isn't persisted:
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x600003721140> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
Here's the code that tries to save the attributed string:
struct AttributedDetailView: View {
@ObservedObject var item: Item
@State private var notesText = AttributedString()
var body: some View {
VStack {
TextEditor(text: $notesText)
.padding()
.onChange(of: notesText) {
item.attributedString = NSAttributedString(notesText)
}
}
.onAppear {
if let nsattributed = item.attributedString {
notesText = AttributedString(nsattributed)
} else {
notesText = ""
}
}
.task {
item.attributedString = NSAttributedString(notesText)
do {
try item.managedObjectContext?.save()
} catch {
print("core data save error = \(error)")
}
}
}
}
This is the attribute setup in the Core Data model editor:
Is there a workaround for this?
I filed FB17943846 if someone can take a look.
Thanks.
I'm using NSPersistentCloudKitContainer to save, edit, and delete items, but it only works half of the time. When I delete an item and terminate the app and repoen, sometimes the item is still there and sometimes it isn't. The operations are simple enough:
moc.delete(thing)
try? moc.save()
Here is my DataController. I'm happy to provide more info as needed
class DataController: ObservableObject {
let container: NSPersistentCloudKitContainer
@Published var moc: NSManagedObjectContext
init() {
container = NSPersistentCloudKitContainer(name: "AppName")
container.loadPersistentStores { description, error in
if let error = error {
print("Core Data failed to load: \(error.localizedDescription)")
}
}
#if DEBUG
do {
try container.initializeCloudKitSchema(options: [])
} catch {
print("Error initializing CloudKit schema: \(error.localizedDescription)")
}
#endif
moc = container.viewContext
}
}
Hi! I use Tips with CloudKit and it works very well, however when a user want to remove their data from CloudKit, how to do that?
In CoreData with CloudKit area, NSPersistentCloudKitContainer have purgeObjectsAndRecordsInZone to delete both local managed objects and CloudKit records, however there is no information about the TipKit deletion.
Does anyone know ideas?
In a CloudKit private database, the Owner creates a custom zone and performs the following actions:
Creates CKRecord1 with CKShare1 and invites Participant1 to it.
Creates CKRecord2 with CKShare2 and invites Participant2 to it.
Creates CKRecordShared, which should be accessible to both Participant1 and Participant2.
How can I achieve step 3?
I observed that:
Setting a regular reference from CKRecord1 (or CKRecord2) to CKRecordShared does not automatically make CKRecordShared accessible to Participant1 (or Participant2).
CKRecordShared can only have one parent, so it cannot be directly linked via parent reference to both Participant1 and Participant2 at the same time.
One potential solution I see is to have the Owner create a separate CKShare for CKRecordShared and share it explicitly with each participant. However, this approach could lead to user errors, as it requires careful management of multiple shares for each participant.
Is there a better way to handle this scenario, ensuring that CKRecordShared is accessible to multiple participants without introducing unnecessary complexity or potential errors?
I'm a first time developer for Swift, (getting on a bit!) but after programming in VB back in the late 90s I wanted to write an app for iPhone. I think I might have gone about it the wrong way, but I've got an app that works great on my iPhone or works great on my iPad. It saves the data persistently on device, but, no matter how much I try, what I read and even resorting to AI (ChatGPT & Gemini) I still can't get it to save the data on iCloud to synchronise between the two and work across the devices. I think it must be something pretty fundamental I'm doing (or more likely not doing) that is causing the issue.
I'm setting up my signing and capabilities as per the available instructions but I always get a fatal error. I think it might be something to do with making fields optional, but at this point I'm second guessing myself and feeling a complete failure. Any advice or pointers would be really gratefully appreciated. I like my app and would like eventually to get it on the App Store but at this point in time I feel it should be on the failed projects heap!
I've even tried a new Xcode project for iOS and asking it to use SwiftData and CloudKit - the default project should work - right? But it absolutely doesn't for me. Please send help!!
My macOS app is developed using SwfitUI, SwiftData, and CloudKit. In the development environment, CloudKit works well. Locally added models can be quickly viewed in the CloudKit Console. macOS app and iOS app with the same BundleID can also synchronize data normally when developing locally. However, in the production environment, the macOS app cannot synchronize data with iCloud. But iOS app can. The models added in the production environment are only saved locally and cannot be viewed in CloudKit Console Production.
I am sure I have configured correctly, container schema changes to deploy to the Production environment. I think there may be a problem with CloudKit in macOS.
Please help troubleshoot the problem. I can provide you with any information you need.
var body: some Scene {
WindowGroup {
MainView()
.frame(minWidth: 640, minHeight: 480)
.environment(mainViewModel)
}
.modelContainer(for: [NoteRecord.self])
}
I didn't do anything special. I didn’t do anything special. I just used SwiftData hosted by CloudKit.
I am attempting to migrate a cloudkit module that calls on manual cloudkit methods for fetching record zone changes, modifying records, etc to one that utilizes CKSyncEngine. I've got a basic implementation working with just a create method for one of my data models, however it seems like the sync engine keeps calling sync events on the same pending changes.
Here is my current flow:
The user will hit some button that lets them fill out a form to create a data model.
The user saves the form. This triggers a method that takes the resulting data model and queues it to the sync engine's state (engine.state.add(pendingRecordZoneChanges: pendingChanges)
I have my delegate method nextRecordZoneChangeBatch(_ context:...) implemented where it fetches the corresponding data model using the record ID and returns a batch containing the corresponding populated record from the data model.
I have the handleEvent(_ event:...) delegate method implemented where I handle both .fetchRecordZoneChanges and .sentRecordZoneChanges. I have set up .sentRecordZoneChanges to merge the server record into my local record (and persisted locally) so that the record change tags are the same.
After this last portion, it seems that the sync engine continues to keep pushing syncs/updates and I end up with numerous handleEvent(_ event:) calls that keep returning savedRecords (and occasionally failedRecordSaves).
Am I missing some step to remove the record from the changes after the sync engine recognizes that I have properly saved the record to the server?
If use a SortDescriptor for a model and sort by some attribute from a relationship, in DEBUG mode it all works fine and sorts. However, in release mode, it is an instant crash.
SortDescriptor(.name, order: .reverse) ---- works
SortDescriptor(.assignedUser?.name, order: .reverse) ---- works in debug but crash in release.
What is the issue here, is it that SwiftData just incompetent to do this?
I'm trying to add Cloud Kit integration to SwiftData app (that is already in the App Store, btw).
When the app is installed on devices that are directly connected to Xcode, it works (a bit slow, but pretty well).
But when the app is distributed to Testflight internal testers, the synchronization doesn't happen at all.
So, is this situation normal and how can I test apps with iCloud integration properly?
SwiftData ModelContainer instances don't seem to have a value for setting the Data Protection class.
Is the best way to set that by setting the Data Protection in the app capabilities? Is that the only way?
I have a need for log data that would be "Complete unless open" and user data that would be "Complete", but how do I change one of the containers data protection class?