I enabled Advanced Data Protection for my developer account, and this (understandably) broke access to my private records in CloudKit Console.
I disabled Advanced Data Protection but CloudKit Console still cannot connect. In the database popup the "Click here to retry..." option always fails silently.
Does anyone know a workaround?
CloudKit
RSS for tagStore structured app and user data in iCloud containers that can be shared by all users of your app using CloudKit.
Posts under CloudKit tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I’m looking for code samples (if it’s possible) for de-duplicating the public database. I have seen code samples on how to de-duplicate the private database, but I haven’t seen anything regarding the public database.
I found that the main application and widget NSUbiquitousKeyValueStore data is completely independent?
(I signed in to the same iCloud account, the same AppGroup, the same iCloud Containers for the app and widget, and Key-value Storage was checked.)
But when I get on the widget and modify NSUbiquitousKeyValueStore data, find the Key to the value of the same, such as in the screenshot, the main application of 'gemstone' value is 24, But the widget's value is still 0.
I thought it was a synchronization problem, but using NSUbiquitousKeyValueStore.default.synchronize() or restart the App didn't solve the problem
... “Add Image”function can't used, this is the Logs:
Main App Logs:
---ubiquitousKeyValueStoreDidChange
---Change reason: 0
---The key 'experience' was updated to value '-28'
---UbiquitousKeyValueStoreDidChange: [AnyHashable("NSUbiquitousKeyValueStoreChangedKeysKey"): <__NSSingleObjectArrayI 0x280098960>(
experience
)
, AnyHashable("NSUbiquitousKeyValueStoreChangeReasonKey"): 0]
---ubiquitousKeyValueStoreDidChange
---Change reason: 0
---The key 'gemstone' was updated to value '24'
---UbiquitousKeyValueStoreDidChange: [AnyHashable("NSUbiquitousKeyValueStoreChangedKeysKey"): <__NSSingleObjectArrayI 0x280081c70>(
gemstone
)
widget Logs:
--- widget health: 0, level: 0, experience: 0
---ubiquitousKeyValueStoreDidChange
---Change reason: 0
---The key 'experience' was updated to value '2'
---UbiquitousKeyValueStoreDidChange: [AnyHashable("NSUbiquitousKeyValueStoreChangeReasonKey"): 0, AnyHashable("NSUbiquitousKeyValueStoreChangedKeysKey"): <__NSSingleObjectArrayI 0x159e752f0>(
experience
)
]
--- widget health: 0, level: 0, experience: 2
---ubiquitousKeyValueStoreDidChange
---Change reason: 0
---The key 'gemstone' was updated to value '2'
---UbiquitousKeyValueStoreDidChange: [AnyHashable("NSUbiquitousKeyValueStoreChangeReasonKey"): 0, AnyHashable("NSUbiquitousKeyValueStoreChangedKeysKey"): <__NSSingleObjectArrayI 0x15bb0cd80>(
gemstone
)
]
Starting only recently, cloudSharingControllerDidSaveShare: stopped firing with no code changes on my end.
Is anyone else experiencing this same issue?
Hello,
I have a couple of questions about the CloudKit public database:
Is it possible to control what authenticated users can write to the database on the server side? I know I could write logic in my iOS app to prevent to prevent certain actions, like uploading more data than I want to allow, but traditionally one would write server-side checks too. Even if I don't use CloudKit JS, it still seems like a malicious user could intercept network traffic and interact directly with iCloud to bypass any validations I've included in my app.
Is it possible to block a user from using my app and interacting with CloudKit entirely? Along the same lines as question 1, I may want to block a malicious user from interacting with my public database, particularly writing to it.
Is it common practice to write configuration settings to the public database as an administrative user and to have the app look for these known records? For example, I could add records to a configuration zone via the iCloud dashboard and have my app read them at startup to do things like enable/disable signups.
Thanks for any help and guidance on these issues!
I'm testing disabling iCloud for my app (https://support.apple.com/en-gb/HT207689) and it's disabled in my main app but when I use the share extension it's always enabled. I would think that disabling iCloud would disable it for all extensions you might have in your app.
Is there no way to disable iCloud for an extension only for main app?
I have made an app to test flight, and I am using Push Notifications Console by apple, and all I need it how to get the hexadecimal bytes that identify the recipient's device. (Device Token) to be able to send push notifications. I just want to send it to all users at the same time.
So I am trying to sync only some of my Models with iCloud and others kept locally in the default.store. I am having a world of issues so before I start looking for the needle in my haystack. I would like to ask this forum, is my approach one that should work as desired or is my code obviously why things are not working? All my Models have default values and relationships where needed are optionals. iCloud is working but my issue arises when i try to exclude some models. So I want to sync "modelsForCloudSyncing" but not "modelNotForCloudSyncing" In advance thank you
var avoidCloudSyncModelContainer : ModelContainer = {
let modelNotForCloudSyncing = Schema([NoCloudSyncModel.self])
let modelConfigForNoCloudSync = ModelConfiguration(schema: modelNotForCloudSyncing, cloudKitDatabase: .none)
let modelsForCloudSyncing = Schema([CloudSyncModelA.self, CloudSyncModelB.self, CloudSyncModelC.self])
let modelConfigForCloudSync = ModelConfiguration(schema: modelsForCloudSyncing, cloudKitDatabase: .automatic)
do {
return try ModelContainer(for: NoCloudSyncModel.self, CloudSyncModelA.self, CloudSyncModelB.self, CloudSyncModelC.self, configurations: modelConfigForNoCloudSync, modelConfigForCloudSync)
}
catch { fatalError("Could not create ModelContainer: \(error)") }
}()
...
{
ContentView()
}.modelContainer(avoidCloudSyncModelContainer)
We're doing some disaster recovery management / risk management and a point-of-failure for our app is if we lose access to our bundle id.
From my understanding, secure keychain items are scoped to your bundle ID as well as iCloud files stored under the app with 'hidden' scope.
Losing our bundle ID is a scenario we want to eliminate completely from our threat/disaster modelling.
Is this a realistic concern we should have?
Is there any tool to automatically migrate data & data structure from Google Firebase to CloudKit?
TLDR: How can I listen to changes in SwiftData and share the data via WatchConnectivity?
I am developing an app for the Apple Watch where the iPhone can act as a remote for the Watch.
The App on the Watch should work independently from iPhone. The user can create elements on the Watch and start the action associated with the element. The iPhone user can see the elements created on the Watch and start the action on the Watch from the iPhone (if possible I want to add the functionality to let the user update the elements on both devices, but that's not a priority atm).
I tried to get it to work with CloudKit and SwiftData, but somehow I couldn't get CloudKit to initialize correctly. After further research, I reconned that using WatchConnectivity and ApplicationContext should be a suitable approach.
To communicate with the iPhone App, I created a singleton class that manages the communication. Now I want this class to listen to the changes in SwiftData to send the elements to the iPhone, but I don't know how I can get access to the ModelContext in the Communicator class. I read that passing the value from the initializer of a view is not good practice and it didn't work for me.
What would be a suitable way to achieve the desired behavior of my app? Any help and feedback is appreciated. TIA
Friends,
I have created an App in SwiftData that uses CloudKit to sync between devices. I am using Xcode 15.0.1, and iOS 17.1.1. For further context, I am calling modelContext.save() with every change that I want to synchronise, and this seems to call a CloudKit save, as expected, within the development environment.
The synchronisation works great in the development environment with no issues, it updates fairly quickly and I use @Query to manage SwiftUI updates in the most direct way possible. It is a complex model with many relationships, and I call @Query and filter instances to get to the instance required, rather than using traditional Bindings, as many tutorials and WWDC have suggested.
When I switch to the production environment the app synchronises between devices great using the production CloudKit container. I have set up push notification certificates, and these seem to work. The issues is that, after a few minutes, the synchronisation stops happening between devices.
When synchronisation is working, Device 1 initially saves to CloudKit, and you can see the items update in the CloudKit console. When synching stops working, Device 1 stops saving, and the CloudKit console stops updating.
If I then delete and install the app on Device 1 from TestFlight, you can see that it starts saving again, with updates to the CloudKit console as expected.
But, Device 2 does not begin updating again unless you delete the app on that device, and install again.
This behaviour seems to suggest that both devices become logged out or deregistered from CloudKit after a short period of time as a consequence of some unknown process within CloudKit or SwiftData. When logged out, each device cannot write to, or read from, CloudKit.
Now, the problem with trying to fix the issue is that the registration with CloudKit, silent push notifications, and fetches, are all managed "under the hood" by SwiftData.
In the production environment, you cannot configure any registration state or refresh registration within your code, because you don't have access to the parts of SwiftData that manage this.
I wanted to find out if this is an issue that has been encountered by other users, and if anyone can help with a solution, or perhaps a debugging strategy that I can use to find out what is happening.
Thank you all in advance.
Hi,
My app has been receiving a huge increase in the number of CKHTTPStatus=503 errors over the past couple of months. I created a thread before, and also a Feedback (FB13300807) over a month ago, but I haven't gotten any assistance on this, and am wondering if there is any better way to get the attention of a CloudKit engineer who might be able to help.
From my users, I was able to print out the error code and error userInfo in the console:
error.code == 15 (the same as CKErrorServerRejectedRequest),
UserInfo={ContainerID=, CKHTTPStatus=503, RequestUUID=17C6B9B9-35DD-411B-8AED-7A497075D228, OperationID=5285362CCD2DDB32}}, CKHTTPStatus=503}
How can I get this issue addressed? A lot of users are reporting this issue and it's creating a big support burden.
Very simple one. how do I add “create“ permissions for my CloudKit security roles. For some reason “create“ is greyed out when I try to check the box for _creator
Starting today around 2PM MST I started receiving emails from users reporting their CloudKit synced data was 'completely gone'...
They are reporting no error messages... so that means the CKQuery on the private database is completing without error, but simply not returning any previously saved records...
This appears to be only occurring to a percentage of my users and I cannot replicate it on my device (I'm using iOS 17.1.2.
Are any other developers experiencing this?!
SwiftData supports the unique attribute. Unfortunately that one is not available when using CloudKit for SwiftData.
I'm looking for some help (maybe an example) or best practices how to implement the same behavior.
I've created a container, enabled CloudKit in xCode and added code to reference the container and save. Every time I run the app I get this error when I close the game:
Snapshot request 0x2814167c0 complete with error: <NSError: 0x28144df80; domain: BSActionErrorDomain; code: 1 ("response-not-possible")>
The app is not saved and i cannot see any action with the container. My app is built in Unity with C# code and builds with no errors.
I would appreciate and assistance!
I have v3 models in coredata (model: Event, Lecture), and make new model in v4 with swiftdata but model name, property is different (model: EventModel, LectureModel).
For migration, I add V3Schema, V4Schema and MigrationPlan.
enum V4Schema: VersionedSchema {
static var models: [any PersistentModel.Type] = [LectureModel.self, EventModel.self ]
static var versionIdentifier = Schema.Version(4, 0, 0)
}
enum V3Schema: VersionedSchema {
static var models: [any PersistentModel.Type] = [Event.self, Lecture.self]
static var versionIdentifier = Schema.Version(3, 5, 2)
}
enum ModelMigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] = [V3Schema.self, V4Schema.self]
static var stages: [MigrationStage] = [migrateV3ToV4]
}
extension ModelMigrationPlan {
static let migrateV3ToV4 = MigrationStage.custom(fromVersion: V3Schema.self,
toVersion: V4Schema.self,
willMigrate: willMigrate,
didMigrate: { _ in Log.debug(message: "Migration Complete") })
}
private func willMigrate(context: ModelContext) throws {
try migrateLectures(context: context)
try migrateEvents(context: context)
try context.save()
}
private func migrateEventTypes(context: ModelContext) throws {
// create new v4 event model using v3 event model.
}
private func migrateLectures(context: ModelContext) throws {
// create new v4 lecture model using v3 lecture model.
}
static let release: ModelContainer = {
let v4Schema = Schema(V4Schema.models)
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "app group id")
let databaseURL = containerURL?.appending(path: "**.sqlite")
let configuration = ModelConfiguration("**",
schema: v4Schema,
url: databaseURL!,
cloudKitDatabase: .private("**"))
#if DEBUG
do {
try autoreleasepool {
let desc = NSPersistentStoreDescription(url: configuration.url)
let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: configuration.cloudKitContainerIdentifier!)
desc.cloudKitContainerOptions = opts
desc.shouldAddStoreAsynchronously = false
if let model = NSManagedObjectModel.makeManagedObjectModel(for: V4Schema.models) {
let container = NSPersistentCloudKitContainer(name: "**", managedObjectModel: model)
container.persistentStoreDescriptions = [desc]
container.loadPersistentStores(completionHandler: { _, err in
if let err {
Log.error(message: "Store open failed: \(err.localizedDescription)")
}
})
try container.initializeCloudKitSchema()
Log.debug(message: "Initialize Cloudkit Schema")
if let store = container.persistentStoreCoordinator.persistentStores.first {
try container.persistentStoreCoordinator.remove(store)
}
}
}
} catch {
Log.error(message: "Failed: \(error.localizedDescription)")
}
#endif
return try! ModelContainer(for: v4Schema, migrationPlan: ModelMigrationPlan.self, configurations: configuration)
}()
But when I run, I got error message.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _scheduleAutomatedExportWithLabel:activity:completionHandler:]_block_invoke(3508): <NSCloudKitMirroringDelegate: 0x1036b1540> - Finished automatic export - ExportActivity - with result: <NSCloudKitMirroringResult: 0x1035da810> storeIdentifier: ***** success: 0 madeChanges: 0 error: Error Domain=NSCocoaErrorDomain Code=134407 "Request '*****' was cancelled because the store was removed from the coordinator." UserInfo={NSLocalizedFailureReason=Request '****' was cancelled because the store was removed from the coordinator.}
I don't know why store was removed from the coordinator.
Any have solutions?
My app uses a significant amount of space in a private CloudKit database, and I need to be able to show users how much free space they have. Is there any way to get this value programmatically?
I am trying to use ArchiveStream.process on MacOS as outlined in the documentation here:
https://developer.apple.com/documentation/accelerate/decompressing_and_extracting_an_archived_directory
I have been able to successfully do the following:
Take objects and create Data objects
Create a UIDocument that is FileWrapper based
Compress the UIDocument as an .aar archive
Upload it to iCloud as a CKRecord
Download it as an .aar and decode it back to a directory
Decode the directory as individual data items and back to objects
The problem is that I sometimes can only download from iCloud once and have the decompression function - other times it may work two or three times but ultimately fails when trying to call ArchiveStream.process
The error reported by ArchiveStream.process is simply 'ioError' but on the console I see the following:
[0xa5063c00] Truncated block header (8/16 bytes read)
[0xa503d000] NOP received
[0xa5080400] processStream
[0xa7019000] decoder failed
[0xbd008c00] istream read error
[0xbd031c00] refill buffer
[0x90008000] archive stream read error (header)
[0xc8173800] stream cancelled
The test data I am using does not change so it does not appear to be related to what I am compressing.
But I am at a loss how to prevent the error.
This is IOS 17 running on MacOS (as iPad) and on IOS 17 devices.