CloudKit

RSS for tag

Store 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

Can CloudKit security rules be scoped to an application?
I'm building two apps. They both share a CloudKit container. One application is designed to edit the contents of the public database regardless of who a record's creator is. The other should only be allowed to read from the public database. Since CloudKit is largely a client-side framework it's easy enough to enforce this client side. Are there any additional guarantees that iCloud provides to enforce what the clients are signed to do? Or is there a risk of having some actor tamper with the public database that isn't using the editing application?
0
0
368
Jan ’24
CloudKit Web Services with ASP.NET Core server to server key auth
Hello, I have an iOS app that is still in development, and I am also making a website for it with asp.net core. I am trying to use a server to server key, but it isn't working. The response is: { "uuid" : "some_uuid", "serverErrorCode" : "AUTHENTICATION_FAILED", "reason" : "Authentication failed" } I am using a library called EllipticCurve. You can find it here. My code is: var requestData = new { zoneID = new {}, query = new { recordType = "CD_Person", filterBy = new [] { new { comparator = "EQUALS", fieldName = "CD_email", fieldValue = new { value = email, type = "String" } } }, sortBy = new [] { new { fieldName = "CD_email" } } }, zoneWide = "true", numbersAsStrings = "true" }; string request = JsonSerializer.Serialize(requestData); HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("X-Apple-CloudKit-Request-KeyID", "my_key_id"); DateTime date = DateTime.Now; string iso8601Date = date.ToUniversalTime().ToString("u").Replace(" ", "T"); client.DefaultRequestHeaders.Add("X-Apple-CloudKit-Request-ISO8601Date", iso8601Date); byte[] bytes = Encoding.UTF8.GetBytes(request); SHA256 hashstring = SHA256.Create(); byte[] hash = hashstring.ComputeHash(bytes); string base64Request = Convert.ToBase64String(hash); string paramsToSign = $"{iso8601Date}:{base64Request}:my url"; PrivateKey privateKey = PrivateKey.fromPem("-----BEGIN EC PRIVATE KEY-----\nprivate_key\n-----END EC PRIVATE KEY-----"); Signature signature = Ecdsa.sign(paramsToSign, privateKey); client.DefaultRequestHeaders.Add("X-Apple-CloudKit-Request-SignatureV1", signature.toBase64()); var content = new StringContent(request, Encoding.UTF8, "application/json"); var response = client.PostAsync("https://api.apple-cloudkit.com/database/1/my_container/development/public/records/query", content); string responseString = response.Result.Content.ReadAsStringAsync().Result; Console.WriteLine(responseString); return View(); Any help would be appreciated.
0
0
349
Jan ’24
CloudKit Data Startup Issue
Afternoon all, I am starting out and want to store data in the App, some will be user specific and some general. So I have a new developer account which should have CloudKit permissions. I am just trying to make any of the most basic example applications work, but keep hitting issues. I create an App, select CloudKit and SwiftData. When I go into the signing and capabilities I select the Team which has the developer account. Then the CloudKit is selected as I clicked it when creating the project, but no Container is selected. I create a Container using the +, it names it iCloud.com.mydomain.AppName. However it is coloured in Red text. I press the refresh and then it turns into black text, the Push Notifications appear all populated for 1 second then all disappear. I have nothing under Push now, only a Trashcan button. The Container is now selected however. Is this an issue that the Push notifications items appeared then vanished? When I then try to run the app, using any of the many attempts I have had with simple code samples, it always fails to create the Container, usually with an error like this: error: Store failed to load. <NSPersistentStoreDescription: 0x600000c79ce0> (type: SQLite, url: file:///Users/cal/Library/Developer/CoreSimulator/Devices/6D2BA1B3-C7CA-499D-A280-AFF4C5E98180/data/Containers/Data/Application/B9CD5E35-08BD-44CC-A72D-EB170E3691C6/Library/Application%20Support/default.store) with error = Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=CloudKit integration requires that all attributes be optional, or have a default value set. The following attributes are marked non-optional but do not have a default value: Item: name} with userInfo { NSLocalizedFailureReason = "CloudKit integration requires that all attributes be optional, or have a default value set. The following attributes are marked non-optional but do not have a default value:\nItem: name"; If I go into the CloudKit database view on Apple, I see the Container listed, albeit it is marked as not deployed to production. To try to remove my newbie issues I have used many web examples, the most recent of which was the "A Beginner’s Guide to SwiftData with a to-do app" from medium.com, which should just work really, snipped from Item.swift below but I have tried several other simple examples which all give the same issue: import Foundation import SwiftData @Model class Item: Identifiable { var name: String init(name: String){ self.name = name } } Any ideas really appreciated. Thank you
2
0
509
Jan ’24
SwiftUI against SwiftData is too fragile and error prone
The hardest part of SwiftUI programming is to correctly define the layers of references that you need as your app grows features. When you add Swift data to the mix, it hard to get much of anything correct. I have an application that interacts with the outside world via BLE and LocationManager. I need to preserve used BLE devices and then store their current state in a static Monitor type class structure. This monitor though, needs to have access to some SwiftData elements, and it is not clear from the documentation whether it's preferred to create multiple ModelContainer instances, when they might share a particular types management. This doesn't feel very safe, so it would then make more sense to have a ModelContainer stuck inside of some other static Monitor object that everyone would use to get the single ModelContainer that should be used. All of the context specific stacking of references in SwiftUI creates huge dependency chains, and it make the build of my application, currently to take 10s of minutes sometimes, when I have changes in flux and the compiler cannot make heads or tails out of broken references. We really need to find a way to get the compiler fixed so that as a Recursive Decent parser, it has an easier time finding a terminal state instead of crawling up and down the stack of references looking for a place that it can reach a terminal state. Not using ';' on every statement is a big part of the problem I feel...
1
0
635
Dec ’23
CKModifyRecordsOperation records limit?
I'm trying to delete many records with one CKModifyRecordsOperation and getting this error: <CKError 0x600000dbe4f0: "Limit Exceeded" (27/1020); "Your request contains 552 items which is more than the maximum number of items in a single request (400)"> This obviously means, that Modify Operation has record limit of 400 which is equal to CKQueryOperation.maximumResults. The good solution here would be to chunk the array of records into subarrays with length less than 400 and add multiple delete operations to the database. The only problem is that the limit for CKModifyRecordsOperation is neither documented nor provided with a constant, so it's basically a magic number. In hope that my prayers would be heard I want to ask to add maximumResults constant to CKModifyRecordsOperation.
3
0
468
Dec ’23
Cloudkit Error: "Invalid bundle ID for container"
I get the "Permission Failure" error ("Invalid bundle ID for container") below only when running my app from my iOS Target, and not my watchkit target. The watch app is able to sync/create/delete items, but my iOS target is unable to even read the data from the cloud. The cloudkit Container ID matches my iOS Target Bundle ID, which is the apps Bundle ID. Looking at the output of CKContainer, the container matches the iOS Bundle ID. I have tried reseting multiple times, creating different cloud containers, reseting the Signing and Capabilites online. It always results in the same issue... What am I missing here? <CKError 0x281b69590: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = D57676F8-455E-4039-9DF4-824E3BAD42BE; container ID = "iCloud.companyName.AppName"; partial errors: { com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x281b771e0: "Permission Failure" (10/2007); server message = "Invalid bundle ID for container"; op = 8CCAD43B495AADC0; uuid = D57676F8-455E-4039-9DF4-824E3BAD42BE> }>
1
0
526
Dec ’23
iCloud Key-Value storage does not work for users with full iCloud
I have a flutter app I developed and some of the users cannot use our backup system which uses iCloud Key-Value storage. These users all have one thing in common. Full iCloud. If they turn off the app from iCloud from backup details page in iCloud settings then it works. But if their iCloud is 100% full and they can't even access the page then it does not work. Can someone tell me why this is happening? My app is made in flutter. It uses this package: https://pub.dev/packages/cloud_kit. Thanks.
0
0
178
Dec ’23
Private database: failed to access iCloud data please signin again.
When I logged into my cloudkit console to inspect the database for some debugging work I couldn't access the private database. It keeps saying "failed to access iCloud data, please signi n again". No matter how many times I sign in again, whether with password or passwordless key it keeps saying the same thing. It says that message when I click on Public database, and private and shared databases are below it. I only noticed this a couple of days ago. It's done this in the past, but I eventually got back into the database but I don't know what changed to make it work.
7
5
771
Mar ’24
Preventing ioError with ArchiveStream.process
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.
2
0
316
Dec ’23
SwiftData+Cloudkit Migration Failed
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?
2
0
492
May ’24
Can't get Apple TV app to connect to iCloud
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!
0
0
375
Dec ’23
CloudKit Erasing Private Database with No Errors?!
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?!
0
0
258
Dec ’23
Huge increase in CKErrorServerRejectedRequest / CKHTTPStatus=503 errors
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.
1
0
308
Dec ’23
SwiftData CloudKit integration seems to log out or deregister
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.
3
1
894
Dec ’23
Syncing data between Watch and iPhone in real-time
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
0
0
587
Nov ’23