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

Persist app state across reinstalls/multiple devices
So I’m trying to setup an existing app to work with iCloud syncing. The syncing part seems to be working for the most part. When the app is first installed it sets up some data locally. Throughout the life of the app additional data is added through updates. There is a user default setup that stores the current data version, then compares it with the new version. If it’s newer, then loads the additional data. The issue I’ve got is a user can delete the app and reinstall, or install on another device which has that data version as 0, prompting another import even though the data in the cloud is current version, resulting in duplicate data once the sync is done. How can I persist that version data? I’ve seen NSUbiquitousKeyValueStore which seems to be a cloud based version of user defaults, but it says not to rely on it if it’s critical to app functions
0
0
309
Oct ’24
Using SwiftData with a local and CloudKit backed configuration at the same time
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?
0
0
194
1w
Ongoing Issues with ModelActor in SwiftData?
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?
1
0
504
Dec ’24
Error accessing backing data on deleted item in detached task
I have been working on an app for the past few months, and one issue that I have encountered a few times is an error where quick subsequent deletions cause issues with detached tasks that are triggered from some user actions. Inside a Task.detached, I am building an isolated model context, querying for LineItems, then iterating over those items. The crash happens when accessing a Transaction property through a relationship. var byTransactionId: [UUID: [LineItem]] { return Dictionary(grouping: self) { item in item.transaction?.id ?? UUID() } } In this case, the transaction has been deleted, but the relationship existed when the fetch occurred, so the transaction value is non-nil. The crash occurs when accessing the id. This is the error. SwiftData/BackingData.swift:1035: Fatal error: This model instance was invalidated because its backing data could no longer be found the store. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb43fea2c4bc3b3f5 &lt;x-coredata://A9EFB8E3-CB47-48B2-A7C4-6EEA25D27E2E/Transaction/p1756&gt;))) I see other posts about this error and am exploring some suggestions, but if anyone has any thoughts, they would be appreciated.
0
0
90
5d
CloudKit console fails to query indexed records in Production
"No records found" If I create a new record on the console, I can copy the record name. I can then query for recordName and get that individual record back. BUT no other queries work. I cannot query all records. I cannot query by individual property. Just returns "no records found" Seems like my indexes got messed up. Is there a way to reset indexes on prod? This is on a coredata.cloudkit managed zone.
1
0
73
4w
Why is CKModifyRecordsOperation to batch delete records in CloudKit not deleting records?
My Code: let op = CKModifyRecordsOperation(recordIDsToDelete:recordIDsToDelete) op.modifyRecordsCompletionBlock = { _, deleteRecordIDs, error in if error == nil { print("successful delete deleteRecordIDS = \(deleteRecordIDs)") } else { print("delete error = \(error?.localizedDescription)") } } op.database = CKContainer.default().privateCloudDatabase op.qualityOfService = .userInitiated CKContainer.default().privateCloudDatabase.add(op) My problem is that CKRecord are not deleted once I reinstall the app: when I reinstall the app and try to delete a CloudKit record, the method is executed successfully (error is nil) but the records are still in CloudKit Dashboards.
2
0
186
3w
How are items in CKSyncEngine.State.pendingDatabaseChanges removed after they haven been saved to cloud?
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.
0
0
342
Nov ’24
Document based SwiftData apps do not autosave
Document based SwiftData apps do not autosave changes to the ModelContext at all. This issue has been around since the first release of this SwiftData feature. In fact, the Apple WWDC sample project (https://developer.apple.com/documentation/swiftui/building-a-document-based-app-using-swiftdata) does not persist any data in its current state, unless one inserts modelContext.save() calls after every data change. I have reported this under the feedback ID FB16503154, as it seemed to me that there is no feedback report about the fundamental issue yet. Other posts related to this problem: https://forums.developer.apple.com/forums/thread/757172 https://forums.developer.apple.com/forums/thread/768906 https://developer.apple.com/forums/thread/764189
0
0
290
Feb ’25
iCloudKit Unable to Deploy Container to Production Environment
When attempting to deploy schema changes in the iCloudKit Database by clicking the Deploy Schema Changes button, a Confirm Deployment dialog appears, showing an error: “Internal error”. The following error details were observed in the JavaScript console: • description: “The request has failed due to an error.” • headers: undefined • message: “Known response error: The request has failed due to an error.” • result: • code: 400 • detailedMessage: undefined • message: “bad-request” • reason: “Internal error” • redirectUrl: undefined • requestUuid: “0c5b4af2-15c9-425f-87ea-************” • retryAfterSeconds: undefined
2
0
915
Dec ’24
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
97
Aug ’25
Safari App Extension fails to connect to CloudKit daemon (cloudd) with XPC communication errors -- CKErrorDomain Code=6 / NSCocoaErrorDomain Code=4099 – Unable to connect to CloudKit daemon
I'm working on a macOS app with a Safari web extension. I'm trying to share a SwiftData model between devices using CloudKit synchronization. I am able to get synchronization in the main app on the same device, CloudKit sync works correctly — changes appear in the CloudKit Dashboard under com.apple.coredata.cloudkit.zone. However, in the Safari App Extension, data is saved locally and persists across launches, but never syncs to CloudKit. I have followed the recommended practices for configuring the App Group and entitlements, but the issue persists. Questions: Is there an official limitation preventing Safari App Extensions from connecting to the CloudKit daemon (cloudd)? If not, what entitlements or configuration changes are required for a Safari App Extension to successfully sync with CloudKit? Is the xpc_error=159 from bootstrap_look_up() a known sandbox restriction for this extension type? Any guidance from Apple engineers or others who have successfully used CloudKit from a Safari App Extension would be appreciated. What I’ve confirmed: The extension’s .entitlements includes: com.apple.security.app-sandbox com.apple.developer.icloud-services CloudKit com.apple.developer.icloud-container-identifiers iCloud.dev.example.myapp Same iCloud container ID for both app and extension CloudKit container exists and is initialized in CloudKit Console Running in :Sandbox environment during development Database name in SwiftData matches container identifier (without the iCloud. prefix) The extension’s codesign output shows correct entitlements App Group is configured (although in this case, extension and app use separate stores intentionally) Observed behavior in Console.app logs: CloudKit sync engine initializes in the extension XPC activities are registered for import/export: _xpc_activity_register: com.apple.coredata.cloudkit.activity.export. xpc_activity_set_criteria: ... import. Then a bootstrap lookup fails: failed to do a bootstrap look-up: xpc_error=[159: Unknown error: 159] CloudKit daemon connection error: CKErrorDomain Code=6 "Error connecting to CloudKit daemon" NSCocoaErrorDomain Code=4099 There is no “Will attempt to upload transactions” or “Upload succeeded” logs are ever seen. Symptoms When the extension is run, I see logs like the following in Console.app: [0x13e215820] failed to do a bootstrap look-up: xpc_error=[159: Unknown error: 159] CoreData+CloudKit: -[PFCloudKitSetupAssistant _checkAccountStatus:]_block_invoke(342): Fetched account info for store : (null) Error Domain=CKErrorDomain Code=6 "Error connecting to CloudKit daemon. This could happen for many reasons..."
2
0
70
Aug ’25
SwiftData SortDescriptor Limitation...
I built a SwiftData App that relies on CloudKit to synchronize data across devices. That means all model relationships must be expressed as Optional. That’s fine, but there is a limitation in using Optional’s in SwiftData SortDescriptors (Crashes App) That means I can’t apply a SortDescriptor to ModelA using some property value in ModelB (even if ModelB must exist) I tried using a computed property in ModelA that referred to the property in ModelB, BUT THIS DOESN”T WORK EITHER! Am I stuck storing redundant data In ModelA just to sort ModelA as I would like???
4
0
148
Aug ’25
CloudKit sign in error in normal tab
Hi, I'm trying to sign in with Apple CloudKit. I'm using the following code: 'use client'; import { CLOUDKIT_CONSTANTS } from '@/constants/cloudkit'; import { setCloudKitConfigured } from '@/lib/cloudkitSingleton'; import { CloudKitStatic } from '@/types/cloudkit'; import Script from 'next/script'; declare global { interface Window { CloudKit: CloudKitStatic; } } export default function Home() { const initializeCloudKit = async () =&gt; { console.info('⭐️ initializeCloudKit - start'); // 古い認証情報を削除 try { // LocalStorageから古い認証情報を削除 const keysToRemove = []; for (let i = 0; i &lt; localStorage.length; i++) { const key = localStorage.key(i); if (key &amp;&amp; (key.includes('cloudkit') || key.includes('CloudKit'))) { keysToRemove.push(key); } } keysToRemove.forEach(key =&gt; localStorage.removeItem(key)); // SessionStorageからも削除 const sessionKeysToRemove = []; for (let i = 0; i &lt; sessionStorage.length; i++) { const key = sessionStorage.key(i); if (key &amp;&amp; (key.includes('cloudkit') || key.includes('CloudKit'))) { sessionKeysToRemove.push(key); } } sessionKeysToRemove.forEach(key =&gt; sessionStorage.removeItem(key)); console.log('古い認証情報を削除しました'); } catch (cleanupError) { console.warn('認証情報のクリーンアップ中にエラー:', cleanupError); } try { const cloudKit = window.CloudKit.configure({ containers: [ { containerIdentifier: 'XXXXXX', apiTokenAuth: { apiToken: 'XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX', persist: false, signInButton: { id: 'cloudkit-sign-in-button', theme: 'black', }, signOutButton: { id: 'cloudkit-sign-out-button', theme: 'black', }, }, environment: 'development', }, ], }); console.info('⭐️ cloudKit', cloudKit); setCloudKitConfigured(true); const container = cloudKit.getDefaultContainer(); console.info('⭐️ CloudKit configured, setting up auth...'); // 初期認証状態をチェック try { const initialUser = await container.setUpAuth(); console.info('⭐️ setUpAuth result:', initialUser); } catch (authError) { console.info('⭐️ setUpAuth error (expected for unauthenticated):', authError); } // CloudKitの標準コールバックも併用(念のため) try { container.whenUserSignsIn().then((userInfo: any) =&gt; { console.info('⭐️ CALLBACK: whenUserSignsIn fired!', userInfo); }); container.whenUserSignsOut().then(() =&gt; { console.info('⭐️ CALLBACK: whenUserSignsOut fired!'); }); } catch (callbackError) { console.info('⭐️ Callback setup error (non-critical):', callbackError); } console.info('⭐️ initializeCloudKit - completed'); } catch (error) { console.error('⭐️ Critical CloudKit initialization error:', error); } }; return ( &lt;&gt; &lt;Script src="https://cdn.apple-cloudkit.com/ck/2/cloudkit.js" strategy="afterInteractive" onLoad={() =&gt; { initializeCloudKit(); }} onError={error =&gt; { console.error('⭐️ CloudKit initialization error:', error); }} /&gt; &lt;div id="cloudkit-sign-in-button" /&gt; &lt;div id="cloudkit-sign-out-button" /&gt; &lt;/&gt; ); } In Chrome secret tab, I can sign in successfully. But in Chrome normal tab, I can't sign in. In normal tab, following error occurs on sign in button click: cloudkit.js:14 Uncaught (in promise) Error: UNKNOWN_ERROR cloudkit.js:14 GET https://api.apple-cloudkit.com/database/1/XXXXXX/XXXXXX/public/users/caller?ckjsBuildVersion=2420ProjectDev22&amp;ckjsVersion=2.6.4&amp;clientId=XXXXX-XXXXXXX-XXXX-XXXXX&amp; ckAPIToken=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX 421 (Misdirected Request) I think, cloudkit instance has re-initialized when I click the sign in button only in normal tab. So I can't sign in. Do you have any idea what might be causing the error ? Thanks in advance for your help!
0
0
86
Aug ’25
Can't deploy CloudKit schema because of empty record? Why?
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?
1
0
583
Feb ’25
Consequences of incorrect VersionedSchema.versionIdentifier
About 4 months ago, I shipped the first version of my app with 4 versioned schemas that, unintentionally, had the same versionIdentifier of 1.2.0 in 2 of them: V1: 1.0.0 V2: 1.1.0 V3: 1.2.0 V4: 1.2.0 They are ordered correctly in the MigrationPlan, and they are all lightweight. Migration works, SwiftData doesn't crash on init and I haven't encountered any issues related to this. The app syncs with iCloud. Questions, preferable for anybody with knowledge of SwiftData internals: What will break in SwiftData when there are 2 duplicate numbers? Not that I would expect it to be safe, but does it happen to be safe to ship an update that changes V4's version to 1.3.0, what was originally intended?
0
0
135
Jul ’25
What is the best SwiftData approach to replicate NSManagedObject's willSave?
When using Core Data I would override willSave on NSManagedObject to compute alastModified value on a model object. This allowed one simple method to check changed values and set a date if necessary. It is possible set lastModified in SwiftData, but the approaches I have found all have drawbacks when compared to the previous approach. Hide saved model properties behind transient versions private var textSaved: String = "" var text: String { get { textSaved } set { textSaved = newValue lastModified = .now } } I could hide every property that should update the lastModified behind a computed value, but this requires additional code for each new property and obfuscates the model definition. Update all properties through an update function func update<T>(keyPath: ReferenceWritableKeyPath<Player, T>, to value: T) Paul Hudson notes a workaround where any changes are made to the model through an update function that takes a keyPath. This will add complexity to every view that wants to modify model properties, and also leaves those properties open to change through other approaches. Use ModelContext.willSave ModelContext sends a notification when it is about to save. This could be caught in .onReceive in a view or perhaps in some model-holding singleton, then ALL changes queried and dealt with accordingly. Perhaps the best approach here would to add willSave to all model objects so code external to the model isn't doing the lastModified logic. This last solution feels like the best way forward that I know (ideally avoiding any .onReceive code in views). Should I prefer another solution or are there better ones I have missed?
1
0
430
Oct ’24
NSCocoaErrorDomain Code=513 after user delete's
I work on an app that saves data to the Documents folder in the users iCloud Drive. This uses the iCloud -> iCloud Documents capability with a standard container. We've noticed an issue where a user will delete the apps data by doing to Settings > {Name} > iCloud > Storage > App Name > select "delete data from iCloud", and then our app can no longer write to or create the Documents folder. Once that happens, we get this error: Error Domain=NSCocoaErrorDomain Code=513 "You don't have permission to save the file "Documents" in the folder "iCloud~your~bundle~identifier"." UserInfo={NSFilePath=/private/var/mobile/Library/Mobile Documents/iCloud~your~bundle~identifier/Documents, NSURL=file:///private/var/mobile/Library/Mobile%20Documents/iCloud~your~bundle~identifier/Documents, NSUnderlyingError=0x1102c7ea0 {Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"}} This is reproducible using the sample project here https://developer.apple.com/documentation/uikit/synchronizing-documents-in-the-icloud-environment. Steps to reproduce in that project: Tap the plus sign in the top right corner to create a new document Add a document name and tap "Save to Documents" Go to Settings > {Name} > iCloud > Storage > SimpleiCloudDocument App Name > select "delete data from iCloud" Reopen the app and repeat steps 1-2 Observe error on MainViewController+Document.swift:59 Deleting and reinstalling the app doesn't seem to help.
2
0
74
Aug ’25