What's new in CloudKit

RSS for tag

Discuss the WWDC21 session What's new in CloudKit.

View Session

Posts under wwdc21-10086 tag

10 Posts
Sort by:
Post not yet marked as solved
8 Replies
2.4k Views
So I tried the public database feature of NSPersistentCloudKitContainer last year but never really got anywhere so I thought i'd try it again this year. However I've still had basically no luck and I figured now might be a good time to try and document the issues I have had. The documentation for this at https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/creating_a_core_data_model_for_cloudkit mentions shouldInitializeSchema which from what I can gather was removed in a beta version a long ** time ago. It appears to now be a method on the container - container.initializeCloudKitSchema(). Ya'll should update this documentation. initializeCloudKitSchema does not work if you have options.databaseScope = .public on the NSPersistentCloudKitContainerOptions. You get a bunch of errors saying "No authToken received for asset" Turning off the public scope and then calling initializeCloudKitSchema gets you the Record types you need created in the CloudKit console, then removing the initialise code and setting it back to public, it APPEARS to work, but then... The WWDC video from 2020 says that before you can sync you need to add two indexes to each record type recordName and modifiedAt however if you get this far you will have no such fields. After running it a few times and scouring through the logs you will spot a few errors telling you about missing indexes - adding querable index to recordID, and queryable + searchable to modTime gets you something that.... appears to work... kind of. Ok so you get this far, and you insert some object into your store and save them - and they appear on the cloudkit server, huzzah!. Then you delete the app and reinstall it, and the objects appear in your app, huzzah! However you will now start getting a ton of these kinds of errors in your log: com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x2814192f0: "Server Rejected Request" (15/2027); server message = "Custom zones are not allowed in public DB"; op = 8F0FD95A1EFB2348; uuid = F1DCD158-BA28-4E20-AD18-723F603A0C00> And if you use your app to add or edit any objects they won't make it to CloudKit any more. However, adding new objects via the console will make them appear in the app. At this point I kinda gave up. Can somebody tell me I am an *****, or does this feature legitimately not work?
Posted
by
Post not yet marked as solved
2 Replies
701 Views
The WWDC 2021 CloudKit session talked about the new encryptedValues field on CKRecord. It also indicated that CKAssets have already been end-to-end encrypted in previous releases. The documentation indicates that for encrypted values such as these: CloudKit encrypts the fields’ values on-device before saving them to iCloud, and decrypts the values only after fetching them from the server. The encryption keys are available exclusively to the record’s owner and, if the user shares the record, that share’s participants. For a client that is accessing CloudKit via the HTTP interface, the documentation indicates that assets have a downloadURL property which can be used to fetch the asset. Does this URL download the already-decrypted asset? Or does it need to be encrypted after downloading? If the asset is already decrypted at the time it is downloaded, how can this work, since as I understand it the key should not even be available to Apple. If the asset is not decrypted at that point, is there documentation about how we need to decrypt it?
Posted
by
Post not yet marked as solved
1 Replies
543 Views
Hi. I have heard that the CloudKit APIs should be ready for the new async and await pattern. In the demo app, I see completion handlers and completion blocks. Also, I have an app that needs to use the share DB and it is quite confusing and messy how different caches are handled. I was hoping for a more straightforward API. Is any chance that we can see an updated demo of how to use the shared database in a list?
Posted
by
Post not yet marked as solved
2 Replies
522 Views
Does the new encrypted fields work with CloudKit JS? I have checked the API for CloudKit JS, and under CloudKit.Record there is no mentioning of encrypted fields. It feels like this API has not been updated for a while. Does this mean that if I use field-level encryption, I will not be able to use CloudKit JS?
Posted
by
Post not yet marked as solved
1 Replies
261 Views
Can Apple clarify that the values showing in iCloud Console for Encrypted fields is intentionally being decrypted? Or that it was ever encrypted in the first place? For each of my Encrypted Strings, the value is showing in the console. I am looking at my private database records, but it isn't totally clear that the value is unencrypted because I'm auth'd. These values should have a decrypt button next to them if the user is able to do do. It is unclear if encryption is working otherwise.
Posted
by
Post marked as solved
1 Replies
480 Views
The function in question is the following. func records(for ids: [CKRecord.ID], desiredKeys: [CKRecord.FieldKey]? = nil) async throws -> [CKRecord.ID : Result<CKRecord, Error>] Note that the returned value looks like a dictionary of the form [CKRecord.ID : Result<CKRecord, Error>], but the input is an array of CKRecord.IDs. There are similar functions, but they return a tuple. Like the below example. func records(matching query: CKQuery, inZoneWith zoneID: CKRecordZone.ID? = nil, desiredKeys: [CKRecord.FieldKey]? = nil, resultsLimit: Int = CKQueryOperation.maximumResults) async throws -> (matchResults: [(CKRecord.ID, Result<CKRecord, Error>)], queryCursor: CKQueryOperation.Cursor?) Note that matchedResults is an array of tuples consisting of [(CKRecord.ID, Result<CKRecord, Error>)]. I would have thought that the return type in the first function would also be of the form [(CKRecord.ID, Result<CKRecord, Error>)]. What am I missing?
Posted
by
Post not yet marked as solved
0 Replies
231 Views
<CKError 0x28250d500: "Invalid Arguments" (12/2006); server message = "Only shared zones can be accessed in the shared DB"; op = 608B307A1B891298; uuid = B82344B1-B4FF-42B7-913C-4F2F07A10FD7> Has Used ShareDB
Posted
by
Post not yet marked as solved
0 Replies
222 Views
I'm working on an app that uses NSPersistentCloudKitContainer to handle CloudKit sharing. Against all odds I've gotten the sharing to work, but now I'm seeing errors on startup that look very much like some kind of background loop trying to merge changes from multiple users and failing. In a more traditional CloudKit installation not backed on NSPersistentCloudKitContainer this feels like a case where I'd have to provide some code to handle the merge. In the brave new world I can't seem to find anyway to affect this Mirroring Delegate. It starts when I initialize the NSPersistentCloudKitContainer and produces the error below (as well as a long stream of similar errors). Any ideas? error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _exportFinishedWithResult:exporter:](1347): <PFCloudKitExporter: 0x282d2ead0>: Export failed with error: <CKError 0x280079470: "Partial Failure" (2/1011); "Failed to modify some records"; partial errors: { cloudkit.zoneshare:(Pacts:__defaultOwner__) = <CKError 0x280079680: "Server Record Changed" (14/1022); "Participants conflict while trying to update share from the server. Participants: === Client: (     "<CKShareParticipant: 0x100cebb70; participantID=..., isCurrentUser=true, role=owner, permission=readWrite, acceptanceStatus=Accepted, identity=<CKUserIdentity: 0x100c4cae0; userID=__defaultOwner__:(_defaultZone:__defaultOwner__), nameComponents=, cached=false, publicKeyVersion=2>, hasProtectionInfo=true, invitationTokenStatus=Healthy, isAnonymousInvitedParticipant=false>" ) === Server: (     "<CKShareParticipant: 0x100c26db0; participantID=..., isCurrentUser=true, role=owner, permission=readWrite, acceptanceStatus=Accepted, identity=<CKUserIdentity: 0x100c13b60; userID=__defaultOwner__:(_defaultZone:__defaultOwner__), nameComponents=..., lookupInfo=<CKUserIdentityLookupInfo: 0x100c13c00; email=...>, cached=false, publicKeyVersion=2>, hasProtectionInfo=true, invitationTokenStatus=Healthy, isAnonymousInvitedParticipant=false>",     "<CKShareParticipant: 0x100c25960; participantID=..., isCurrentUser=false, role=user, permission=readWrite, acceptanceStatus=Accepted, identity=<CKUserIdentity: 0x100c259f0; userID=_6cd4c7c8091c946d4b8e704efbfc0bc4:(_defaultZone:__defaultOwner__), nameComponents=..., lookupInfo=<CKUserIdentityLookupInfo: 0x100c68d10; email=...>, cached=false, publicKeyVersion=2>, hasProtectionInfo=true, invitationTokenStatus=Healthy, isAnonymousInvitedParticipant=false>" )"> }>
Posted
by