Using this Apple repository as a basis
https://github.com/apple/sample-cloudkit-zonesharing
I created and verified the shared zone and the same zone is private for the person who shared it and shared for the person who received it, so aren't they the same zones?
[same zone but different id?]
I can make the person who shared the zone (owner) access the zone as a .shared scope just like the person who was shared.
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 using NSPersistentCloudKitContainer to sync CoreData to CloudKit public database but I have the problem that canUpdateRecord always returns true even for objects created by another iCloud user with _icloud role permission set to Read only. Am I missing something?
Is it possible to integrate CKShare with SwiftData? I wanted to provide a quick and good experience to my users.
When i try to share CKshare (parent record) with one of methods: Mail, Message, copy link then i get:
Obj-C-CloudKit[13190:1488194] [lifecycle] [u 0480B7D0-2E2B-46C7-9D25-273E4466827B:m (null)] [com.apple.CloudDocsUI.CloudSharing(1.0)] Connection to plugin invalidated while in use.
All of a sudden my app started getting this CloudKit error, and it happens to a lot of users. I had no changes to cloud sync for months and really surprised by seeing this. What confuses me even more, is that there is no information on the web about this kind of error. I have no idea what causes it and how to solve it. Would love to get any feedback from the CloudKit engineer.
Client went away before operation 27761871408C460A could be validated; failing
{
"NSUnderlyingError": "<CKUnderlyingError 0x600002573f30: \"ClientInternalError\" (2005); \"Client went away before operation 27761871408C460A could be validated; failing\">",
"CKErrorDescription": "Client went away before operation 27761871408C460A could be validated; failing",
"NSDebugDescription": "CKInternalErrorDomain: 2005",
"NSLocalizedDescription": "Client went away before operation 27761871408C460A could be validated; failing"
}
Seems to happen only on macOS.
Hello,
After iOS 18 fetchChanges() method of CloudKitSync engine does not work as before. Calling the function doesn't fetch changes always, but it does fetch on iOS 17.
However going background and foreground again fetches changes automatically.
I have a requirement to get all records changed after a certain date.
I have set modifiedTimestamp as Queryable, but when I attempt to do any query at all using the following operators: > < >= <= no results are returned. I have confirmed there are records that should be returned. The only operator that works is == and !=.
I have tried the following:
NSPredicate(format: "modificationDate > %@", lastFetched as NSDate)
NSPredicate(format: "___modTime > %@", lastFetched as NSDate)
Hello!
I deleted an index on the cloudkit console of a container in development environment and re-added it again with the same name. After that my app has been giving error on development environment.
The live version is working fine as I haven't deployed the changes.. Any idea what can cause this issue and is there a way to fix it? Thank you
I'm studying sharing through this link. I followed the first steps by changing the bundle identifier of the project, the tests and placing my own container in the config and in the info.plist.
https://github.com/apple/sample-cloudkit-zonesharing
The app appears and in the log it appears that it has managed to access my iCloud, but when I click on share and share something, the following message appears in the console, on the simulator and on the iPhone:
"No options were found, providing default value for access type"
"No options were found, providing default values for permissions"
"connection invalidated"
And finally, when I click on the shared link, the following message appears:
"Item unavailable
The owner stopped sharing, or you don't have permission to open it."
Every new container i create for cloudkit doesn't work and or connect back to my icloud dev account. Here are the errors:
Communication with Apple failed.
An iCloud Container with Identifier 'iCloud.icloud.com.plantclock.backup' is not available. Please enter a different string.
Provisioning profile "iOS Team Provisioning Profile: CGL.CannaGrowLog" doesn't support the iCloud.icloud.com.plantclock.backup iCloud Container.
Provisioning profile "iOS Team Provisioning Profile: CGL.CannaGrowLog" doesn't match the entitlements file's value for the com.apple.developer.icloud-container-identifiers entitlement.
STEPS TO REPRODUCE
Went into xcode > Project name > targets > icloud > containers > + sign and anytime i try to add it fails with the above issues.
Also, going into apple dev website has no option to even see or add containers.
I'm building a SwiftUI social photo-sharing app that uses CloudKit, where user profiles (including a CKAsset for profile pictures) are displayed throughout the app. To reduce redundant fetching of profiles across multiple views, I’m trying to implement a cache for the profile CKRecord into a custom model. (Important for handling the CKAsset for a user’s profile picture, ensuring it’s moved from the CloudKit fileURL staging area)
Here's my current approach:
struct UserProfileModel: Identifiable {
let id: String
let displayUsername: String
var profilePicture: UIImage? = nil
}
class UserProfileCache: ObservableObject {
static let shared = UserProfileCache()
@Published var cache: [UserProfileModel] = []
}
Is this a solid approach for caching CKRecords, or is there a more efficient way to structure this for performance and memory management?
I'd appreciate any input or advice on improving this architecture for performance, memory management, and handling profile updates.
Thanks in advance for your help!
I would like to create a private container and share a zone between two users with different iCloud accounts. All changes made by one would be notified with push notifications to the other user's db. Both could change the same information.
Exactly as it is done in this apple project.
https://developer.apple.com/documentation/cloudkit/shared_records/sharing_cloudkit_data_with_other_icloud_users
However, I have been reading this code for days and I am stuck on it, it is extremely complicated for my level.
I would really like to know if there is any simple project that uses the same idea to build this logic with swiftui.
Hello all!
I'm porting a ios15+ swiftui app to be compatible with Swift 6 and enabling strict concurrency checking gave me a warning that will be an error when switching to swift 6.
I'm initializing a persistence controller for my cloud kit container:
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentCloudKitContainer
init() {
container = NSPersistentCloudKitContainer(name: "IBreviary")
container.loadPersistentStores(completionHandler: { _, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
The warning is on the merge policy:
Reference to var 'NSMergeByPropertyObjectTrumpMergePolicy' is not concurrency-safe because it involves shared mutable state; this is an error in the Swift 6 language mode
I have no idea how to make this concurrency safe, nor I found a documentation entry to help me with this.
Anyone have idea how to solve this?
Thanks in advance
V.
I’m developing an app for inspections that allows users to develop their own template for inspections. Because of this, my data structure has become more than a little complex (see below).
This structure does allow a great deal in flexibility, through, as users can add groups, rows, and individual fields as needed. For example, users can add a header group, then a row to the header with fields for the Building Number, Unit Number, & Inspection Date.
However, I don’t have an efficient way to sort the inspections by the values in these fields. SwiftData sorting is keypath based, which won’t allow me to sort the inspections based on the values only in fields with specific labels.
As an alternative, I can query for fields with a specific label and do a compactMap to the inspection. But this doesn’t scale well when working with potentially hundreds or thousands of inspections as compactMap takes a lot longer then the query takes. It also doesn’t work well if I want to filter inspections or sort using values in multiple user defined fields.
Models below are greatly simplified to just get the point across. More than happy to provide some additional code if asked when I’m back at my laptop with the source code. (Typing this on my iPad at the moment)
@Model final class Inspection {
// init and other fields
var groups: [Group]?
}
@Model final class Group {
// init and other fields
@Relationship(inverse: \Inspection.groups)
var inspection: Inspection?
var rows: [Row]?
}
@Model final class Row {
// init and other fields
@Relationship(inverse: \Group.rows)
var group: Group?
var fields: [Field]?
}
@Model final class Field {
// init and other fields
var label: String?
var type: FieldType // enum, denoting what type of data this is storing
var stringValue: String?
var boolValue: Bool?
var dateValue: Date?
@Attribute(.externalStorage) var dataValue: Data?
@Relationship(inverse: \Row.fields)
var row: Row?
}
My app uses a temporary singleton to store CKRecords for user profiles, to prevent repeated fetching of profile pics & display usernames during a user's session.
Since iOS 18, after leaving the app in the background for an unspecified period of time & reopening it, the app has started to discard the CKAssets in those 'cached' records.
The records are still there, & the custom fields such as the display username string is still accessible. However the profile pic assets aren't?
This is the code that is displaying the profile picture, could this be something to do with some changes to how CKAssets are given file urls?
if postOwnerRecord != nil, let imageAsset = postOwnerRecord!.object(forKey: "profilePicture") as? CKAsset, let photoData = NSData(contentsOf:imageAsset.fileURL!) {
if let uiImage = UIImage(data: photoData as Data) {
let imageToUse = Image(uiImage: uiImage)
Image(uiImage: imageToUse)
}
}
Expected behavior: CKAssets should persist when resuming the app from the background.
Actual behavior: CKAssets are discarded when reopening the app, but custom fields are still accessible.
Question: Is this related to iOS 18, or am I mishandling how CKAssets are cached or their file URLs? Is there a better approach to caching these assets across app sessions? Any pointers or changes would be appreciated.
I've reviewed iOS 18 release notes but didn't find any clear references to changes with CKAsset handling. Any ideas?
Hello everyone,
Xcode 16.0 SwiftData project. CloudKit. WidgetConfigurationIntent.
For some reason, I see a really weird behavior.
I have a shared ModelContainer and an interactive widget where I update the model data through an app intent.
This is my model -
@MainActor
class ItemsContainer {
static let shared = ItemsContainer()
var sharedModelContainer: ModelContainer!
init() {
self.sharedModelContainer = container()
}
func container() -> ModelContainer? {
if let sharedModelContainer {
return sharedModelContainer
}
let schema = Schema([
Session.self,
])
let modelConfiguration: ModelConfiguration
modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .automatic)
do {
let container = try ModelContainer(for: schema, configurations: [modelConfiguration])
self.sharedModelContainer = container
return container
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}
}
And this is how I get the model context across the app and the app intent -
let modelContext = ModelContext(ItemsContainer.shared.sharedModelContainer)
The problem is that somehow, when I update the model context in the app and then in the widget (I save the context after every change), the data is synced between the app and the widget, but then, the data is changed back to the previous state and kind of ignores the widget changes.
Didn't happen before iOS 18/Xcode 16.
Any idea?
Thanks a lot!
I'm using NSPersistentCloudKitContainer and in the CloudKit dashboards I have added indexes for all my records modifiedTimestamp queryable, modifiedTimestamp sortable and recordName queryable.
But I'm still getting this warning message in the console.
<CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _importFinishedWithResult:importer:](1400): <PFCloudKitImporter: 0x30316c1c0>: Import failed with error:
<CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2312): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Attempting recovery from error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromError:withZoneIDs:forStore:inMonitor:](2622): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Failed to recover from error: CKErrorDomain:12
Recovery encountered the following error: (null):0
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate resetAfterError:andKeepContainer:](612): <NSCloudKitMirroringDelegate: 0x301b1cd20> - resetting internal state after error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2200): <NSCloudKitMirroringDelegate: 0x301b1cd20> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringImportRequest: 0x300738eb0> A3F23AAC-F820-4044-B4B9-28DFAC4DE8D7' due to error: <CKError 0x302acf0c0: "Invalid Arguments" (12/2015); server message = "Field 'recordName' is not marked queryable"; op = FF68EFF8D501AED8; uuid = 12C5C84B-EA9B-41A6-AD85-34023827E6FA; container ID = "z.y.x">
Hello everyone,
I’ve recently encountered an issue where my app is working perfectly fine, but I’m seeing an “OTHER” error in the CloudKit dashboard under errors. I’ve checked the logs and there doesn’t seem to be any obvious failure or issue affecting the app’s functionality.
The error doesn’t provide much detail, and I’m having trouble identifying the root cause since everything appears to be functioning as expected in the app. Has anyone else experienced this? Is this something that could be related to a server-side issue, or am I missing something on my end?
Any insights or advice would be greatly appreciated!
Thanks in advance!
Hello,
I’m struggling to go from unversioned data model in SwiftData, to starting to version it.
Some FYI:
I’m using CloudKit
I’m using a widget, where I also pass in my data model and setup my container, this is shared over a group container/app group.
My migration is very simple, I’m adding a property which is not optional ( has default value set, and a default value in initialiser ).
Model:
@Model
class NicotineModel {
var nicotineType: NicotineType = NicotineType.snus
var startDate: Date = Date() + 30
var spendingAmount: Int = 0
var nicotinePerDay: Int = 0
var quittingMethod: QuittingMethod = QuittingMethod.coldTurkey // this is the change in the model, V1 doesn't have the quittingMethod property
var setupComplete: Bool = false
I’ve tried with:
static let migrateV1toV2 = MigrationStage.lightweight(
fromVersion: SchemaV1.self,
toVersion: SchemaV2.self
)
But also
static let migrateV1toV2 = MigrationStage.custom(
fromVersion: SchemaV1.self,
toVersion: SchemaV2.self,
willMigrate: nil,
didMigrate: {
context in
let nicotineModels2 = try context.fetch(FetchDescriptor<SchemaV2.NicotineModel>())
let nicotineModels = try context.fetch(FetchDescriptor<SchemaV1.NicotineModel>())
for model in nicotineModels {
let newModel = SchemaV2.NicotineModel(
nicotineType: model.nicotineType,
startDate: model.startDate,
spendingAmount: model.spendingAmount,
nicotinePerDay: model.nicotinePerDay,
setupComplete: model.setupComplete,
quittingMethod: .coldTurkey
)
context.insert(newModel)
context.delete(model)
}
try context.save()
}
)
and simply
static let migrateV1toV2 = MigrationStage.custom(
fromVersion: SchemaV1.self,
toVersion: SchemaV2.self,
willMigrate: nil,
didMigrate: { context in
let nicotineModels = try context.fetch(FetchDescriptor<SchemaV2.NicotineModel>())
for model in nicotineModels {
model.quittingMethod = .coldTurkey
}
try context.save()
}
)
This gives me the error on startup
SwiftData/ModelCoders.swift:1762: Fatal error: Passed nil for a non-optional keypath \NicotineModel.quittingMethod
On https://icloud.developer.apple.com I can see that the record doesn't include my quittingMethod.
I'm loosing my mind, what am I doing wrong?
Hello, everyone!
I'm using CloudKit JS with a React SPA to allow users from a mobile app to access their data in a web browser. Currently, the project is still under development so there are no public users beside my team.
The way I've integrated CK JS in my app is via their CDN, importing the required url in my index.html file.
However, I'm having issues with the Authentication using Apple Sign In. While the Sign In and Sign Out buttons work correctly for me and my teammates, the session is not persisted for everyone. Actually, I'm the only one from me team that does not have to log in every day.
I have the following configuration function:
export const configureCloudKit = () =&gt; {
window.CloudKit.configure({
locale: 'en-us',
containers: [
{
containerIdentifier: CONTAINER_ID,
apiTokenAuth: {
apiToken: API_TOKEN,
persist: true,
signInButton: {
id: 'apple-sign-in-button',
theme: 'black',
},
signOutButton: {
id: 'apple-sign-out-button',
theme: 'black',
},
},
environment: 'development',
},
],
});
};
As you can see, I'm using the persist:true option so there shouldn't be any issues with having a persistent session.
From my research, I found that CloudKit JS sets a cookie called iCloud.com.myContainerName and if I delete that cookie, when I reload the browser, the session is indeed lost. This happens for all my teammates, same cookie and same behavior.
Nevertheless, I also found three cookies that are not present for any of my teammates but me (using Google Chrome). Those are called:
X-APPLE-WEBAUTH-AC-PARTITION
X-APPLE-WEBAUTH-AC-SERVERINFO
X-APPLE-WEBAUTH-AC-TOKEN
But even if I delete those cookies, the session is not lost for me.
Does anyone know whether I'm doing something wrong with the configuration?
Or if there are something I'm not taking into account regarding the cookies handling in my project?