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

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
760
Mar ’24
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
177
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
525
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
464
Dec ’23
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
633
Dec ’23
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
507
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
347
Jan ’24
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
364
Jan ’24
SwiftData + iCloudkit sync Error
In my Swiftui - SwiftData based Application I get the following error after running it both on simulator and real device... The App itself runs, and all Cloudkit requirements are met on data model side. So the problem is, that it is simply no syncing to iCloud: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(): <NSCloudKitMirroringDelegate: 0x282648620>: Failed to set up CloudKit integration for store: <NSSQLCore: 0x10440b270> (URL: file:///var/mobile/Containers/Data/Application/731332F0-B79C-4433-AF57-875C3CC72FCD/Library/Application%20Support/default.store) <CKError 0x28112d860: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = 98551939-72A4-4EBB-BB0E-6E6D87DCE285; partial errors: { com.apple.coredata.cloudkit.zone:defaultOwner = <CKError 0x281112070: "Server Rejected Request" (15/2001); "Request failed with http status code 500"; uuid = 98551939-72A4-4EBB-BB0E-6E6D87DCE285> }> error: CoreData+CloudKit: recoverFromError:](): - Attempting recovery from error: <CKError 0x28112d860: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = 98551939-72A4-4EBB-BB0E-6E6D87DCE285; partial errors: { com.apple.coredata.cloudkit.zone:defaultOwner = <CKError 0x281112070: "Server Rejected Request" (15/2001); "Request failed with http status code 500"; uuid = 98551939-72A4-4EBB-BB0E-6E6D87DCE285> }> error: CoreData+CloudKit: _recoverFromError:withZoneIDs:forStore:inMonitor:](): <NSCloudKitMirroringDelegate: 0x282648620> - Failed to recover from error: CKErrorDomain:15 Recovery encountered the following error: (null):0 Can anyone help me with this Problem Thank you! Kind Regards Chris
2
0
758
Jan ’24
TooManyProviderTokensUpdates - how many is too many
Our service is 100% on token-based authentication with APNs. Each pod generates a new token to use every 30 mins. We have hundreds of pods. We implemented this way because in Refresh your token regularly section it says Refresh your token no more than once every 20 minutes and no less than once every 60 minutes. APNs report an error if you use a new token more than once every 20 minutes on the same connection. However, we saw TooManyProviderTokensUpdates sporadically. What is even stranger is, the trigger of the error does not correlate to the number of pods as we scaled up or down, nor does it correlate to the QPS. To me, it looks like It triggers randomly. Can someone from Apple shed some light on this?
0
1
227
Jan ’24
SwiftData with CloudKit failing to migrate schema
My app has been in the App Store a few months. In that time I've added a few updates to my SwiftData schema using a MigrationPlan, and things were seemingly going ok. But then I decided to add CloudKit syncing. I needed to modify my models to be compatible. So, I added another migration stage for it, changed the properties as needed (making things optional or adding default values, etc.). In my tests, everything seemed to work smoothly updating from the previous version to the new version with CloudKit. So I released it to my users. But, that's when I started to see the crashes and error reports come in. I think I've narrowed it down to when users update from older versions of the app. I was finally able to reproduce this on my end, and Core Data is throwing an error when loading the ModelContainer saying "CloudKit integration requires that all attributes be optional, or have a default value set." Even though I did this in the latest schema. It’s like it’s trying to load CloudKit before performing the schema migration, and since it can’t, it just fails and won’t load anything. I’m kinda at a loss how to recover from this for these users other than tell them to delete their app and restart, but obviously they’ll lose their data that way. The only other idea I have is to setup some older builds on TestFlight and direct them to update to those first, then update to the newest production version and hope that solves it. Any other ideas? And what can I do to prevent this for future users who maybe reinstall the app from an older version too? There's nothing special about my code for loading the ModelContainer. Just a basic: let container = try ModelContainer( for: Foo.self, Bar.self, migrationPlan: SchemaMigration.self, configurations: ModelConfiguration(cloudKitDatabase: .automatic) )
4
3
1.1k
Mar ’24
Delay in CKRecord uploads
Hi, I have recently noticed that it's taking my app a long time between the CKModifyOperations being 'completed' in the app, and for the record to actual show up through either looking at the CloudKit dashboard, or by using CKQueryOperations. The whole upload can take 10-15 minutes or more, from the time the CKOperation has completed to the time I can see all the records on the dashboard. The 'upload' seems to be happening in chunks ... for e.g. if I uploaded a 100 records, if I check after 2 minutes the query will show 20 records, and then 35-40 a bit later, and after 10+ minutes will show all 100 records (exact numbers vary of course). This was never an issue before, but has recently been reported by a couple of users of my app, and I need to know what's going on before it balloons into a big thing. And it's highly problematic, because it leads to users not being able to download the records that they uploaded on the first device. Is there something in CloudKit servers that have changed recently? Can someone in the CloudKit team take a look? I filed a Feedback, along with CloudKit profile logs: FB13537245 I can also reproduce the issue in production as well as development environments.
1
0
320
Jan ’24
CKQueryOperation in private database produces 500 errors from server and in CloudKit Console
I've been scratching my head on this one. Out of the blue, part of my 'synchronization' mechanism that copies 'favorites' from device to device has stopped working. A user can save a favorite location and it will propagate to all of their other devices, or repopulate after an uninstall and reinstall. My code in the space hasn't changed for months and I haven't made any schema changes to this type either. Last night I noticed the process wasn't working anymore. My CKQueryOperation result completion is returning this error: &lt;CKError 0x2818a16b0: "Server Rejected Request" (15/2001); "Request failed with http status code 500"; uuid = 2CA523A6-8F39-4538-98AF-E9B7D6CACF73&gt; What is telling to me is that the CloudKit Console also fails with an internal error when I try to query this type in MY private database for two different accounts. I can query another type in the private database but this one won't work for two of the Apple ID's I have tried. Also interesting, if I query this type in the PUBLIC database, even though this type is only saved to the private database, that operation succeeds just fine. I don't want to burn a DTS ticket for a server issue. FB13543186 - CloudKit: Receiving 500 when performing a query operation on the private database CloudKit status page is green on the developer site as of this morning.
3
0
572
Apr ’24
SwiftUI view not updated after SwiftData change through CloudKit
A SwiftUI view is displaying a SwiftData model object that's being updated on another device, using CloudKit. The update arrives through CloudKit and the view is correctly updated. However, when the view is not displaying the model object directly, but in a nested view, this nested view is NOT updated. Why not? Is this a bug? Or is it just me, forgetting about some elementary detail? A workaround (that I definitely don't like!) is to put a dummy SwiftData query in the nested view. Even when the dummy query result is never used, the view now IS updated correctly. Why? The code below is mostly Xcode's standard template for a SwiftUI+SwiftData+CloudKit app, modified to use a String property i.s.o. a Date, and to be able to edit that name in a Textfield. The ContentView: struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var items: [Item] var body: some View { NavigationSplitView { List { ForEach(items) { item in @Bindable var item = item NavigationLink { VStack(alignment: .leading) { // item details in same view TextField(item.name, text: $item.name) .textFieldStyle(.roundedBorder) .padding() .background(.red.opacity(0.5)) // item details in nested view ItemDetailView(item: item) .padding() .background(.yellow.opacity(0.5)) Spacer() } } label: { Text(item.name) } } .onDelete(perform: deleteItems) } #if os(macOS) .navigationSplitViewColumnWidth(min: 180, ideal: 200) #endif .toolbar { #if os(iOS) ToolbarItem(placement: .navigationBarTrailing) { EditButton() } #endif ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { Text("Select an item") } } private func addItem() { withAnimation { let newItem = Item(name: "item") modelContext.insert(newItem) } } private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(items[index]) } } } } The nested ItemDetailView: struct ItemDetailView: View { @Bindable var item: Item // dummy query to force view updates triggered by CloudKit // @Query private var items: [Item] var body: some View { TextField(item.name, text: $item.name) .textFieldStyle(.roundedBorder) } } The result:
1
0
465
Jan ’24
isStoredInMemoryOnly has no effect for macOS + iCloud?
Wondering if anyone else is running into this. It seems ModelConfiguration(isStoredInMemoryOnly: true) for previews (as outlined by Paul Hudson / Hacking with Swift) works correctly for iOS + iCloud syncing macOS WITHOUT iCloud syncing But as soon as I turn on iCloud syncing capability for my macOS target, its as if the isStoredInMemoryOnly has no effect on the macOS target. Here's my code... I made a PreviewHelper to encapsulate the preview logic... enum PreviewHelper { static let previewModelContainer: ModelContainer = { do { let config = ModelConfiguration(isStoredInMemoryOnly: true) let container = try ModelContainer(for: Task.self, configurations: config) return container } catch { fatalError("Failed to create model container for previewing: \(error.localizedDescription)") } }() } And then use it like so... #Preview { let container = PreviewHelper.previewModelContainer for task in MockData.tasks { container.mainContext.insert(task) } return HorizonView() .modelContainer(container) } On the macOS target & destination, using a macOS device in the Preview canvas, with iCloud syncing turned on that code inserts the MockData.tasks into my iCloud container every time the preview refreshes, so the data just keeps getting duplicated. With iCloud syncing turned off it behaves as expected/correctly (just inserting the MockData as needed for Previews). In an iOS target, using the same helper and mock data, the helper behaves as expected/correctly (with or without iCloud syncing enabled). Assuming this might be a bug/oversight with SwiftData and macOS? Or am I missing a needed configuration/capability on the macOS side? Anybody else seeing this?
0
1
302
Jan ’24
'Establishing a User' - CloudKit Discoverability Deprecated.
My App uses Core Data + CloudKit and requires use of CloudKit to store persistent data, that will be shared between Users. I’d like to establish the User’s identity - like so they can augment their Core Data ‘Player’ entity w/ App specific info. Certain interfaces have been deprecated (‘user discoverability’). I’ve taken to creating a ‘dummy shared zone’ and extracting the ‘owner.userIdentity': public func establishUser () async -> User? { let container = cloudKitContainer // If we store the userUUID then the implication is that the `user` can // never be deleted; that is fair enough. let userUUIDKey = "userUUID" var userIdentity = Optional<CKUserIdentity>.none do { // // We'll store the UUID of the CoreData `User` in the CloudKit `User` record. If there // is no UUID in CloudKit, then this will be the first time the User has ever started // the App. We'll create a user and update the CloudKit `User` record // let userID = try await container.userRecordID () let userRecord = try await container.publicCloudDatabase.record (for: userID) // If the `userRecord` does not have a `userUUIDKey` then we must create a new `User`. if nil == userRecord[userUUIDKey] { // See if the user has the required iCloud account. let userStatus = try await container.accountStatus() guard userStatus == .available else { print ("JKP: \(#function) accountStatus: \(userStatus)") return nil } // // Create a `dummyShare` (in a 'dummyZone') so we can access the share's owner // That owner will have our `userIdentity` // do { let dummyZone = CKRecordZone (zoneName: UUID().uuidString) let dummyShare = CKShare (recordZoneID: dummyZone.zoneID) print ("JKP: User: Establish Zone: \(dummyZone.zoneID.zoneName)") // Save the dummyZone and then the dummyShare (for/in the dummyZone) let _ = try await container.privateCloudDatabase.save (dummyZone) let _ = try await container.privateCloudDatabase.save (dummyShare) // Extract the dummyShare's owner's identity - which is 'us/me' userIdentity = dummyShare.owner.userIdentity // Cleanup by deleting the 'dummyShare' and then the 'dummyZone' let _ = try await container.privateCloudDatabase.deleteRecord (withID: dummyShare.recordID) let _ = try await container.privateCloudDatabase.deleteRecordZone (withID: dummyZone.zoneID) } catch { print ("JKP: User Establish Error: \(error.localizedDescription)") } // Create `newUser` with the `userRecordId`. We'll use this to lookup the // Core Data User when players appear in a League. let newUser = User.create (context, scope: Player.Scope.owner, name: (userIdentity?.nameComponents ?? PersistenceController.nameDefault), identification: userIdentity?.lookupInfo .map { PlayerIdentification.create (lookupInfo: $0) } ?? PlayerIdentification()) … } Is this how getting the userIdentity is meant to be done (w/o using the deprecated interfaces)? The deprecated interfaces, when warned in Xcode, reference a sample project; that project doesn’t actually use/get the userIdentity. Also the deleteRecord and deleteRecordZone don’t appear to remove the dummy zone in CloudKit; why?
1
0
367
Jan ’24
CloudKit Sync Complete Event/Notification
How does one know when the CloudKit data in a CoreData+CloudKit (NSPersistentCloudKitContainer) has been fully synchronized. UseCase would be a user starts the App on a second device, user deletes then reinstalls the App, another User accepts a share and the share needs to sync. Is the containerEventChanged Notification for 'import success' the definitive event? CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _finishedRequest:withResult:](3403): Finished request: <NSCloudKitMirroringImportRequest: 0x600002345d10> 729A742A-7F3B-42F1-B04C-72705D41FFEF with result: <NSCloudKitMirroringResult: 0x600000c4edc0> storeIdentifier: 79FA5848-A135-41B1-A36A-09F2F914D23D success: 1 madeChanges: 0 error: (null) As the sync could be time-consuming, is there a way to identify a single CloudKit record?
1
0
646
Jan ’24