iCloud & Data

RSS for tag

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

CloudKit Documentation

Post

Replies

Boosts

Views

Activity

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
369
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
295
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
1
548
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 = "***" 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
304
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
308
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
250
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
258
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
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
436
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.
4
0
401
Aug ’24
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
282
Aug ’24
Swiftdata using an existing CloudKit container, how to listen to the NSPersistentCloudKitContainer's NSPersistentStoreRemoteChange event
My app uses SwiftData and CloudKit to store and synchronize data. This works nice. in some scenarios, I need to listen to NSPersistentStoreRemoteChange event to deduplicate data. In SwiftData, how do I get the persistentStoreCoordinator of the corresponding SwiftData ModelContainer? Or are there other APIs to achieve the same purpose? There is no relevant content in the developer documentation. In addition, in wwdc 24, there is a new API to track history (https://developer.apple.com/cn/videos/play/wwdc2024/10075/). But there is no mention of how to listen to remote data change events either.
1
0
426
Aug ’24
ModelContainer fails to create in ios18 beta
I get this error : ModelContainer creation failed: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer, _explanation: nil) AbsGod/AbsGodApp.swift:25: Fatal error: Failed to create ModelContainer: The operation couldn’t be completed. (SwiftData.SwiftDataError error 1.) when doing: struct MyAppApp: App { let container: ModelContainer init() { do { let schema = Schema([ Workout.self, Exercise.self ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) container = try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { print("ModelContainer creation failed: \(error)") fatalError("Failed to create ModelContainer: \(error.localizedDescription)") } } var body: some Scene { WindowGroup { TabBarView() .tint(.red) } .modelContainer(for: [Workout.self, Exercise.self]) } And I have no clue of how to resolve that. I saw similar issues with CloudKit, but I don't even have enabled it, just ticked Automatically manage signing in Signing & Capabilities of my project. the relationship of my classes are defined like this, in a workout class having an array of exercises: @Relationship(deleteRule: .cascade, inverse: \Exercise.workout) var exercises: [Exercise]? = [] and the inverse in the exercise class: var workout: Workout? I don't feel like the problem is coming from my classes, because when I try to reproduce the error on simpler project, everything works. it just won't create a modelContainder in my project and I have no idea what can makes that and the error is not really explicit...
1
0
378
Aug ’24
Managing Duplicate Objects in Core Data (or SwiftData) with CloudKit Sync When Devices were Offline during object creation
Suppose I have two iPhones that are offline. On the first iPhone, at 1 PM, I create a Person object with the details: name: "John", lastName: "Smith", and age: 40. Then, on the second iPhone, which is also offline, I also create Person object at 2 PM with the same name: "John" and lastName: "Smith", but with a different age: 30. Both iPhones come online at 3 PM and sync with CloudKit. I would expect CloudKit to reconcile these two records and end up with a single record—specifically, Person(name: "John", lastName: "Smith", age: 30), assuming a "last writer wins" approach. Any guidance or best practices for handling this situation would be greatly appreciated! My idea is that I could generate a 128bit UUID as hash from first name and last name and then I would have to force this UUID to be used as recordName in CKRecord as this would trigger a conflict on CloudKit side and prevent two instance to be created. But how do I accomplish this with SwiftData or CoreData?
3
0
672
Aug ’24
SwiftData unversioned migration
Hi, I'm struggling with SwiftData and the components for migration and could really use some guidance. My specific questions are Is it possible to go from an unversioned schema to a versioned schema? Do all @Model classes need to be converted? Is there one VersionedSchema for the entire app that handles all models or one VersionedSchema per model? What is the relationship, if any, between the models given to ModelContainer in a [Schema] and the models in the VersionedSchema in a [any PersistentModel.Type] I have an app in the AppStore. I use SwiftData and have four @Models defined. I was not aware of VersionedSchema when I started, so they are unversioned. I want to update the model and am trying to convert to a VersionedSchema. I've tried various things and can't even get into the migration plan yet. All posts and tutorials that I've come across only deal with one Model, and create a VersionedSchema for that model. I've tried to switch the one Model I want to update, as well as switching them all. Of course I get different errors depending on what configuration I try. It seems like I should have one VersionedSchema for the app since there is the static var models: [any PersistentModel.Type] property. Yet the tutorials I've seen create a TypeNameSchemaV1 to go with the @Model TypeName. Which is correct? An AppNameSchemaV1 which defines four models, or four TypeNameSchemaV1? Any help will be much appreciated
12
1
1.1k
Aug ’24
ModelContext autosaveEnabled leading to crashes when SwiftUI App moves to background?
Hi! I'm investigating some crashes that seem to be related to ModelContext.autosaveEnabled^1. I don't have a very clean repro test case at this time… but I seem to be seeing crashes when a SwiftUI app moves to the background. I am testing an app built for macOS 14.6.1. I am building from Xcode_16_beta_5. My app is not using a mainContext. My app is building a ModelActor that is running on a background thread (off main). The modelContext inside my ModelActor is set with autosaveEnabled equal to true. The mutations on my state are not being explicitly saved (I am waiting for the system to save automatically). My guess (so far) is that transitioning into the background from SwiftUI is kicking off some kind of logic that is specifically being tied to the main thread… but this is causing problems when my modelContext is created from a background thread. My understanding was that ModelActor could help to defend against threading problems… but this might be a different problem that I did not expect. I am unblocked for now by turning off autosaveEnabled (and manually saving from my ModelActor). That fixes the crashes. Any more thoughts or insight about what could be causing these crashes when my app transitions into the background? Thanks! Thread 1 Queue : com.apple.main-thread (serial) #0 0x000000023108beb8 in ___lldb_unnamed_symbol2827 () #1 0x000000023108ef30 in ___lldb_unnamed_symbol2847 () #2 0x000000023108eca8 in ___lldb_unnamed_symbol2845 () #3 0x000000019bac6144 in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ () #4 0x000000019bb5a3d8 in ___CFXRegistrationPost_block_invoke () #5 0x000000019bb5a320 in _CFXRegistrationPost () #6 0x000000019ba94678 in _CFXNotificationPost () #7 0x000000019cbb12c4 in -[NSNotificationCenter postNotificationName:object:userInfo:] () #8 0x000000019f489408 in -[NSApplication _handleDeactivateEvent:] () #9 0x000000019fb24380 in -[NSApplication(NSEventRouting) sendEvent:] () #10 0x000000019f771d9c in -[NSApplication _handleEvent:] () #11 0x000000019f322020 in -[NSApplication run] () #12 0x000000019f2f9240 in NSApplicationMain () #13 0x00000001c74c73b8 in ___lldb_unnamed_symbol83060 () #14 0x00000001c7c30ddc in ___lldb_unnamed_symbol132917 () #15 0x00000001c802be0c in static SwiftUI.App.main() -> () () Thread 5 Queue : NSManagedObjectContext 0x6000009c38e0 (serial) #0 0x000000019ba66f94 in constructBuffers () #1 0x000000019ba65e30 in _CFURLCreateWithURLString () #2 0x000000019bad6e7c in _CFURLComponentsCopyURLRelativeToURL () #3 0x000000019cbde864 in -[__NSConcreteURLComponents URL] () #4 0x000000019d3782f8 in -[NSURL(NSURL) initWithString:relativeToURL:encodingInvalidCharacters:] () #5 0x000000019cbdd4d4 in +[NSURL(NSURL) URLWithString:relativeToURL:] () #6 0x00000001a23feef0 in -[NSTemporaryObjectID URIRepresentation] () #7 0x00000002310e0878 in ___lldb_unnamed_symbol4176 () #8 0x00000002310ef480 in ___lldb_unnamed_symbol4401 () #9 0x00000002310eb6e0 in ___lldb_unnamed_symbol4385 () #10 0x00000002310a22b4 in ___lldb_unnamed_symbol3130 () #11 0x00000002310ed4e8 in ___lldb_unnamed_symbol4390 () #12 0x00000002310883dc in ___lldb_unnamed_symbol2799 () #13 0x0000000231087edc in ___lldb_unnamed_symbol2798 () #14 0x000000023109fd24 in ___lldb_unnamed_symbol3021 () #15 0x0000000231086acc in ___lldb_unnamed_symbol2784 () #16 0x00000001a2392144 in developerSubmittedBlockToNSManagedObjectContextPerform () #17 0x00000001a2392004 in -[NSManagedObjectContext performBlockAndWait:] () #18 0x00000002310879ac in ___lldb_unnamed_symbol2797 ()
1
0
250
Aug ’24