iCloud & Data

RSS for tag

Learn how to integrate your app with iCloud and data frameworks for effective data storage

CloudKit Documentation

Posts under iCloud & Data subtopic

Post

Replies

Boosts

Views

Activity

CoreData + CloudKit
I am having problems when I first loads the app. The time it takes for the Items to be sync from my CloudKit to my local CoreData is too long. Code I have the model below defined by my CoreData. public extension Item { @nonobjc class func fetchRequest() -> NSFetchRequest<Item> { NSFetchRequest<Item>(entityName: "Item") } @NSManaged var createdAt: Date? @NSManaged var id: UUID? @NSManaged var image: Data? @NSManaged var usdz: Data? @NSManaged var characteristics: NSSet? @NSManaged var parent: SomeParent? } image and usdz columns are both marked as BinaryData and Attribute Allows External Storage is also selected. I made a Few tests loading the data when the app is downloaded for the first time. I am loading on my view using the below code: @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Item.createdAt, ascending: true)] ) private var items: FetchedResults<Item> var body: some View { VStack { ScrollView(.vertical, showsIndicators: false) { LazyVGrid(columns: columns, spacing: 40) { ForEach(items, id: \.self) { item in Text(item.id) } } } } } Test 1 - Just loads everything When I have on my cloudKit images and usdz a total of 100mb data, it takes around 140 seconds to show some data on my view (Not all items were sync, that takes much longer time) Test 2 - Trying getting only 10 items at the time () This takes the same amount of times the long one . I have added the following in my class, and removed the @FetchRequest: @State private var items: [Item] = [] // CK @State private var isLoading = false @MainActor func loadMoreData() { guard !isLoading else { return } isLoading = true let fetchRequest = NSFetchRequest<Item>(entityName: "Item") fetchRequest.predicate = NSPredicate(format: "title != nil AND title != ''") fetchRequest.fetchLimit = 10 fetchRequest.fetchOffset = items.count fetchRequest.predicate = getPredicate() fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Item.createdAt, ascending: true)] do { let newItems = try viewContext.fetch(fetchRequest) DispatchQueue.main.async { items.append(contentsOf: newItems) isLoading = false } } catch {} } Test 2 - Remove all images and usdz from CloudKit set all as Null Setting all items BinaryData to null, it takes around 8 seconds to Show the list. So as we can see here, all the solutions that I found are bad. I just wanna go to my CloudKit and fetch the data with my CoreData. And if possible to NOT fetch all the data because that would be not possible (imagine the future with 10 or 20GB or data) What is the solution for this loading problem? What do I need to do/fix in order to load lets say 10 items first, then later on the other items and let the user have a seamlessly experience? Questions What are the solutions I have when the user first loads the app? How to force CoreData to query directly cloudKit? Does CoreData + CloudKit + NSPersistentCloudKitContainer will download the whole CloudKit database in my local, is that good???? Storing images as BinaryData with Allow external Storage does not seems to be working well, because it is downloading the image even without the need for the image right now, how should I store the Binary data or Images in this case?
1
0
868
Jan ’25
Swift data issue in queries in iOS 18, no pb in iOS 17
Dear community !!! I'm brand new in SwiftUI development. I created an app, I was almost at the end with fine tuning when I got weird behaviours with the iOS 18 version when using Swift Data. I think I'm part of the problem but I can not figure out how to solve it. I've searched, spent so many hours and feel a bit disappointed not succeeding. Here is my first problem : I've two models : @Model class Song: Codable { var uuid: UUID = UUID() var text: String = "" var creationDate: Date = Date.now var updatingDate: Date = Date.now var status: Int = 0 var nbRead: Int = 0 var speed: Float = 0.5 var language: String = "" enum CodingKeys: CodingKey { case uuid, text, creationDate, updatingDate, status, nbRead, speed, language } @Relationship(inverse: \Genre.songs) var genres: [Genre]? ... } and @Model class Genre { //var uuid: UUID var name: String = "" var color: String = "Red" var songs: [Song]? init( name: String, color: String) { //self.uuid = uuid self.name = name self.color = color } } I want to list all songs organised by sections : import SwiftData import SwiftUI struct SongsListView: View { private var searchingText: String @Environment(\.modelContext) private var modelContext @Query(sort: \Genre.name) private var genres: [Genre] @Query var songs : [Song] init(searchText: String) { if !searchText.isEmpty { let predicate = #Predicate<Song> { song in song.text.localizedStandardContains(searchText) } _songs = Query(filter: predicate) } searchingText = searchText } var body: some View { HStack{ List{ if !songs.isEmpty { ForEach(genres, id: \.name){ genre in Section(header: Text(genre.name)){ ForEach (songs){song in if let songGenres = song.genres { if songGenres.contains(genre){ NavigationLink { SongView(song: song) } label: { Text(song.text) } } } } } } .onDelete { indexSet in indexSet.forEach { index in let song = songs[index] modelContext.delete(song) } } Section(header: Text("Without Genre")) { ForEach (songs){song in if let songGenres = song.genres { if songGenres.isEmpty{ NavigationLink { SongView(song: song) } label: { Text(song.text) } } } } .onDelete { indexSet in indexSet.forEach { index in let song = songs[index] modelContext.delete(song) } } } } } .scrollContentBackground(.hidden) } } } On iOS 17, creating a new song adds it directly to the list in the Without Genre section. On iOS 18, it takes around 30 seconds to be added. I did a video, and I have a demo project to illustrate if necessary. Thanks a lot for any hint, advice !
1
0
563
Oct ’24
Cannot add participants to CoreData to share between multiple users
I have been trying to get this to work since it was announced a few years ago but with no joy. I'm struggling to get Apple's example code to behave itself too. Seems overly complex and buggy. So I set out to create a simplified version myself. I have got the database to sync with CloudKit and I can see my records in the developer dashboard. I'm trying to use container.record(for: object.objectID) to get the CKRecord for it, but this always fails. The next step would be to add the participant. I try to add the participant based on this code: Button { let record = fetchRecord(for: items[0]) //hack just to use the first record for dev testing let share = CKShare(rootRecord: record) let persistenceController = PersistenceController.shared persistenceController.addParticipant( emailAddress: "andrew@ambrit.com", permission: .readWrite, share: share) { share, error in if let error = error { print("Error: \(error.localizedDescription)") } else if let share = share { print("Share updated successfully: \(share)") } } } label: { Label("Participants", systemImage: "person") } and extension PersistenceController { func addParticipant(emailAddress: String, permission: CKShare.ParticipantPermission = .readWrite, share: CKShare, completionHandler: ((_ share: CKShare?, _ error: Error?) -> Void)?) { let container = PersistenceController.shared.container let lookupInfo = CKUserIdentity.LookupInfo(emailAddress: emailAddress) let persistentStore = privatePersistentStore //share.persistentStore! container.fetchParticipants(matching: [lookupInfo], into: persistentStore) { (results, error) in guard let participants = results, let participant = participants.first, error == nil else { completionHandler?(share, error) return } participant.permission = permission participant.role = .privateUser share.addParticipant(participant) container.persistUpdatedShare(share, in: persistentStore) { (share, error) in if let error = error { print("\(#function): Failed to persist updated share: \(error)") } completionHandler?(share, error) } } } } My immediate problem is that when I call fetchRecord it doesn't find anything despite the record being available in the CloudKit dashboard. func fetchRecord(for object: NSManagedObject) -> CKRecord { let container = PersistenceController.shared.container print ("Fetching record \(object.objectID)") if let record = container.record(for: object.objectID) { print("CKRecord ID: \(record.recordID)") print("Record Name: \(record.recordID.recordName)") return record } else { fatalError("Record not found") } }
1
0
793
Jan ’25
Schema Migrations with CloudKit Not Working
I have not had any successful Schema Migration with CloudKit so far so I'm trying to do with with just very basic attributes, with multiple Versioned Schemas This is the code in my App Main var sharedModelContainer: ModelContainer = { let schema = Schema(versionedSchema: AppSchemaV4.self) do { return try ModelContainer( for: schema, migrationPlan: AppMigrationPlan.self, configurations: ModelConfiguration(cloudKitDatabase: .automatic)) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ItemListView() } .modelContainer(sharedModelContainer) } And this is the code for my MigrationPlan and VersionedSchemas. typealias Item = AppSchemaV4.Item3 enum AppMigrationPlan: SchemaMigrationPlan { static var schemas: [any VersionedSchema.Type] { [AppSchemaV1.self, AppSchemaV2.self, AppSchemaV3.self, AppSchemaV4.self] } static var stages: [MigrationStage] { [migrateV1toV2, migrateV2toV3, migrateV3toV4] } static let migrateV1toV2 = MigrationStage.lightweight( fromVersion: AppSchemaV1.self, toVersion: AppSchemaV2.self ) static let migrateV2toV3 = MigrationStage.lightweight( fromVersion: AppSchemaV2.self, toVersion: AppSchemaV3.self ) static let migrateV3toV4 = MigrationStage.custom( fromVersion: AppSchemaV3.self, toVersion: AppSchemaV4.self, willMigrate: nil, didMigrate: { context in // Fetch all Item1 instances let item1Descriptor = FetchDescriptor<AppSchemaV3.Item1>() let items1 = try context.fetch(item1Descriptor) // Fetch all Item2 instances let item2Descriptor = FetchDescriptor<AppSchemaV3.Item2>() let items2 = try context.fetch(item2Descriptor) // Convert Item1 to Item3 for item in items1 { let newItem = AppSchemaV4.Item3(name: item.name, text: "Migrated from Item1 on \(item.date)") context.insert(newItem) } // Convert Item2 to Item3 for item in items2 { let newItem = AppSchemaV4.Item3(name: item.name, text: "Migrated from Item2 with value \(item.value)") context.insert(newItem) } try? context.save() } ) } enum AppSchemaV1: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(1, 0, 0) static var models: [any PersistentModel.Type] { [Item1.self] } @Model class Item1 { var name: String = "" init(name: String) { self.name = name } } } enum AppSchemaV2: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(2, 0, 0) static var models: [any PersistentModel.Type] { [Item1.self] } @Model class Item1 { var name: String = "" var date: Date = Date() init(name: String) { self.name = name self.date = Date() } } } enum AppSchemaV3: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(3, 0, 0) static var models: [any PersistentModel.Type] { [Item1.self, Item2.self] } @Model class Item1 { var name: String = "" var date: Date = Date() init(name: String) { self.name = name self.date = Date() } } @Model class Item2 { var name: String = "" var value: Int = 0 init(name: String, value: Int) { self.name = name self.value = value } } } enum AppSchemaV4: VersionedSchema { static var versionIdentifier: Schema.Version = Schema.Version(4, 0, 0) static var models: [any PersistentModel.Type] { [Item1.self, Item2.self, Item3.self] } @Model class Item1 { var name: String = "" var date: Date = Date() init(name: String) { self.name = name self.date = Date() } } @Model class Item2 { var name: String = "" var value: Int = 0 init(name: String, value: Int) { self.name = name self.value = value } } @Model class Item3 { var name: String = "" var text: String = "" init(name: String, text: String) { self.name = name self.text = text } } } My experiment was: To create Items for every version of the schema Updating the typealias along the way to reflect the latest Item version. Updating the Schema in my ModelContainer to reflect the latest Schema Version. By AppSchemaV4, I have expected all my Items to be displayed/migrated to Item3, but it does not seem to be the case. I can only see newly created Item3 records. My question is, is there something wrong with how I'm doing the migrations? or are migrations not really working with CloudKit right now?
1
0
372
Mar ’25
CKSyncEngine: Duplicate FetchedRecordZoneChanges & Sync Handling Questions
Hi everyone, I've recently implemented CKSyncEngine in my app, and I have two questions regarding its behavior: Duplicate FetchedRecordZoneChanges After Sending Changes: I’ve noticed that the engine sometimes receives a FetchedRecordZoneChanges event containing modifications and deletions that were just sent by the same device a few moments earlier. This event arrives after the SentRecordZoneChanges event, and both events share the same recordChangeTag, which results in double-handling the record. Is this expected behavior? I’d like to confirm if this is how CKSyncEngine works or if I might be overlooking something. Handling Initial Sync with a "Sync Screen": When a user opens the app for the first time and already has data stored in iCloud, I need to display a "Sync Screen" temporarily to prevent showing partial data or triggering abrupt, rapid UI changes. I’ve found that canceling current operations, then awaiting sendChanges() and fetchChanges() works well to ensure data is fully synced before dismissing the sync screen: displaySyncScreen = true await syncEngine.cancelOperations() try await syncEngine.sendChanges() try await syncEngine.fetchChanges() displaySyncScreen = false However, I’m unsure if canceling operations like this could lead to data loss or other issues. Is this a safe approach, or would you recommend a better strategy for handling this initial sync state?
1
0
605
Feb ’25
Import sqlite database to SwiftData
Hello, I recently switched my app from flutter which was using sqlite3 database. I would like to migrate my existing users to SwiftData. The issue is I do not know where to start in finding the database for the current users, reading the data and inserting into the SwiftData schema. I tried searching but not clear on how to proceed. Any help pointing in the right direction would be great. Thanks.
1
0
414
Nov ’24
Invalid bundle ID for container
I'm trying to get the CoreDataCloudKitShare example to work, but having trouble. The first error I see when running the InitializeCloudKitSchema target (on macOS) is the following: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1242): <NSCloudKitMirroringDelegate: 0x60000229c0f0>: Failed to set up CloudKit integration for store: <NSSQLCore: 0x15b807830> (URL: file:///Users/rmann/Library/Application%20Support/InitializeCloudKitSchema/CoreDataStores/Private/private.sqlite) <CKError 0x600001311290: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = 3E1B1380-AE1C-4B14-97A8-7F60B4A8F3EF; container ID = "iCloud.com.example.CoreDataCloudKitShareH6F2W964VK"; partial errors: { com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x60000132f810: "Permission Failure" (10/2007); server message = "Invalid bundle ID for container"; op = F3987848B25CEED7; uuid = 3E1B1380-AE1C-4B14-97A8-7F60B4A8F3EF> }> I see a database in the Dashboard with that container ID, but don't know what it means by "Invalid bundle ID for container". I've seen several other posts about this across the web, and the only answer is ever "seems to be an Apple issue, wait a bit."
1
0
996
Oct ’24
iCloud sync issues using NSPersistentCloudKitContainer for Core Data + CloudKit sync.
I have tried to set up iCloud sync. Despite fully isolating and resetting my development environment, the app fails with: NSCocoaErrorDomain Code=134060 (PersistentStoreIncompatibleVersionHashError) What I’ve done: Created a brand new CloudKit container Created a new bundle ID and app target Renamed the Core Data model file itself Set a new model version Used a new .sqlite store path Created a new .entitlements file with the correct container ID Verified that the CloudKit dashboard shows no records Deleted and reinstalled the app on a real device Also tested with “Automatically manage signing” and without Despite this, the error persists. I am very inexperienced and am not sure what my next step is to even attempt to fix this. Any guidance is apprecitated.
1
0
139
Jun ’25
Undo in SwiftData deletes all data at once.
When the following models in SwiftData, @Model final class UndoRedoData { var id: [Int] init(id: [Int]) { self.id = id } } I created the following code. struct ContentView: View { @ObservedObject var swiftDataViewModel = SwiftDataArrayViewModel.shared @State private var idArray: [Int] = [1,2,3,4] @State private var firstviewSwich: Bool = true @State private var twoviewSwich: Bool = false @State private var threeviewSwich: Bool = false var body: some View { VStack { if firstviewSwich == true { Button(action: addItem) { Text("1.New Item") } } if twoviewSwich == true { Button { forArrayData() } label: { Text("2.Data Road") } } if threeviewSwich == true { Button(action: undoItem) { Text("3.Undo") } } } } private func addItem() { withAnimation { let newItem = UndoRedoData(id: [1,2,3,4]) swiftDataViewModel.taskContext.insert(newItem) do { try swiftDataViewModel.taskContext.save() } catch { print(error) } swiftDataViewModel.fetchItems() firstviewSwich.toggle() twoviewSwich.toggle() } } private func forArrayData() { twoviewSwich.toggle() for data in idArray { swiftDataViewModel.idUndoCreate(id: data, undoManager: swiftDataViewModel.arrayItemUndoManager) } threeviewSwich.toggle() } private func undoItem() { swiftDataViewModel.arrayItemUndoManager.undo() threeviewSwich.toggle() firstviewSwich.toggle() } } class SwiftDataArrayViewModel: ObservableObject { static let shared = SwiftDataArrayViewModel() let modelContainer: ModelContainer @ObservationIgnored lazy var taskContext: ModelContext = { return ModelContext(modelContainer) }() @Published var arrayItems = [UndoRedoData]() @Published var arrayItemUndoManager = UndoManager() init() { let schema = Schema([UndoRedoData.self]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { modelContainer = try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError(error) } fetchItems() } func fetchItems() { let fetchDescriptor = FetchDescriptor<UndoRedoData>() do { arrayItems = try taskContext.fetch(fetchDescriptor) } catch { fatalError(error) } } func idUndoCreate(id: Int, undoManager: UndoManager?) { undoManager?.registerUndo(withTarget: self) { target in target.removeID() } } func removeID() { if let firstUndoRedoData = arrayItems.first { print("Before Delete:\(firstUndoRedoData.id)") if !firstUndoRedoData.id.isEmpty { firstUndoRedoData.id.removeLast() } print("After Delete:\(firstUndoRedoData.id)") } do { try taskContext.save() } catch { print(error) } fetchItems() } } In this code, 1. Create an Item in New Item, 2. Execute Data Road and register the data in the array that is the same value as the data created in New Item in SwiftData one by one in UndoManager by for data in idArray. This is done because the data in the array and the data created by New Item in SwiftData can be known in advance. private func forArrayData() { twoviewSwich.toggle() for data in idArray { swiftDataViewModel.idUndoCreate(id: data, undoManager: swiftDataViewModel.arrayItemUndoManager) } // class SwiftDataArrayViewModel: ObservableObject func idUndoCreate(id: Int, undoManager: UndoManager?) { undoManager?.registerUndo(withTarget: self) { target in target.removeID() } } After registering in UndoManager, when Undo is executed with 3. Undo, instead of being able to perform Undo where one id is deleted each time, all the data of the id in SwiftData is deleted in a one-time Undo. I would like to be able to delete one id each time Undo is performed and restore them in sequence, but I can only delete them all once. Does this mean that such registration to UndoManager should not be done with for statements, etc.? Or is there another problem in the code? I want to make sure that one id is deleted for each Undo executed.
1
0
778
Dec ’24
macOS SwiftData app never syncs with CloudKit
I'm using SwiftData with CloutKit with a very simple app. Data syncs between iOS, iPadOS, and visionOS, but not macOS. From what I can tell, macOS is never getting CK messages unless I'm running the app from Xcode. I can listen for the CK messages and show a line in a debug overlay. This works perfectly when I run from Xcode. I can see the notifications and see updates in my app. However, if I just launch the app outside of Xcode I will never see any changes or notifications. It is as if the Mac app never even tries to contact CloudKit. Schema has been deployed in the CloudKit console. The app is based on the multi-platform Xcode template. Again, only the macOS version has this issue. Is there some extra permission or setting I need to set up in order to use CloudKit on macOS? @State private var publisher = NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification).receive(on: DispatchQueue.main) .onReceive(publisher) { notification in // Listen for changes in CK events if let userInfo = notification.userInfo, let event = userInfo[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event { let message = "CloudKit Sync: \(event.type.rawValue) - \(event.succeeded ? "Success" : "Failed") - \(event.description)" // Store for UI display syncNotifications.append(message) if syncNotifications.count > 10 { syncNotifications.removeFirst() } } } .overlay(alignment: .topTrailing) { if !syncNotifications.isEmpty { VStack(alignment: .leading) { ForEach(syncNotifications, id: \.self) { notification in Text(notification) .padding(8) } } .frame(width: 800, height: 500) .cornerRadius(8) .background(Color.secondary.opacity(0.2)) .padding() .transition(.move(edge: .top)) } }
1
0
127
May ’25
What xattrs does iCloud maintain?
As of 2025-05-03, when a macOS user enables iCloud Drive synchronization for Desktop &amp; Documents in US region, does iCloud filter xattrs upon upload or later when downloading back to another macOS host? Or is it the case that iCloud has no filtering of third-party xattrs? Where can I find the technical document outlining exactly what iCloud does with xattrs set on macOS host files and folders synchronized with iCloud Drive?
1
0
89
May ’25
Warning in Xcode console: Couldn't read values in CFPrefsPlistSource
I have enabled an App Group in my App and the Widget Extension. I use it to share my UserDefaults. Every time the app starts I now get the following error message in the Xcode console: Couldn't read values in CFPrefsPlistSource<0x303034510> (Domain: group.XX.XXXX.XXXX, User: kCFPreferencesAnyUser, ByHost: Yes, Container: (null), Contents Need Refresh: Yes): Using kCFPreferencesAnyUser with a container is only allowed for System Containers, detaching from cfprefsd The shared UserDefaults itself works without problems. Any ideas how I could get rid of this warning?
1
1
3.1k
Oct ’24
Odd, transient .badContainer error in CloudKit
I'm beta-testing a CloudKit-based app. One of my testers suddenly reported that they got a .badContainer CloudKit error: <CKError 0x302619800:"Bad Container" (5/1014); server message = "Invalid container to get bundle ids"; op = <...>; uuid = <...>; container ID = "<...>"> (all private info replaced with <...>) The container ID in the message was exactly what I expected, and exactly what other users are successfully using. When I followed up on the report, the user said she tried again later and everything was fine. It's still working fine days later. What could cause a user to get a .badContainer message, when all other users using the same app are fine, the container ID makes sense, and future runs work fine? Is this something I need to worry about? Does it maybe sometimes happen when CloudKit is having some kind of outage?
1
0
644
Jan ’25
CKShare different targets
Hello, I`m working on an app that uses CloudKit and CKShare, but the app has 2 different targets, one for professional and one for patients, and theoretically the target of the professional sends the CKShare and the target of the patient should accept, but the ckshare tries to always open the target of the profissional, I would like to know if the are any way to configure the CKShare to oppen the target od the patients
1
1
378
Nov ’24
Default zone is not accessible in shared DB - cloudKit
I am trying to save to cloud kit shared database. The shared database does not allow zones to be set up. How do I save to sharedCloudDatabase without a zone? private func addItem(recordType: String, name: String) { let record = CKRecord(recordType: recordType) record[Constances.field.name] = name as CKRecordValue record[Constances.field.done] = false as CKRecordValue record[Constances.field.priority] = 0 as CKRecordValue CKContainer.default().sharedCloudDatabase.save(record) { [weak self] returnRecord, error in if let error = error { print("Error saving record: \(record[Constances.field.name] as? String ?? "No Name"): \n \(error)") return } } } The following error message prints out: Error saving record: Milk: &lt;CKError 0x15af87900: "Server Rejected Request" (15/2027); server message = "Default zone is not accessible in shared DB"; op = B085F7BA703D4A08; uuid = 87AEFB09-4386-4E43-81D7-971AAE8BA9E0; container ID = "iCloud.com.sfw-consulting.Family-List"&gt;
1
0
62
Jun ’25
defaultIsolation option and Core Data
When creating a new project in Xcode 26, the default for defaultIsolation is MainActor. Core Data creates classes for each entity using code gen, but now those classes are also internally marked as MainActor, which causes issues when accessing managed object from a background thread like this. Is there a way to fix this warning or should Xcode actually mark these auto generated classes as nonisolated to make this better? Filed as FB13840800. nonisolated struct BackgroundDataHandler { @concurrent func saveItem() async throws { let context = await PersistenceController.shared.container.newBackgroundContext() try await context.perform { let newGame = Item(context: context) newGame.timestamp = Date.now // Main actor-isolated property 'timestamp' can not be mutated from a nonisolated context; this is an error in the Swift 6 language mode try context.save() } } } Turning code gen off inside the model and creating it manually, with the nonisolated keyword, gets rid of the warning and still works fine. So I guess the auto generated class could adopt this as well? public import Foundation public import CoreData public typealias ItemCoreDataClassSet = NSSet @objc(Item) nonisolated public class Item: NSManagedObject { }
1
0
79
Jun ’25
CloudKit Server-to-Server Authentication Fails with 401 Error
I'm trying to set up server-to-server authentication with CloudKit Web Services, but keep getting AUTHENTICATION_FAILED errors. I've tried multiple environment settings and debugging approaches without success. What I've Tried I created a Swift script to test the connection. Here's the key part that handles the authentication: // Get current ISO 8601 date let iso8601Formatter = ISO8601DateFormatter() iso8601Formatter.formatOptions = [.withInternetDateTime] let dateString = iso8601Formatter.string(from: Date()) // Create SHA-256 hash of request body let bodyHash = SHA256.hash(data: bodyData).compactMap { String(format: "%02x", $0) }.joined() // Get path from URL let path = request.url?.path ?? "/" // String to sign let method = request.httpMethod ?? "POST" let stringToSign = "\(method):\(path):\(dateString):\(bodyHash)" // Sign the string with EC private key let signature = try createSignature(stringToSign: stringToSign) // Add headers request.setValue(dateString, forHTTPHeaderField: "X-Apple-CloudKit-Request-ISO8601Date") request.setValue(KEY_ID, forHTTPHeaderField: "X-Apple-CloudKit-Request-KeyID") request.setValue(signature, forHTTPHeaderField: "X-Apple-CloudKit-Request-SignatureV1") } I've made a request to this endpoint: What's Happening I get a 401 status with this response: "uuid" : "173179e2-c5a5-4393-ab4f-3cec194edd1c", "serverErrorCode" : "AUTHENTICATION_FAILED", "reason" : "Authentication failed" } What I've Verified The key validates correctly and generates signatures The date/time is synchronized with the server The key ID matches what's in CloudKit Dashboard I've tried all three environments: development, Development (capital D), and production The container ID is formatted correctly Debug Information My debugging reveals: The EC key is properly formatted (SEC1 format) Signature generation works No time synchronization issues between client and server All environment tests return the same 401 error Questions Has anyone encountered similar issues with CloudKit server-to-server authentication? Are there specific container permissions needed for server-to-server keys? Could there be an issue with how the private key is formatted or processed? Are there any known issues with the CloudKit Web Services API that might cause this? Any help would be greatly appreciated!
1
0
98
Mar ’25
Unable to see data from a production environment
I am trying to test using Testflight and have set up a test with a user on an account I also own which is different to me developer account. The app I believe is running in production on a separate device and is working from a user point of view, however I am not able to query the data via the console. As I said I know the user id and password as tey are mine so even when I use the Act as user service it logs in but the query is empty. I'm assuming I'm not doing anything wrong its possibly an security issue that is preventing me accessing this account. My question to the group then is how do I verify the data that is being tested?
1
0
594
Feb ’25
How to "Keep on My iPhone" after disabling iCloud for my app using Core Data
I have Core Data setup with a NSPersistentCloudKitContainer as my container, I've added a container identifier and I see my data on CloudKit's database here when I use "Act As iCloud Account". Here's what I have under capabilities in Xcode However, on my device when I go to Settings > Apple Account > iCloud > Saved to iCloud and switch off my app, all the data saved to Core Data is removed. I suspected this working as intended. When I switch it back on, all the data comes back. However (x2), the support page here says it should remain on the device: When you turn it off, the app no longer connects with iCloud, so your data exists only on your device Am I missing something in how I integrated Core Data in Xcode? Do I need to explicitly configure something with Apple's SDK to get the behavior described in the support page? I've noticed for some of Apple's apps, when you switch off iCloud there's an action sheet asking what you'd like to do with the local data. I figured this was Apple's magic without sharing especially since the buttons looked different Stocks Safari Contacts However (x3), not all apps that had this option offered "Keep on My iPhone", so perhaps the supported behavior is to remove what's on the device and these Apple apps implemented their own support to keep a copy on the device. Reminders I've tried testing some 3rd-party apps but couldn't convince myself they were using Core Data with iCloud enabled. Instead, it looked like they were using iCloud as a backup
1
1
951
Nov ’24