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

SwiftData 0xdead10cc with cloudKitDatabase
I recently added SwiftData to my project in a limited capacity. I'm creating ModelConfiguration -> ModelContext directly in Swift code rather than in SwiftUI. I'm using an app group & a CloudKit database/container. The functionality all seems fine, but I'm dealing with random 0xdead10cc crashes from threads with CoreData/libsqlite3.dylib in the stack traces (particularly with widgets & complications which aren't actively writing anything), often with NSCloudKitMirroringDelegate.m also in the stack. I haven't seen any actual functionality issues, but the crashing is worrisome. I understand they're keeping files open to cause the 0xdead10cc, but my question is: Is there a clean way to shut down or force shut down SwiftData when using CloudKit? I've looked through example code on Apple's Developer site, but I can't seem to find anything about cleanup/shutdown best practices, though I may be missing something. Here's an example thread from a crash log: Thread 12: 0 libsystem_kernel.dylib 0x00000000258b4fe4 pread + 12 1 libsqlite3.dylib 0x0000000023ce7684 seekAndRead + 88 (sqlite3.c:44032) 2 libsqlite3.dylib 0x0000000023c5ffc4 unixRead + 200 (sqlite3.c:44124) 3 libsqlite3.dylib 0x0000000023c730fc readDbPage + 132 (sqlite3.c:66901) 4 libsqlite3.dylib 0x0000000023cf14e4 getPageNormal + 532 (sqlite3.c:69515) 5 libsqlite3.dylib 0x0000000023cfd684 getAndInitPage + 104 (sqlite3.c:79184) 6 libsqlite3.dylib 0x0000000023c8f99c moveToRoot + 532 (sqlite3.c:82309) 7 libsqlite3.dylib 0x0000000023cfa448 sqlite3BtreeTableMoveto + 168 (sqlite3.c:82547) 8 libsqlite3.dylib 0x0000000023c859fc sqlite3VdbeExec + 4996 (sqlite3.c:105391) 9 libsqlite3.dylib 0x0000000023c83da4 sqlite3_step + 976 (sqlite3.c:97868) 10 CoreData 0x00000000211c92d4 _execute + 128 (NSSQLiteConnection.m:4573) 11 CoreData 0x00000000211c5e74 -[NSSQLiteConnection execute] + 1784 (NSSQLiteConnection.m:5014) 12 CoreData 0x000000002121c3f8 -[NSSQLiteConnection insertRow:] + 1488 (NSSQLiteConnection.m:3608) 13 CoreData 0x00000000211ca160 _executeSaveChangesRequest + 1792 (NSSQLCore_Functions.m:2543) 14 CoreData 0x00000000211dc128 -[NSSQLSaveChangesRequestContext executeRequestCore:] + 28 (NSSQLSaveChangesRequestContext.m:263) 15 CoreData 0x00000000211fa424 -[NSSQLStoreRequestContext executeRequestUsingConnection:] + 220 (NSSQLStoreRequestContext.m:183) 16 CoreData 0x00000000211cce3c __52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke + 56 (NSSQLConnectionManager.m:302) 17 CoreData 0x00000000211c99d4 __37-[NSSQLiteConnection performAndWait:]_block_invoke + 40 (NSSQLiteConnection.m:733) 18 libdispatch.dylib 0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576) 19 libdispatch.dylib 0x0000000020b004d8 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104) 20 CoreData 0x00000000211c3d4c -[NSSQLiteConnection performAndWait:] + 140 (NSSQLiteConnection.m:730) 21 CoreData 0x000000002122fb3c -[NSSQLDefaultConnectionManager handleStoreRequest:] + 208 (NSSQLConnectionManager.m:297) 22 CoreData 0x00000000211bd16c -[NSSQLCoreDispatchManager routeStoreRequest:] + 216 (NSSQLCoreDispatchManager.m:60) 23 CoreData 0x00000000211bfb8c -[NSSQLCore dispatchRequest:withRetries:] + 168 (NSSQLCore.m:3999) 24 CoreData 0x00000000211c0480 -[NSSQLCore executeRequest:withContext:error:] + 2044 (NSSQLCore.m:2963) 25 CoreData 0x000000002134662c __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.387 + 8968 (NSPersistentStoreCoordinator.m:2967) 26 CoreData 0x00000000211c6190 -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 220 (NSPersistentStoreCoordinator.m:644) 27 CoreData 0x00000000211bf3fc -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1112 (NSPersistentStoreCoordinator.m:2779) 28 CoreData 0x00000000211d5468 -[NSManagedObjectContext save:] + 988 (NSManagedObjectContext.m:1624) 29 CoreData 0x0000000021296ba8 __52+[NSCKEvent beginEventForRequest:withMonitor:error:]_block_invoke_2 + 280 (NSCKEvent.m:76) 30 CoreData 0x00000000211d1024 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:3987) 31 libdispatch.dylib 0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576) 32 libdispatch.dylib 0x0000000020b004d8 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104) 33 CoreData 0x00000000211e3d8c -[NSManagedObjectContext performBlockAndWait:] + 256 (NSManagedObjectContext.m:4104) 34 CoreData 0x000000002129e14c __52+[NSCKEvent beginEventForRequest:withMonitor:error:]_block_invoke + 152 (NSCKEvent.m:66) 35 CoreData 0x00000000212231d0 -[PFCloudKitStoreMonitor performBlock:] + 84 (PFCloudKitStoreMonitor.m:148) 36 CoreData 0x0000000021284c28 +[NSCKEvent beginEventForRequest:withMonitor:error:] + 184 (NSCKEvent.m:61) 37 CoreData 0x000000002125fb80 __57-[NSCloudKitMirroringDelegate _performExportWithRequest:]_block_invoke + 256 (NSCloudKitMirroringDelegate.m:1435) 38 CoreData 0x0000000021209cb4 __92-[NSCloudKitMirroringDelegate _openTransactionWithLabel:assertionLabel:andExecuteWorkBlock:]_block_invoke + 64 (NSCloudKitMirroringDelegate.m:959) 39 libdispatch.dylib 0x0000000020af1288 _dispatch_call_block_and_release + 24 (init.c:1549) 40 libdispatch.dylib 0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576) 41 libdispatch.dylib 0x0000000020af96bc _dispatch_lane_serial_drain + 680 (queue.c:3934) 42 libdispatch.dylib 0x0000000020afa124 _dispatch_lane_invoke + 376 (queue.c:4025) 43 libdispatch.dylib 0x0000000020b03c40 _dispatch_root_queue_drain_deferred_wlh + 268 (queue.c:7193) 44 libdispatch.dylib 0x0000000020b034fc _dispatch_workloop_worker_thread + 516 (queue.c:6787) 45 libsystem_pthread.dylib 0x0000000025f9b7bc _pthread_wqthread + 280 (pthread.c:2696) 46 libsystem_pthread.dylib 0x0000000025f9b85c start_wqthread + 8 (:-1)
1
0
658
Aug ’24
"Internal Error" in CloudKit Dashboard
Hi, I'm getting an "Internal Error" in the CloudKit Dashboard for my user. This happens for the Private database across all of my apps, and in both Development and Production environments. (Screenshot attached). If I login as a different user via the 'Act as iCloud Account' function, everything works fine - it seems to be an issue with my own user account. In the JavaScript console, I see "Known response error: The request has failed due to an error.", but no other details (Screenshot attached) I can see these failures in the Logs tag, showing as 'INTERNAL_ERROR' (another Screenshot) It appears that the data on my account is currently not sync'ing to CloudKit, although I haven't found any other errors from within the app claiming that there is an issue (using the CoreData+CloudKit integration). I'm assuming my in-app errors and my dashboard errors are related, although it's difficult to say without more information on what these errors actually are.
5
0
1k
Aug ’24
CKModifyBadgeOperation is no longer working?
Whilst all current answers to this question indicate the depreciation of CKModifyBadgeOperation, all of them had advised up until 2022 that it could still be used due to Apple not having a replacement Api. Upon running the following code: badgeReset.modifyBadgeCompletionBlock = { (error) -> Void in if error != nil { print("Error resetting badge: \(error!)") } } CKContainer.default().add(badgeReset) When run I receive the following error: Error resetting badge: <CKError 0x3001ddf50: "Invalid Arguments" (12/1017); "CKModifyBadgeOperation is no longer supported"> And from testing following this, the badge count incrementation issue continues, indicating that this has been completely invalidated and cannot be used at all. Even with UNUserNotificationCenter.current().setBadgeCount(0) this only clears the badge count temporarily. I'm aware of the proposed "workaround" of creating an extension that manually keeps track of notification count & sets the badge accordingly when a notification is received. However I'm trying to ascertain if as of this current point in time there is now no way whatsoever to clear the badge count on the Cloudkit sever level?
3
0
689
Aug ’24
Swift Data + Swift 6 Sendable-ity paradox
Xcode 16 beta 3 Assume a SwiftData model starts like this and has a few more properties like a name and creation date (these are immaterial to my main question. @Model final class Batch: Identifiable, Sendable { @Attribute(.unique) var id: UUID //... more stuff The combination of Swift 6 (or Swift 5 with warnings enabled) and SwiftData seem to provide a paradox: Swift 6 complains when the id is a let: Cannot expand accessors on variable declared with 'let'; this is an error in the Swift 6 language mode Swift 6 complains when the id is a var: Stored property '_id' of 'Sendable'-conforming class 'Batch' is mutable; this is an error in the Swift 6 language mode Removing "Sendable" may be one solution but defeats the purpose and causes warnings elsewhere in the app about the model not being Sendable. Is there an obvious fix? Am I as a newbie (to the combination of Swift 6 and SwiftData) missing an entire architectural step of using ModelActor somewhere?
1
1
3.5k
Aug ’24
How to remove a single record from a CKShare?
It is possible to append a record to a CKShare using NSPersistentCloudKitContainer.share(objects, to: share) but how can I reverse this operation and remove the object from share? The workaround would be to delete and recreate the object, but is there any SDK function to do it right? The more I work with CoreData+CloudKit the more it seems like everything there is a workaround or hack or bug... This SDK is still in Alpha at best.
0
0
572
Aug ’24
How to properly share one CKREcord with CKShare in obj-c
When I trying to set share record I get: NSOperationQueue * quwuw = [[NSOperationQueue alloc] init]; [quwuw setMaxConcurrentOperationCount:1]; [self createOrFetchZone:^(CKRecordZone *rzone, NSError *error) { CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:recordId zoneID:custZone.zoneID]; [[self privateCloudDatabase] fetchRecordWithID:recordID completionHandler:^(CKRecord *record, NSError *error) { if (error) { dispatch_async(dispatch_get_main_queue(), ^{ prephandler(nil, nil,error); }); return; } CKShare * share = [[CKShare alloc] initWithRootRecord:record]; share[CKShareTitleKey] = @"Some title"; [share setPublicPermission:CKShareParticipantPermissionReadWrite]; CKModifyRecordsOperation * op = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:@[share, record] recordIDsToDelete:nil]; [op setModifyRecordsCompletionBlock:^(NSArray<CKRecord *> * _Nullable savedRecords, NSArray<CKRecordID *> * _Nullable deletedRecordIDs, NSError * _Nullable operationError) { if (operationError == nil) { dispatch_async(dispatch_get_main_queue(), ^{ prephandler(share, [CKContainer defaultContainer],operationError); }); } else { dispatch_async(dispatch_get_main_queue(), ^{ prephandler(share, [CKContainer defaultContainer],operationError); }); } }]; [op setDatabase:[self privateCloudDatabase]]; [quwuw addOperation:op]; }]; }]; I get error: Invalid Arguments" (12/2006); server message = "Chaining supported for hierarchical sharing only" Any advices for this?
0
0
388
Aug ’24
How to retrieve previously set title for a CKShare?
I create a CKShare and then I set the title: share[CKShare.SystemFieldKey.title] = title I even call: if let cloudStore = coreDatabase.cloudStore { try await persistentContainer.persistUpdatedShare(share, in: cloudStore) } but when I retrieve this share again using persistentContainer.fetchShares(matching: [id]) the title is not set. I even checked CloudKit console and I can't see there title either... How can I retrieve the previously set title for a share?
1
0
665
Aug ’24
Simple SwiftData app exhibits excessive & persistent memory growth as items are added
[Submitted as FB14860454, but posting here since I rarely get responses in Feedback Assistant] In a simple SwiftData app that adds items to a list, memory usage drastically increases as items are added. After a few hundred items, the UI lags and becomes unusable. In comparison, a similar app built with CoreData shows only a slight memory increase in the same scenario and does NOT lag, even past 1,000 items. In the SwiftData version, as each batch is added, memory spikes the same amount…or even increases! In the CoreData version, the increase with each batch gets smaller and smaller, so the memory curve levels off. My Question Are there any ways to improve the performance of adding items in SwiftData, or is it just not ready for prime time? Example Projects Here are the test projects on GitHub if you want to check it out yourself: PerfSwiftData PerfCoreData
2
0
843
Aug ’24
Using core data in ShieldConfigurationExtension
Hi there, In short, I'm trying to use CoreData in my ShieldConfigurationDataSource extension. Trying to fetch from core data at all seems to cause the shield to render it's default look. I already added the extension to an app group + configured my persistence store to use the app group. Below is my code, any help is appreciated: // Shield extension override func configuration(shielding application: Application) -> ShieldConfiguration { do { let appSelectionId = "XXX" let blockedItemReq = ... blockedItemReq.predicate = ... let moc = PersistenceController.shared.container.viewContext // Commenting this and the bottom out makes it work, but I need the data! let blockedItemRes = try moc.fetch(blockedItemReq) let shieldTitle = ShieldConfiguration.Label(text: "Hello there", color: .red) return ShieldConfiguration(backgroundColor: .black, title: shieldTitle) } catch { let shieldTitle = ShieldConfiguration.Label(text: "ERROR \(error.localizedDescription)", color: .white) return ShieldConfiguration(backgroundColor: .black, title: shieldTitle) } } // Persistence Controller init(inMemory: Bool = false) { container = NSPersistentContainer(name: "AppBlockerOne") if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } else { let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.appblockerone")! let storeURL = containerURL.appendingPathComponent("AppBlockerOne.sqlite") let description = NSPersistentStoreDescription(url: storeURL) container.persistentStoreDescriptions = [description] } container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) container.viewContext.automaticallyMergesChangesFromParent = true }
2
0
652
Aug ’24
Custom AttributedString and SwiftData
The central feature of my app requires the use of AttributedStrings with multiple custom attributes to store data about various functions related to parts of them. These AttributedString and other data also need to be persisted in SwiftData. Regarding how to do this, I spoke with an Apple engineer during WWDC24, and he said this was possible with the use of a ValueTransformer. After looking into this, I decided upon this scheme (forward direction shown here): Transform the AttributedString (with its custom attributes) into JSON data and have this interpreted as NSData, which SwiftData can persist. The value transformer seems to transform the AttributedString to NSData and back without any problems. But any attempts to use this transformer with SwiftData crashes the app. Your prompt solution to this problem would be greatly appreciated.
5
3
1.7k
Aug ’24
Can't accept CloudKit share invitation from my SwiftUI application
I am able to send invitation from my device to friend's device. When friend clicks on invitation that was shared through text messages it says: Open "Resources"? User X wants to collaborate. You'll join as User Y (user Y @iCloud.com). |Not Now| |Open| If friend clicks on |Open| then nothing happens. Share remains in "invited" state and the callbacks which I expected to be called are not. The official Apple CloudKit Sharing App - https://github.com/apple/sample-cloudkit-sharing/blob/main/Sharing/App/AppDelegate.swift - is confusing me because it does not have following code like typical SwiftUI app: @main struct MainApp: App { Instead it uses @main for AppDelegate. Here is my code with prints that encode what is going on: class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { print("I see this getting called on App startup") return true } func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { print("I also see this getting called on App startup") return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { print("I don't see this getting called") } func application(userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) -> Bool { print("However, I expected this to be called when friend opened his CloudKit share invitation") return false } } @main struct MainApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate static let sharedModelActor: ModelActorDatabase = { let schema = Schema([ Resource.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .none) do { let modelContainer = try ModelContainer(for: schema, configurations: [modelConfiguration]) return ModelActorDatabase(modelContainer: modelContainer) } catch { fatalError("Could not create ModelContainer: \(error)") } }() @StateObject var syncedDatabase: SyncedDatabase = SyncedDatabase(modelContainer: Self.sharedModelActor.modelContainer) var body: some Scene { WindowGroup { ResourceView() .environmentObject(syncedDatabase) } .modelContainer( Self.sharedModelActor.modelContainer ) .database(SharedDatabase.shared.database) } } I was expecting that this would call userDidAcceptCloudKitShareWith, but it is not. Why?
1
0
615
Aug ’24
SwiftData @ModelActor Memory usage skyrocketing when changing properties
When changing a property of a SwiftData Model from a ModelActor the memory needed slightly increases. Once you do that more often, you can see that the usage is linearly increasing. I modified the Swiftdata template as little as possible. This is the least code I need to reproduce the problem: Changes In the @main struct : ContentView(modelContainer: sharedModelContainer) ContentView: struct ContentView: View { @Query private var items: [Item] let dataHanndler: DataHandler @State var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: { t in }) var body: some View { NavigationSplitView { List { ForEach(items) { item in NavigationLink { Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") } label: { Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) } } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } ToolbarItem { Button { timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { t in Task { await dataHanndler.updateRandom() // Obviously this makes little sense but I need to update a lot of entities in my actual app. This is the simplest way to demonstrate that. updateRandom() could also be a function of a view but that doesn't make a difference } } } label: { Label("Do a lot of writing", systemImage: "gauge.with.dots.needle.100percent") } } ToolbarItem { Button { timer.invalidate() } label: { Label("Invalidate", systemImage: "stop.circle") } } } } detail: { Text("Select an item") } } private func addItem() { Task { await dataHanndler.insert(timestamp: Date.now) } } init(modelContainer: ModelContainer) { self.dataHanndler = DataHandler(modelContainer: modelContainer) } } ModelActor: @ModelActor actor DataHandler { public func update<T>(_ persistentIdentifier: PersistentIdentifier, keypath: ReferenceWritableKeyPath<Item, T>, to value: T) throws { let model = modelContext.model(for: persistentIdentifier) as! Item model[keyPath: keypath] = value } public func insert(timestamp: Date) { let item = Item(timestamp: timestamp) modelContext.insert(item) } public func updateRandom() { let count = try! modelContext.fetchCount(FetchDescriptor<Item>()) var descriptor = FetchDescriptor<Item>() descriptor.fetchOffset = Int.random(in: 0..<count) descriptor.fetchLimit = 1 let model = try! modelContext.fetch(descriptor) model.first!.timestamp = Date.now } } I filed a bug report FB14876920 but I am looking for other ideas to solve this before it will be fixed in a future update. The modelContext I use is created and managed by the @ModelActor macro. Happy to hear ideas
2
0
683
Aug ’24
Able to read from CloudKit shared database, but not write.
User A shares zone with User B (influenced from https://github.com/apple/sample-cloudkit-zonesharing, but I have just one zone "Contacts" that I am sharing): private func shareConfiguration() async throws -> (CKShare, CKContainer) { let container = CKContainer(identifier: "iCloud.com.XXX.syncer") let database = container.privateCloudDatabase let zone = CKRecordZone(zoneName: "Contacts") let fetchedZone = try await database.recordZone(for: zone.zoneID) guard let existingShare = fetchedZone.share else { print("Does not have existing share") let share = CKShare(recordZoneID: zone.zoneID) share[CKShare.SystemFieldKey.title] = "Resources" _ = try await database.modifyRecords(saving: [share], deleting: []) return (share, container) } print("Has existing share") guard let share = try await database.record(for: existingShare.recordID) as? CKShare else { throw NSError(domain: "", code: 0, userInfo: nil) } return (share, container) } ... let (share,container) = try! await shareConfiguration() shareView = CloudSharingView(container: container, share: share) // UIViewControllerRepresentable implementation User B accepts share invitation (borrowed from https://github.com/apple/sample-cloudkit-zonesharing) class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) { guard cloudKitShareMetadata.containerIdentifier == "iCloud.com.XXX.syncer" else { print("Shared container identifier \(cloudKitShareMetadata.containerIdentifier) did not match known identifier.") return } // Create an operation to accept the share, running in the app's CKContainer. let container = CKContainer(identifier: "iCloud.com.XXX.syncer") let operation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata]) debugPrint("Accepting CloudKit Share with metadata: \(cloudKitShareMetadata)") operation.perShareResultBlock = { metadata, result in let shareRecordType = metadata.share.recordType switch result { case .failure(let error): debugPrint("Error accepting share: \(error)") case .success: debugPrint("Accepted CloudKit share with type: \(shareRecordType)") } } operation.acceptSharesResultBlock = { result in if case .failure(let error) = result { debugPrint("Error accepting CloudKit Share: \(error)") } } operation.qualityOfService = .utility container.add(operation) } } User B through CKSyncEngine is able to read all records. However, when User B tries to write to database through CKSyncEngine, User B on his device gets following error: <CKSyncEngine 0x1282a1400> error fetching changes with context <FetchChangesContext reason=scheduled options=<FetchChangesOptions scope=all group=CKSyncEngine-FetchChanges-Automatic)>>: Error Domain=CKErrorDomain Code=2 "Failed to fetch record zone changes" UserInfo={NSLocalizedDescription=Failed to fetch record zone changes, CKPartialErrors={ "<CKRecordZoneID: 0x3024872a0; zoneName=Contacts, ownerName=_18fb98f978ce4e9c207daaa142be6024>" = "<CKError 0x30249ed60: \"Zone Not Found\" (26/2036); server message = \"Zone does not exist\"; op = DC9089522F9968CE; uuid = 4B3432A4-D28C-457A-90C5-129B24D258C0; container ID = \"iCloud.com.XXX.syncer\">"; }} Also, in CloudKit console, if I go to Zones, I don't see any zones under Shared Database. Wasn't I supposed to see my zone here? However, I see "Contacts" zone under Private Database. If I expand Zone details I see following: Zone wide sharing is enabled. All records in this zone are being shared with the sharing participants below. And under Participants I see both User A and User B. User B is marked as: Permission READ_WRITE Type USER Acceptance INVITED What puzzles me is why READ works, but not WRITE?
1
1
504
Aug ’24
CKSyncEngine with dependent CKRecords
Hi, when using CKSynEgine it is the responsibility of the app to implement CKSyncEngineDelegate. One of the methods of CKSyncEngineDelegate is nextFetchChangesOptions. The implementation of this method should return a batch of CKRecords so that CKSyncEngine can do the syncing whenever it thinks it should sync. A simple implementation might look like this: func nextRecordZoneChangeBatch( _ context: CKSyncEngine.SendChangesContext, syncEngine: CKSyncEngine) async -> CKSyncEngine.RecordZoneChangeBatch?{ await CKSyncEngine.RecordZoneChangeBatch(pendingChanges: syncEngine.state.pendingRecordZoneChanges) { recordID in // here we should fetch to local representation of the value and map it to a CKRecord } } The problem I am having is as follows: If the CKRecords I am returning in a batch have dependencies between each other (using CKRecord.Reference or the parent property) but are not part of the same batch, the operation could fail. And as far as I understand, there is no way to prevent this situation because: A: The batch I can return is limited in size. If the number of CKRecords is too large, I have to split them into multiple batches. B: Splitting them is arbitrary, since I only have the recordID at this point, and there is no way to know about the dependencies between them just by looking at the recordID. So basically my question is: how should the implementation of nextRecordZoneChangeBatch look like to handle dependencies between CKRecords?
4
0
1.1k
Aug ’24
error: the replacement path doesn't exist:
I'm using SwiftData with an @Model and am also using an @ModelActor. I've fixed all concurrency issues and have migrated to Swift 6. I am getting a console error that I do not understand how to clear. I get this error in Swift 6 and Swift 5. I do not experience any issue with the app. It seems to be working well. But I want to try to get all issues taken care of. I am using the latest Xcode beta. error: the replacement path doesn't exist: "/var/folders/1q/6jw9d6mn0gx1znh1n19z2v9r0000gp/T/swift-generated-sources/@_swiftmacro_17MyAppName14MyModelC4type18_PersistedPr> opertyfMa.swift"
27
13
11k
Aug ’24