Post

Replies

Boosts

Views

Activity

SwiftData Fatal error: Editors must register their identifiers before invoking operations on this store
I have a UIKit app where I've adopted SwiftData and I'm struggling with a crash coming in from some of my users. I'm not able to reproduce it myself and as it only happens to a small fraction of my user base, it seems like a race condition of some sort. This is the assertion message: SwiftData/DefaultStore.swift:453: Fatal error: API Contract Violation: Editors must register their identifiers before invoking operations on this store SwiftData.DefaultStore: 00CF060A-291A-4E79-BEC3-E6A6B20F345E did not. (ID is unique per crash) This is the ModelActor that crashes: @available(iOS 17, *) @ModelActor actor ConsumptionDatabaseStorage: ConsumptionSessionStorage { struct Error: LocalizedError { var errorDescription: String? } private let sortDescriptor = [SortDescriptor(\SDConsumptionSession.startTimeUtc, order: .reverse)] static func createStorage(userId: String) throws -> ConsumptionDatabaseStorage { guard let appGroupContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: UserDefaults.defaultAppGroupIdentifier) else { throw Error(errorDescription: "Invalid app group container ID") } func createModelContainer(databaseUrl: URL) throws -> ModelContainer { return try ModelContainer(for: SDConsumptionSession.self, SDPriceSegment.self, configurations: ModelConfiguration(url: databaseUrl)) } let databaseUrl = appGroupContainer.appendingPathComponent("\(userId).sqlite") do { return self.init(modelContainer: try createModelContainer(databaseUrl: databaseUrl)) } catch { // Creating the model storage failed. Remove the database file and try again. try? FileManager.default.removeItem(at: databaseUrl) return self.init(modelContainer: try createModelContainer(databaseUrl: databaseUrl)) } } func isStorageEmpty() async -> Bool { (try? self.modelContext.fetchCount(FetchDescriptor<SDConsumptionSession>())) ?? 0 == 0 // <-- Crash here! } func sessionsIn(interval: DateInterval) async throws -> [ConsumptionSession] { let fetchDescriptor = FetchDescriptor(predicate: #Predicate<SDConsumptionSession> { sdSession in if let startDate = sdSession.startTimeUtc { return interval.start <= startDate && interval.end > startDate } else { return false } }, sortBy: self.sortDescriptor) let consumptionSessions = try self.modelContext.fetch(fetchDescriptor) // <-- Crash here! return consumptionSessions.map { ConsumptionSession(swiftDataSession: $0) } } func updateSessions(sessions: [ConsumptionSession]) async throws { if #unavailable(iOS 18) { // Price segments are duplicated if re-inserted so unfortunately we have to delete and reinsert sessions. // On iOS 18, this is enforced by the #Unique macro on SDPriceSegment. let sessionIds = Set(sessions.map(\.id)) try self.modelContext.delete(model: SDConsumptionSession.self, where: #Predicate<SDConsumptionSession> { sessionIds.contains($0.id) }) } for session in sessions { self.modelContext.insert(SDConsumptionSession(consumptionSession: session)) } if self.modelContext.hasChanges { try self.modelContext.save() } } func deleteAllSessions() async { if #available(iOS 18, *) { try? self.modelContainer.erase() } else { self.modelContainer.deleteAllData() } } } The actor conforms to this protocol: protocol ConsumptionSessionStorage { func isStorageEmpty() async -> Bool func hasCreditCardSessions() async -> Bool func sessionsIn(interval: DateInterval) async throws -> [ConsumptionSession] func updateSessions(sessions: [ConsumptionSession]) async throws func deleteAllSessions() async } The crash is coming in from line 30 and 41, in other words, when trying to fetch data from the database. There doesn't seem to be any common trait for the crashes. They occur across iOS versions and device types. Any idea what might cause this?
4
0
150
2w
UISheetPresentationController with top attached views
I am using UISheetPresentationController to show bottom sheets like the one in Apple Maps. It works very well. In Apple Maps, there is a weather indicator that sits on top of the presented sheets and follows it (to a point) when the sheet is dragged up or down. I would like to mimic this behavior for my own bottom sheets to have content from the presenting view controller stay visible while the sheet is presented. How do I do this? Is this even possible? I think I'm looking for some kind of layout guide that sits on top of the presented sheet.
Topic: UI Frameworks SubTopic: UIKit
1
1
51
Jul ’25
Setting selectedImage in UITab API
I feel like UITab (new in iOS 18) is missing a selectedImage property. The class can only be instantiated with an image property. In the documentation, it says that if you provide the image as outlined an SF Symbol, it will automatically choose the filled version in the selected state: If you use SF Symbols for your tab’s image, be sure to select the outline variant. The system automatically selects the correct variant (outline or filled) based on the context. https://developer.apple.com/documentation/uikit/elevating-your-ipad-app-with-a-tab-bar-and-sidebar But it doesn't mention how to manage selected state when a custom image is provided. The only workaround I've found is to use this delegate method to switch out the tab images (Tab is a custom enum, providing identifiers, image and selectedImage for each tab): func tabBarController(_ tabBarController: UITabBarController, didSelectTab selectedTab: UITab, previousTab: UITab?) { if let tab = Tab.allCases.first(where: { $0.identifier == selectedTab.identifier }) { selectedTab.image = tab.selectedImage } if let previousTab, let tab = Tab.allCases.first(where: { $0.identifier == previousTab.identifier }) { previousTab.image = tab.image } } Is this really the intention of the new API, that using custom images is this complicated or am I missing something?
Topic: UI Frameworks SubTopic: UIKit
0
0
75
Jul ’25
Unable to get widgetConfigurationIntent from NSUserActivity
I have a simple lock screen widget that when tapped, should open a certain flow in my app. This works fine when the main app is already running, but when tapped while the app is not running, the app launches, but it doesn't open the flow I want it to. When I debug it (see flow below), it seems that the problem come from the widgetConfigurationIntent(of:) function on NSUserActivity. When the app is cold launched, I get the expected NSUserActitivity, but the function above returns nil. That same piece of code returns a valid WidgetConfigurationIntent if the app is already running. Any ideas what might go wrong? There's nothing in the documentation hinting about why this might happen, so I feel a bit lost. BTW, this is how a debug opening from scratch with a lock screen widget: Select "Wait for the executable to be launched" in the scheme editor in Xcode. Make sure the app is not running on device or simulator Start debugging session in Xcode (app is built but not opened) Lock device, tap already installed lock screen widget. App launches and my breakpoint is hit.
0
0
345
Aug ’24
Not able to find the CarPlay capability
In the documentation for adding CarPlay capabilities to an app, it says that I should: Complete the actions in Register an App ID to create an App ID if you don’t already have one. Sign in to your Apple Developer account and select Certificates, Identifiers & Profiles. Select Identifiers in the menu on the left. Select your app’s App ID. Choose the Additional Capabilities tab. Enable the CarPlay capabilities that your app requires. I get stuck on step 5. I simply don't see the "Additional Capabilities" tab (I have "Capabilities" and "App Services") and the CarPlay capability is not showing on the regular "Capabilities" tab. I am Admin on the account. How do I find the CarPlay Capability? Documentation: https://developer.apple.com/documentation/carplay/requesting_carplay_entitlements
2
1
3.2k
Jan ’23