iCloud & Data

RSS for tag

Learn how to integrate your app with iCloud and data frameworks for effective data storage

CloudKit Documentation

Posts under iCloud & Data subtopic

Post

Replies

Boosts

Views

Activity

How to figure out sync errors in Production?
I'm using SwiftData with CloudKit private database. I was able to identify the error on my device by debugging in Xcode with com.apple.CoreData.SQLDebug flag. However, in Production, I couldn't find a way to get the cause of errors. I tried inspecting the error coming from eventChangedNotification. The NSPersistentCloudKitContainer.Event error does not contain any underlying error (neither CKError.userInfo nor in NSError.underlyingError). It only reports a partial failure with CKErrorDomain code 2. If a user encounter an error, there seems to be no way to retrieve the error details. Is there any way to access the error details or logs in Production?
1
0
245
Jan ’26
SwiftData Class Inheritance
Hi, I'm considering using the new SwiftData class inheritance for a new app I'm building. I have a few questions: Is it working well enough for production? I have a number of different object types in my app. Some of them are very similar, and there's always a balance to be struck when it comes to splitting them into different types using class inheritance. Are there some good advice on when to use multiple classes instead of squeezing my object types into a single class? Is there advice against using class inheritance in multiple levels (3-4)? Claes
1
0
130
Jul ’25
Default zone is not accessible in shared DB - cloudKit
I am trying to save to cloud kit shared database. The shared database does not allow zones to be set up. How do I save to sharedCloudDatabase without a zone? private func addItem(recordType: String, name: String) { let record = CKRecord(recordType: recordType) record[Constances.field.name] = name as CKRecordValue record[Constances.field.done] = false as CKRecordValue record[Constances.field.priority] = 0 as CKRecordValue CKContainer.default().sharedCloudDatabase.save(record) { [weak self] returnRecord, error in if let error = error { print("Error saving record: \(record[Constances.field.name] as? String ?? "No Name"): \n \(error)") return } } } The following error message prints out: Error saving record: Milk: <CKError 0x15af87900: "Server Rejected Request" (15/2027); server message = "Default zone is not accessible in shared DB"; op = B085F7BA703D4A08; uuid = 87AEFB09-4386-4E43-81D7-971AAE8BA9E0; container ID = "iCloud.com.sfw-consulting.Family-List">
1
0
107
Jun ’25
Unable to sync SwiftData model fully using CloudKit
Hey everyone I just ran into an issue where I couldn't sync the model below fully by using CloudKit, enum LinkMapV3_1: VersionedSchema { static let versionIdentifier: Schema.Version = .init(3, 1, 0) static var models: [any PersistentModel.Type] { [AnnotationData.self, GroupData.self, Item.self, Deployment.self, History.self] } // MARK: - Data @Model class AnnotationData { var name: String = "" var longitude: Double = 0.0 var latitude: Double = 0.0 var order: Int = -1 var level: Int = 1 var detail: String = "" @Relationship(deleteRule: .nullify, inverse: \GroupData.annotation) var groups: [GroupData]? @Relationship(deleteRule: .nullify, inverse: \AnnotationData.to) var from: AnnotationData? var to: AnnotationData? var history: History? } // MARK: - History @Model class History { var id: UUID = UUID() var timestamp: Date = Date() @Relationship(deleteRule: .nullify, inverse: \AnnotationData.history) var annotations: [AnnotationData]? @Relationship(deleteRule: .nullify, inverse: \GroupData.history) var groups: [GroupData]? @Relationship(deleteRule: .nullify, inverse: \Item.history) var items: [Item]? @Relationship(deleteRule: .nullify, inverse: \Deployment.history) var deployment: Deployment? var formattedDate: String { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short return formatter.string(from: timestamp) } var timeAgo: String { let formatter = RelativeDateTimeFormatter() formatter.unitsStyle = .abbreviated return formatter.localizedString(for: timestamp, relativeTo: Date()) } } } So when trying to sync with the code in documentation let modelContainer: ModelContainer init() { let config = ModelConfiguration() typealias vs = LinkMapV3_1 do { #if DEBUG // Use an autorelease pool to make sure Swift deallocates the persistent // container before setting up the SwiftData stack. try autoreleasepool { let desc = NSPersistentStoreDescription(url: config.url) let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.name.Endsunset.LinkMap.SwiftData.v1") desc.cloudKitContainerOptions = opts // Load the store synchronously so it completes before initializing the // CloudKit schema. desc.shouldAddStoreAsynchronously = false if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [vs.AnnotationData.self, vs.GroupData.self, vs.Item.self, vs.Deployment.self, vs.History.self]) { let container = NSPersistentCloudKitContainer(name: "LinkMap", managedObjectModel: mom) container.persistentStoreDescriptions = [desc] container.loadPersistentStores {_, err in if let err { fatalError(err.localizedDescription) } } // Initialize the CloudKit schema after the store finishes loading. try container.initializeCloudKitSchema() // Remove and unload the store from the persistent container. if let store = container.persistentStoreCoordinator.persistentStores.first { try container.persistentStoreCoordinator.remove(store) } } } #endif modelContainer = try ModelContainer(for: vs.AnnotationData.self, vs.GroupData.self, vs.Item.self, vs.Deployment.self, vs.History.self, configurations: config) } catch { fatalError(error.localizedDescription) } } The output is Console Output Where you can see Output Extract Optional arrays with @Relationship are missing, and the entry of record types on cloudkit database container are also missing it. When I attempt to insert an annotation, I got SwiftData/PersistentModel.swift:559: Fatal error: This KeyPath does not appear to relate AnnotationData to anything - \AnnotationData.groups It gets more suspicious when restart the app and try again, the above error end with "AnnotationData.history", and if I tried again the above error end with "AnnotationData.from"... and so on. No matter how my app stop working.
1
0
298
Jan ’26
What xattrs does iCloud maintain?
As of 2025-05-03, when a macOS user enables iCloud Drive synchronization for Desktop & Documents in US region, does iCloud filter xattrs upon upload or later when downloading back to another macOS host? Or is it the case that iCloud has no filtering of third-party xattrs? Where can I find the technical document outlining exactly what iCloud does with xattrs set on macOS host files and folders synchronized with iCloud Drive?
1
0
151
May ’25
SwiftData Background Fetching?
Hi, I am experiencing main thread freezes from fetching on Main Actor. Attempting to move the function to a background thread, but whenever I reference the TestModel in a nonisolated context or in another model actor, I get this warning: Main actor-isolated conformance of 'TestModel' to 'PersistentModel' cannot be used in actor-isolated context; this is an error in the Swift 6 language mode Is there a way to do this correctly? Recreation, warning on line 13: class TestModel { var property: Bool = true init() {} } struct SendableTestModel: Sendable { let property: Bool } @ModelActor actor BackgroundActor { func fetch() throws -> [SendableTestModel] { try modelContext.fetch(FetchDescriptor<TestModel>()).map { SendableTestModel(property: $0.property) } } }
1
0
143
Jul ’25
SwiftData updates in the background are not merged in the main UI context
Hello, SwiftData is not working correctly with Swift Concurrency. And it’s sad after all this time. I personally found a regression. The attached code works perfectly fine on iOS 17.5 but doesn’t work correctly on iOS 18 or iOS 18.1. A model can be updated from the background (Task, Task.detached or ModelActor) and refreshes the UI, but as soon as the same item is updated from the View (fetched via a Query), the next background updates are not reflected anymore in the UI, the UI is not refreshed, the updates are not merged into the main. How to reproduce: Launch the app Tap the plus button in the navigation bar to create a new item Tap on the “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice the time is updated Tap on the “Update from View” (once or many times) Notice the time is updated Tap again on “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice that the time is not update anymore Am I doing something wrong? Or is this a bug in iOS 18/18.1? Many other posts talk about issues where updates from background thread are not merged into the main thread. I don’t know if they all are related but it would be nice to have 1/ bug fixed, meaning that if I update an item from a background, it’s reflected in the UI, and 2/ proper documentation on how to use SwiftData with Swift Concurrency (ModelActor). I don’t know if what I’m doing in my buttons is correct or not. Thanks, Axel import SwiftData import SwiftUI @main struct FB_SwiftData_BackgroundApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Item.self) } } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @State private var simpleModelActor: SimpleModelActor! @Query private var items: [Item] var body: some View { NavigationView { VStack { if let firstItem: Item = items.first { Text(firstItem.timestamp, format: Date.FormatStyle(date: .omitted, time: .standard)) .font(.largeTitle) .fontWeight(.heavy) Button("Update from Task") { let modelContainer: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task { let context: ModelContext = ModelContext(modelContainer) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from Detached Task") { let container: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task.detached { let context: ModelContext = ModelContext(container) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from ModelActor") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Button("Update from ModelActor in State") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await MainActor.run { simpleModelActor = actor } await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Divider() .padding(.vertical) Button("Update from View") { firstItem.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) } .buttonStyle(.bordered) } else { ContentUnavailableView( "No Data", systemImage: "slash.circle", // 􀕧 description: Text("Tap the plus button in the toolbar") ) } } .toolbar { ToolbarItem(placement: .primaryAction) { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } } private func addItem() { modelContext.insert(Item(timestamp: Date.now)) try? modelContext.save() } } @ModelActor final actor SimpleModelActor { var context: String = "" func updateItem(identifier: Item.ID) { guard let item = self[identifier, as: Item.self] else { return } item.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try! modelContext.save() } } @Model final class Item: Identifiable { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
1
1
832
Apr ’25
CloudKit: shared records creatorUserRecordID and lastModifiedUserRecordID
Hi, I am testing a situation with shared CKRecords where the data in the CKRecord syncs fine, but the creatorUserRecordID.recordName and lastModifiedUserRecordID.recordName shows "defaultOwner" (which maps to the CKCurrentUserDefaultName constant) even though I made sure I edit the CKRecord value from a different iCloud account. In fact, on the CloudKit dashboard, it shows the correct user recordIDs in the metadata for the 'Created' and 'Modified' fields, but not in the CKRecord. I am mostly testing this on the iPhone simulator with the debugger attached. Is that a possible reason for this, or is there some other reason the lastModifiedUserRecordID is showing the value for 'CKCurrentUserDefaultName'? It would be pretty difficult to build in functionality to look up changes by a different userID if this is the case.
1
0
206
Jul ’25
defaultIsolation option and Core Data
When creating a new project in Xcode 26, the default for defaultIsolation is MainActor. Core Data creates classes for each entity using code gen, but now those classes are also internally marked as MainActor, which causes issues when accessing managed object from a background thread like this. Is there a way to fix this warning or should Xcode actually mark these auto generated classes as nonisolated to make this better? Filed as FB13840800. nonisolated struct BackgroundDataHandler { @concurrent func saveItem() async throws { let context = await PersistenceController.shared.container.newBackgroundContext() try await context.perform { let newGame = Item(context: context) newGame.timestamp = Date.now // Main actor-isolated property 'timestamp' can not be mutated from a nonisolated context; this is an error in the Swift 6 language mode try context.save() } } } Turning code gen off inside the model and creating it manually, with the nonisolated keyword, gets rid of the warning and still works fine. So I guess the auto generated class could adopt this as well? public import Foundation public import CoreData public typealias ItemCoreDataClassSet = NSSet @objc(Item) nonisolated public class Item: NSManagedObject { }
1
0
118
Jun ’25
macOS SwiftData app never syncs with CloudKit
I'm using SwiftData with CloutKit with a very simple app. Data syncs between iOS, iPadOS, and visionOS, but not macOS. From what I can tell, macOS is never getting CK messages unless I'm running the app from Xcode. I can listen for the CK messages and show a line in a debug overlay. This works perfectly when I run from Xcode. I can see the notifications and see updates in my app. However, if I just launch the app outside of Xcode I will never see any changes or notifications. It is as if the Mac app never even tries to contact CloudKit. Schema has been deployed in the CloudKit console. The app is based on the multi-platform Xcode template. Again, only the macOS version has this issue. Is there some extra permission or setting I need to set up in order to use CloudKit on macOS? @State private var publisher = NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification).receive(on: DispatchQueue.main) .onReceive(publisher) { notification in // Listen for changes in CK events if let userInfo = notification.userInfo, let event = userInfo[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event { let message = "CloudKit Sync: \(event.type.rawValue) - \(event.succeeded ? "Success" : "Failed") - \(event.description)" // Store for UI display syncNotifications.append(message) if syncNotifications.count > 10 { syncNotifications.removeFirst() } } } .overlay(alignment: .topTrailing) { if !syncNotifications.isEmpty { VStack(alignment: .leading) { ForEach(syncNotifications, id: \.self) { notification in Text(notification) .padding(8) } } .frame(width: 800, height: 500) .cornerRadius(8) .background(Color.secondary.opacity(0.2)) .padding() .transition(.move(edge: .top)) } }
1
1
203
May ’25
QuotaExceeded error for RecordDelete operation
In the CloudKit logs I see logs that suggest users getting QUOTA_EXCEEDED error for RecordDelete operations. { "time":"21/07/2025, 7:57:46 UTC" "database":"PRIVATE" "zone":"***" "userId":"***" "operationId":"***" "operationGroupName":"2.3.3(185)" "operationType":"RecordDelete" "platform":"iPhone" "clientOS":"iOS;18.5" "overallStatus":"USER_ERROR" "error":"QUOTA_EXCEEDED" "requestId":"***" "executionTimeMs":"177" "interfaceType":"NATIVE" "recordInsertBytes":54352 "recordInsertCount":40 "returnedRecordTypes":"_pcs_data" } I'm confused as to what this means? Why would a RecordDelete operation have recordInsertBytes? I'd expect a RecordDelete operation to never fail on quotaExceeded and how would I handle that in the app?
1
0
146
Jul ’25
SwiftData CloudKit sync broken on iOS 26
Hi everyone, I’m running into a breaking issue with SwiftData automatic CloudKit syncing on iOS 26, and I'm trying to determine if this is a known regression or a new configuration requirement I missed. The Setup: My setup is extremely standard; I am using the default configuration exactly as described in Apple's documentation here: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices The schema is very simple: A single @Model class. No relationships. The Issue: Prior to iOS 26, this exact app was successfully syncing data between devices and to iCloud without issues. Immediately after the iOS 26 update, syncing stopped completely. I haven't changed any code, but when I check the CloudKit Console, I am seeing some BAD_REQUEST errors during sync attempts. Since I am using the default SwiftData sync (and not manual CKRecord handling), I’m not sure how my client code could be triggering a bad request unless the schema requirements have changed under the hood. Questions: Has anyone else seen increased BAD_REQUEST errors with SwiftData on iOS 26? Are there new entitlements or strict schema requirements introduced in iOS 26 that might cause a previously valid model to be rejected by CloudKit? Any pointers or confirmations would be appreciated. Thanks!
1
2
284
Jan ’26
SwiftData crash when enabling CloudKit for existing users (Free to Pro upgrade)
Hi, I am implementing a premium feature in my app where CloudKit syncing is available only for "Pro" users. The Workflow: Free Users: I initialize the ModelContainer with cloudKitDatabase: .none so their data stays local. Pro Upgrade: When a user purchases a subscription, I restart the container with cloudKitDatabase: .automatic to enable syncing. The Problem: If a user starts as "Free" (creates local data) and later upgrades to "Pro", the app crashes immediately upon launch with the following error: Fatal error: Failed to create ModelContainer: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer, _explanation: nil) It seems that SwiftData fails to load the existing data once the configuration changes to expect a CloudKit-backed store. My Question: Is there a supported way to "toggle" CloudKit on for an existing local dataset without causing this crash? I want the user's existing local data to start syncing once they pay, but currently, it just crashes. My code: import Foundation import SwiftData public enum DataModelEnum: String { case task, calendar public static let container: ModelContainer = { let isSyncEnabled = UserDefaults.isProUser let config = ModelConfiguration( groupContainer: .identifier("group.com.yourcompany.myApp"), cloudKitDatabase: isSyncEnabled ? .automatic : .none ) do { return try ModelContainer(for: TaskModel.self, CalendarModel.self, configurations: config) } catch { fatalError("Failed to create ModelContainer: \(error)") } }() }
1
0
212
Dec ’25
How to diagnose spurious SwiftDataMacros error
I have a Package.swift file that builds and runs from Xcode 15.2 without issue but fails to compile when built from the command line ("swift build"). The swift version is 6.0.3. I'm at wits end trying to diagnose this and would welcome any thoughts. The error in question is error: external macro implementation type 'SwiftDataMacros.PersistentModelMacro' could not be found for macro 'Model()'; plugin for module 'SwiftDataMacros' not found The code associated with the module is very vanilla. import Foundation import SwiftData @Model public final class MyObject { @Attribute(.unique) public var id:Int64 public var vertexID:Int64 public var updatedAt:Date public var codeUSRA:Int32 init(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) { self.id = id self.vertexID = vertexID self.updatedAt = updatedAt self.codeUSRA = codeUSRA } public static func create(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) -> MyObject { MyObject(id: id, vertexID: vertexID, updatedAt: updatedAt, codeUSRA: codeUSRA) } } Thank you.
1
1
345
Apr ’25
Troubleshooting CloudKit JS iCloud Backup: setupAuth() Returns Null After Sign in with Apple
Hi, I'm implementing iCloud backup functionality in my web application using CloudKit JS, but I'm running into some issues. I'd appreciate any help you can provide. Issue: The iCloud backup feature isn't working properly in our web app. I believe I've correctly set up the Apple Developer Program registration and API token generation. While a demo implementation works perfectly with iCloud backup, our app implementation is failing. Specifically: "Sign in with Apple" succeeds However, ck.getDefaultContainer().setupAuth() returns null In the working demo, setupAuth() returns a proper value Even after logging in through the redirect URL provided in the "421 Misdirected Request" error response and executing setupAuth(), it still returns null I've essentially copied the working demo code directly, so I suspect the issue might be related to token generation, permissions, or account configuration. Questions: Could you provide detailed step-by-step instructions for implementing iCloud backup in a web application? I've noticed there are configuration items in the Developer Console and Certificates console, so I may have missed something in one of these areas. Based on the symptoms described, what are the possible causes for setupAuth() returning null in CloudKit JS? Could configuration issues be indirectly causing this, or is it more likely a timing issue or SDK coding problem? Specifically regarding the 421 error and redirect flow - is there something in the configuration that could cause setupAuth() to return null even after successful authentication through the redirect? Thanks in advance for your help!
1
0
98
Jul ’25
How to switch between Core Data Persistent Stores?
What is the best way to switch between Core Data Persistent Stores? My use case is that I have a multi-user app that stores thousands of data items unique to each user. To me, having Persistent Stores for each user seems like the best design to keep their data separate and private. (If anyone believes that storing the data for all users in one Persistent Store is a better design, I'd appreciate hearing from them.) Customers might switch users 5 to 10 times a day. Switching users must be fast, say a second or two at most.
1
0
114
Jun ’25
iCloud Drive Implementation Issue in My App
Hi, I'm having trouble implementing iCloud Drive in my app. I've already taken the obvious steps, including enabling iCloud Documents in Xcode and selecting a container. This container is correctly specified in my code, and in theory, everything should work. The data generated by my app should be saved to iCloud Drive in addition to local storage. The data does get stored in the Files app, but the automatic syncing to iCloud Drive doesn’t work as expected. I’ve also considered updating my .entitlements file. Since I’m at a loss, I’m reaching out for help maybe I’ve overlooked something important that's causing it not to work. If anyone has an idea, please let me know. Thanks in advance!
1
0
175
Aug ’25
Extending @Model with custom macros
I am trying to extend my PersistedModels like so: @Versioned(3) @Model class MyType { var name: String init() { name = "hello" } } but it seems that SwiftData's@Model macro is unable to read the properties added by my @Versioned macro. I have tried changing the order and it ignores them regardless. version is not added to schemaMetadata and version needs to be persisted. I was planning on using this approach to add multiple capabilities to my model types. Is this possible to do with macros? VersionedMacro /// A macro that automatically implements VersionedModel protocol public struct VersionedMacro: MemberMacro, ExtensionMacro { // Member macro to add the stored property directly to the type public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // Add the stored property with the version value return [ "public private(set) var version: Int = \(raw: versionValue)" ] } // Extension macro to add static property public static func expansion( of node: SwiftSyntax.AttributeSyntax, attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, conformingTo protocols: [SwiftSyntax.TypeSyntax], in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [SwiftSyntax.ExtensionDeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // We need to explicitly add the conformance in the extension let ext = try ExtensionDeclSyntax("extension \(type): VersionedModel {}") .with(\.memberBlock.members, MemberBlockItemListSyntax { MemberBlockItemSyntax(decl: DeclSyntax( "public static var version: Int { \(raw: versionValue) }" )) }) return [ext] } } VersionedModel public protocol VersionedModel: PersistentModel { /// The version of this particular instance var version: Int { get } /// The type's current version static var version: Int { get } } Macro Expansion:
1
0
420
Aug ’25
How to figure out sync errors in Production?
I'm using SwiftData with CloudKit private database. I was able to identify the error on my device by debugging in Xcode with com.apple.CoreData.SQLDebug flag. However, in Production, I couldn't find a way to get the cause of errors. I tried inspecting the error coming from eventChangedNotification. The NSPersistentCloudKitContainer.Event error does not contain any underlying error (neither CKError.userInfo nor in NSError.underlyingError). It only reports a partial failure with CKErrorDomain code 2. If a user encounter an error, there seems to be no way to retrieve the error details. Is there any way to access the error details or logs in Production?
Replies
1
Boosts
0
Views
245
Activity
Jan ’26
SwiftData Class Inheritance
Hi, I'm considering using the new SwiftData class inheritance for a new app I'm building. I have a few questions: Is it working well enough for production? I have a number of different object types in my app. Some of them are very similar, and there's always a balance to be struck when it comes to splitting them into different types using class inheritance. Are there some good advice on when to use multiple classes instead of squeezing my object types into a single class? Is there advice against using class inheritance in multiple levels (3-4)? Claes
Replies
1
Boosts
0
Views
130
Activity
Jul ’25
Default zone is not accessible in shared DB - cloudKit
I am trying to save to cloud kit shared database. The shared database does not allow zones to be set up. How do I save to sharedCloudDatabase without a zone? private func addItem(recordType: String, name: String) { let record = CKRecord(recordType: recordType) record[Constances.field.name] = name as CKRecordValue record[Constances.field.done] = false as CKRecordValue record[Constances.field.priority] = 0 as CKRecordValue CKContainer.default().sharedCloudDatabase.save(record) { [weak self] returnRecord, error in if let error = error { print("Error saving record: \(record[Constances.field.name] as? String ?? "No Name"): \n \(error)") return } } } The following error message prints out: Error saving record: Milk: &lt;CKError 0x15af87900: "Server Rejected Request" (15/2027); server message = "Default zone is not accessible in shared DB"; op = B085F7BA703D4A08; uuid = 87AEFB09-4386-4E43-81D7-971AAE8BA9E0; container ID = "iCloud.com.sfw-consulting.Family-List"&gt;
Replies
1
Boosts
0
Views
107
Activity
Jun ’25
Unable to sync SwiftData model fully using CloudKit
Hey everyone I just ran into an issue where I couldn't sync the model below fully by using CloudKit, enum LinkMapV3_1: VersionedSchema { static let versionIdentifier: Schema.Version = .init(3, 1, 0) static var models: [any PersistentModel.Type] { [AnnotationData.self, GroupData.self, Item.self, Deployment.self, History.self] } // MARK: - Data @Model class AnnotationData { var name: String = "" var longitude: Double = 0.0 var latitude: Double = 0.0 var order: Int = -1 var level: Int = 1 var detail: String = "" @Relationship(deleteRule: .nullify, inverse: \GroupData.annotation) var groups: [GroupData]? @Relationship(deleteRule: .nullify, inverse: \AnnotationData.to) var from: AnnotationData? var to: AnnotationData? var history: History? } // MARK: - History @Model class History { var id: UUID = UUID() var timestamp: Date = Date() @Relationship(deleteRule: .nullify, inverse: \AnnotationData.history) var annotations: [AnnotationData]? @Relationship(deleteRule: .nullify, inverse: \GroupData.history) var groups: [GroupData]? @Relationship(deleteRule: .nullify, inverse: \Item.history) var items: [Item]? @Relationship(deleteRule: .nullify, inverse: \Deployment.history) var deployment: Deployment? var formattedDate: String { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short return formatter.string(from: timestamp) } var timeAgo: String { let formatter = RelativeDateTimeFormatter() formatter.unitsStyle = .abbreviated return formatter.localizedString(for: timestamp, relativeTo: Date()) } } } So when trying to sync with the code in documentation let modelContainer: ModelContainer init() { let config = ModelConfiguration() typealias vs = LinkMapV3_1 do { #if DEBUG // Use an autorelease pool to make sure Swift deallocates the persistent // container before setting up the SwiftData stack. try autoreleasepool { let desc = NSPersistentStoreDescription(url: config.url) let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.name.Endsunset.LinkMap.SwiftData.v1") desc.cloudKitContainerOptions = opts // Load the store synchronously so it completes before initializing the // CloudKit schema. desc.shouldAddStoreAsynchronously = false if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [vs.AnnotationData.self, vs.GroupData.self, vs.Item.self, vs.Deployment.self, vs.History.self]) { let container = NSPersistentCloudKitContainer(name: "LinkMap", managedObjectModel: mom) container.persistentStoreDescriptions = [desc] container.loadPersistentStores {_, err in if let err { fatalError(err.localizedDescription) } } // Initialize the CloudKit schema after the store finishes loading. try container.initializeCloudKitSchema() // Remove and unload the store from the persistent container. if let store = container.persistentStoreCoordinator.persistentStores.first { try container.persistentStoreCoordinator.remove(store) } } } #endif modelContainer = try ModelContainer(for: vs.AnnotationData.self, vs.GroupData.self, vs.Item.self, vs.Deployment.self, vs.History.self, configurations: config) } catch { fatalError(error.localizedDescription) } } The output is Console Output Where you can see Output Extract Optional arrays with @Relationship are missing, and the entry of record types on cloudkit database container are also missing it. When I attempt to insert an annotation, I got SwiftData/PersistentModel.swift:559: Fatal error: This KeyPath does not appear to relate AnnotationData to anything - \AnnotationData.groups It gets more suspicious when restart the app and try again, the above error end with "AnnotationData.history", and if I tried again the above error end with "AnnotationData.from"... and so on. No matter how my app stop working.
Replies
1
Boosts
0
Views
298
Activity
Jan ’26
Swift Data initiate
I am working with SwiftData and get the below error. I can't find any documentation on it to see what to fix. Any help would be appreciated. Fatal error: This relationship already has a value but it's not the target:
Replies
1
Boosts
0
Views
106
Activity
Apr ’25
What xattrs does iCloud maintain?
As of 2025-05-03, when a macOS user enables iCloud Drive synchronization for Desktop &amp; Documents in US region, does iCloud filter xattrs upon upload or later when downloading back to another macOS host? Or is it the case that iCloud has no filtering of third-party xattrs? Where can I find the technical document outlining exactly what iCloud does with xattrs set on macOS host files and folders synchronized with iCloud Drive?
Replies
1
Boosts
0
Views
151
Activity
May ’25
SwiftData Background Fetching?
Hi, I am experiencing main thread freezes from fetching on Main Actor. Attempting to move the function to a background thread, but whenever I reference the TestModel in a nonisolated context or in another model actor, I get this warning: Main actor-isolated conformance of 'TestModel' to 'PersistentModel' cannot be used in actor-isolated context; this is an error in the Swift 6 language mode Is there a way to do this correctly? Recreation, warning on line 13: class TestModel { var property: Bool = true init() {} } struct SendableTestModel: Sendable { let property: Bool } @ModelActor actor BackgroundActor { func fetch() throws -> [SendableTestModel] { try modelContext.fetch(FetchDescriptor<TestModel>()).map { SendableTestModel(property: $0.property) } } }
Replies
1
Boosts
0
Views
143
Activity
Jul ’25
I have a problem with an entity in the core data
When I try to use an entity created in a CoreData, it gives me: 'PlayerData' is ambiguous for type lookup in this context
Replies
1
Boosts
0
Views
95
Activity
Jun ’25
SwiftData updates in the background are not merged in the main UI context
Hello, SwiftData is not working correctly with Swift Concurrency. And it’s sad after all this time. I personally found a regression. The attached code works perfectly fine on iOS 17.5 but doesn’t work correctly on iOS 18 or iOS 18.1. A model can be updated from the background (Task, Task.detached or ModelActor) and refreshes the UI, but as soon as the same item is updated from the View (fetched via a Query), the next background updates are not reflected anymore in the UI, the UI is not refreshed, the updates are not merged into the main. How to reproduce: Launch the app Tap the plus button in the navigation bar to create a new item Tap on the “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice the time is updated Tap on the “Update from View” (once or many times) Notice the time is updated Tap again on “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice that the time is not update anymore Am I doing something wrong? Or is this a bug in iOS 18/18.1? Many other posts talk about issues where updates from background thread are not merged into the main thread. I don’t know if they all are related but it would be nice to have 1/ bug fixed, meaning that if I update an item from a background, it’s reflected in the UI, and 2/ proper documentation on how to use SwiftData with Swift Concurrency (ModelActor). I don’t know if what I’m doing in my buttons is correct or not. Thanks, Axel import SwiftData import SwiftUI @main struct FB_SwiftData_BackgroundApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Item.self) } } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @State private var simpleModelActor: SimpleModelActor! @Query private var items: [Item] var body: some View { NavigationView { VStack { if let firstItem: Item = items.first { Text(firstItem.timestamp, format: Date.FormatStyle(date: .omitted, time: .standard)) .font(.largeTitle) .fontWeight(.heavy) Button("Update from Task") { let modelContainer: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task { let context: ModelContext = ModelContext(modelContainer) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from Detached Task") { let container: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task.detached { let context: ModelContext = ModelContext(container) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from ModelActor") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Button("Update from ModelActor in State") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await MainActor.run { simpleModelActor = actor } await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Divider() .padding(.vertical) Button("Update from View") { firstItem.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) } .buttonStyle(.bordered) } else { ContentUnavailableView( "No Data", systemImage: "slash.circle", // 􀕧 description: Text("Tap the plus button in the toolbar") ) } } .toolbar { ToolbarItem(placement: .primaryAction) { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } } private func addItem() { modelContext.insert(Item(timestamp: Date.now)) try? modelContext.save() } } @ModelActor final actor SimpleModelActor { var context: String = "" func updateItem(identifier: Item.ID) { guard let item = self[identifier, as: Item.self] else { return } item.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try! modelContext.save() } } @Model final class Item: Identifiable { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
Replies
1
Boosts
1
Views
832
Activity
Apr ’25
CloudKit: shared records creatorUserRecordID and lastModifiedUserRecordID
Hi, I am testing a situation with shared CKRecords where the data in the CKRecord syncs fine, but the creatorUserRecordID.recordName and lastModifiedUserRecordID.recordName shows "defaultOwner" (which maps to the CKCurrentUserDefaultName constant) even though I made sure I edit the CKRecord value from a different iCloud account. In fact, on the CloudKit dashboard, it shows the correct user recordIDs in the metadata for the 'Created' and 'Modified' fields, but not in the CKRecord. I am mostly testing this on the iPhone simulator with the debugger attached. Is that a possible reason for this, or is there some other reason the lastModifiedUserRecordID is showing the value for 'CKCurrentUserDefaultName'? It would be pretty difficult to build in functionality to look up changes by a different userID if this is the case.
Replies
1
Boosts
0
Views
206
Activity
Jul ’25
defaultIsolation option and Core Data
When creating a new project in Xcode 26, the default for defaultIsolation is MainActor. Core Data creates classes for each entity using code gen, but now those classes are also internally marked as MainActor, which causes issues when accessing managed object from a background thread like this. Is there a way to fix this warning or should Xcode actually mark these auto generated classes as nonisolated to make this better? Filed as FB13840800. nonisolated struct BackgroundDataHandler { @concurrent func saveItem() async throws { let context = await PersistenceController.shared.container.newBackgroundContext() try await context.perform { let newGame = Item(context: context) newGame.timestamp = Date.now // Main actor-isolated property 'timestamp' can not be mutated from a nonisolated context; this is an error in the Swift 6 language mode try context.save() } } } Turning code gen off inside the model and creating it manually, with the nonisolated keyword, gets rid of the warning and still works fine. So I guess the auto generated class could adopt this as well? public import Foundation public import CoreData public typealias ItemCoreDataClassSet = NSSet @objc(Item) nonisolated public class Item: NSManagedObject { }
Replies
1
Boosts
0
Views
118
Activity
Jun ’25
macOS SwiftData app never syncs with CloudKit
I'm using SwiftData with CloutKit with a very simple app. Data syncs between iOS, iPadOS, and visionOS, but not macOS. From what I can tell, macOS is never getting CK messages unless I'm running the app from Xcode. I can listen for the CK messages and show a line in a debug overlay. This works perfectly when I run from Xcode. I can see the notifications and see updates in my app. However, if I just launch the app outside of Xcode I will never see any changes or notifications. It is as if the Mac app never even tries to contact CloudKit. Schema has been deployed in the CloudKit console. The app is based on the multi-platform Xcode template. Again, only the macOS version has this issue. Is there some extra permission or setting I need to set up in order to use CloudKit on macOS? @State private var publisher = NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification).receive(on: DispatchQueue.main) .onReceive(publisher) { notification in // Listen for changes in CK events if let userInfo = notification.userInfo, let event = userInfo[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event { let message = "CloudKit Sync: \(event.type.rawValue) - \(event.succeeded ? "Success" : "Failed") - \(event.description)" // Store for UI display syncNotifications.append(message) if syncNotifications.count > 10 { syncNotifications.removeFirst() } } } .overlay(alignment: .topTrailing) { if !syncNotifications.isEmpty { VStack(alignment: .leading) { ForEach(syncNotifications, id: \.self) { notification in Text(notification) .padding(8) } } .frame(width: 800, height: 500) .cornerRadius(8) .background(Color.secondary.opacity(0.2)) .padding() .transition(.move(edge: .top)) } }
Replies
1
Boosts
1
Views
203
Activity
May ’25
QuotaExceeded error for RecordDelete operation
In the CloudKit logs I see logs that suggest users getting QUOTA_EXCEEDED error for RecordDelete operations. { "time":"21/07/2025, 7:57:46 UTC" "database":"PRIVATE" "zone":"***" "userId":"***" "operationId":"***" "operationGroupName":"2.3.3(185)" "operationType":"RecordDelete" "platform":"iPhone" "clientOS":"iOS;18.5" "overallStatus":"USER_ERROR" "error":"QUOTA_EXCEEDED" "requestId":"***" "executionTimeMs":"177" "interfaceType":"NATIVE" "recordInsertBytes":54352 "recordInsertCount":40 "returnedRecordTypes":"_pcs_data" } I'm confused as to what this means? Why would a RecordDelete operation have recordInsertBytes? I'd expect a RecordDelete operation to never fail on quotaExceeded and how would I handle that in the app?
Replies
1
Boosts
0
Views
146
Activity
Jul ’25
SwiftData CloudKit sync broken on iOS 26
Hi everyone, I’m running into a breaking issue with SwiftData automatic CloudKit syncing on iOS 26, and I'm trying to determine if this is a known regression or a new configuration requirement I missed. The Setup: My setup is extremely standard; I am using the default configuration exactly as described in Apple's documentation here: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices The schema is very simple: A single @Model class. No relationships. The Issue: Prior to iOS 26, this exact app was successfully syncing data between devices and to iCloud without issues. Immediately after the iOS 26 update, syncing stopped completely. I haven't changed any code, but when I check the CloudKit Console, I am seeing some BAD_REQUEST errors during sync attempts. Since I am using the default SwiftData sync (and not manual CKRecord handling), I’m not sure how my client code could be triggering a bad request unless the schema requirements have changed under the hood. Questions: Has anyone else seen increased BAD_REQUEST errors with SwiftData on iOS 26? Are there new entitlements or strict schema requirements introduced in iOS 26 that might cause a previously valid model to be rejected by CloudKit? Any pointers or confirmations would be appreciated. Thanks!
Replies
1
Boosts
2
Views
284
Activity
Jan ’26
SwiftData crash when enabling CloudKit for existing users (Free to Pro upgrade)
Hi, I am implementing a premium feature in my app where CloudKit syncing is available only for "Pro" users. The Workflow: Free Users: I initialize the ModelContainer with cloudKitDatabase: .none so their data stays local. Pro Upgrade: When a user purchases a subscription, I restart the container with cloudKitDatabase: .automatic to enable syncing. The Problem: If a user starts as "Free" (creates local data) and later upgrades to "Pro", the app crashes immediately upon launch with the following error: Fatal error: Failed to create ModelContainer: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer, _explanation: nil) It seems that SwiftData fails to load the existing data once the configuration changes to expect a CloudKit-backed store. My Question: Is there a supported way to "toggle" CloudKit on for an existing local dataset without causing this crash? I want the user's existing local data to start syncing once they pay, but currently, it just crashes. My code: import Foundation import SwiftData public enum DataModelEnum: String { case task, calendar public static let container: ModelContainer = { let isSyncEnabled = UserDefaults.isProUser let config = ModelConfiguration( groupContainer: .identifier("group.com.yourcompany.myApp"), cloudKitDatabase: isSyncEnabled ? .automatic : .none ) do { return try ModelContainer(for: TaskModel.self, CalendarModel.self, configurations: config) } catch { fatalError("Failed to create ModelContainer: \(error)") } }() }
Replies
1
Boosts
0
Views
212
Activity
Dec ’25
How to diagnose spurious SwiftDataMacros error
I have a Package.swift file that builds and runs from Xcode 15.2 without issue but fails to compile when built from the command line ("swift build"). The swift version is 6.0.3. I'm at wits end trying to diagnose this and would welcome any thoughts. The error in question is error: external macro implementation type 'SwiftDataMacros.PersistentModelMacro' could not be found for macro 'Model()'; plugin for module 'SwiftDataMacros' not found The code associated with the module is very vanilla. import Foundation import SwiftData @Model public final class MyObject { @Attribute(.unique) public var id:Int64 public var vertexID:Int64 public var updatedAt:Date public var codeUSRA:Int32 init(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) { self.id = id self.vertexID = vertexID self.updatedAt = updatedAt self.codeUSRA = codeUSRA } public static func create(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) -> MyObject { MyObject(id: id, vertexID: vertexID, updatedAt: updatedAt, codeUSRA: codeUSRA) } } Thank you.
Replies
1
Boosts
1
Views
345
Activity
Apr ’25
Troubleshooting CloudKit JS iCloud Backup: setupAuth() Returns Null After Sign in with Apple
Hi, I'm implementing iCloud backup functionality in my web application using CloudKit JS, but I'm running into some issues. I'd appreciate any help you can provide. Issue: The iCloud backup feature isn't working properly in our web app. I believe I've correctly set up the Apple Developer Program registration and API token generation. While a demo implementation works perfectly with iCloud backup, our app implementation is failing. Specifically: "Sign in with Apple" succeeds However, ck.getDefaultContainer().setupAuth() returns null In the working demo, setupAuth() returns a proper value Even after logging in through the redirect URL provided in the "421 Misdirected Request" error response and executing setupAuth(), it still returns null I've essentially copied the working demo code directly, so I suspect the issue might be related to token generation, permissions, or account configuration. Questions: Could you provide detailed step-by-step instructions for implementing iCloud backup in a web application? I've noticed there are configuration items in the Developer Console and Certificates console, so I may have missed something in one of these areas. Based on the symptoms described, what are the possible causes for setupAuth() returning null in CloudKit JS? Could configuration issues be indirectly causing this, or is it more likely a timing issue or SDK coding problem? Specifically regarding the 421 error and redirect flow - is there something in the configuration that could cause setupAuth() to return null even after successful authentication through the redirect? Thanks in advance for your help!
Replies
1
Boosts
0
Views
98
Activity
Jul ’25
How to switch between Core Data Persistent Stores?
What is the best way to switch between Core Data Persistent Stores? My use case is that I have a multi-user app that stores thousands of data items unique to each user. To me, having Persistent Stores for each user seems like the best design to keep their data separate and private. (If anyone believes that storing the data for all users in one Persistent Store is a better design, I'd appreciate hearing from them.) Customers might switch users 5 to 10 times a day. Switching users must be fast, say a second or two at most.
Replies
1
Boosts
0
Views
114
Activity
Jun ’25
iCloud Drive Implementation Issue in My App
Hi, I'm having trouble implementing iCloud Drive in my app. I've already taken the obvious steps, including enabling iCloud Documents in Xcode and selecting a container. This container is correctly specified in my code, and in theory, everything should work. The data generated by my app should be saved to iCloud Drive in addition to local storage. The data does get stored in the Files app, but the automatic syncing to iCloud Drive doesn’t work as expected. I’ve also considered updating my .entitlements file. Since I’m at a loss, I’m reaching out for help maybe I’ve overlooked something important that's causing it not to work. If anyone has an idea, please let me know. Thanks in advance!
Replies
1
Boosts
0
Views
175
Activity
Aug ’25
Extending @Model with custom macros
I am trying to extend my PersistedModels like so: @Versioned(3) @Model class MyType { var name: String init() { name = "hello" } } but it seems that SwiftData's@Model macro is unable to read the properties added by my @Versioned macro. I have tried changing the order and it ignores them regardless. version is not added to schemaMetadata and version needs to be persisted. I was planning on using this approach to add multiple capabilities to my model types. Is this possible to do with macros? VersionedMacro /// A macro that automatically implements VersionedModel protocol public struct VersionedMacro: MemberMacro, ExtensionMacro { // Member macro to add the stored property directly to the type public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // Add the stored property with the version value return [ "public private(set) var version: Int = \(raw: versionValue)" ] } // Extension macro to add static property public static func expansion( of node: SwiftSyntax.AttributeSyntax, attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, conformingTo protocols: [SwiftSyntax.TypeSyntax], in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [SwiftSyntax.ExtensionDeclSyntax] { guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self), let firstArgument = argumentList.first?.expression else { throw MacroExpansionErrorMessage("@Versioned requires a version number, e.g. @Versioned(3)") } let versionValue = firstArgument.description.trimmingCharacters(in: .whitespaces) // We need to explicitly add the conformance in the extension let ext = try ExtensionDeclSyntax("extension \(type): VersionedModel {}") .with(\.memberBlock.members, MemberBlockItemListSyntax { MemberBlockItemSyntax(decl: DeclSyntax( "public static var version: Int { \(raw: versionValue) }" )) }) return [ext] } } VersionedModel public protocol VersionedModel: PersistentModel { /// The version of this particular instance var version: Int { get } /// The type's current version static var version: Int { get } } Macro Expansion:
Replies
1
Boosts
0
Views
420
Activity
Aug ’25