Post

Replies

Boosts

Views

Activity

Access Relationship value from deleted model tombstone in SwiftData.
I’m developing an app using SwiftData. In my app, I have two models: User and Address. A user can have multiple addresses. I’m trying to use SwiftData History tracking to implement some logic when addresses are deleted. Specifically, I need to determine which user the address belonged to. From the documentation, I understand that you can preserve attributes from deleted models in a tombstone object using @Attribute(.preserveValueOnDeletion). However, this isn’t working when I try to apply this to a relationship value. Below is a simplified example of my attempts so far. I suspect that simply adding @Attribute(.preserveValueOnDeletion) to a relationship isn’t feasible. If that’s indeed the case, what would be the recommended approach to identify the user associated with an address after it has been deleted? Thank you. @Model class User { var name: String @Relationship(deleteRule: .cascade, inverse: \Address.user) var addresses: [Address] = [] init(name: String) { self.name = name } } @Model class Address { var adress1: String var address2: String var city: String var zip: String @Attribute(.preserveValueOnDeletion) var user: User? init(adress1: String, address2: String, city: String, zip: String) { self.adress1 = adress1 self.address2 = address2 self.city = city self.zip = zip self.user = user } } for transaction in transactions { for change in transaction.changes { switch change { case .delete(let deleted): if let deleted = deleted as? any HistoryDelete<Address> { if let user = deleted.tombstone[\.user] { //this is never executed } } default: break } } }
1
0
88
2w
SwiftData not syncing to CloudKit
I have an app with SwiftData and CloudKit sync enabled, it was working fine but I recently noticed that the sync with CloudKit is not working anymore. All the changes are persisted locally just fine. When running in simulator (iOS 26/iPhone 17 Pro) I get the following error in the console: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2317): <NSCloudKitMirroringDelegate: 0x600003d14c30> - Attempting recovery from error: Error Domain=NSCocoaErrorDomain Code=134421 "Export encountered an unhandled exception while analyzing history in the store." UserInfo={NSLocalizedFailureReason=Export encountered an unhandled exception while analyzing history in the store., NSUnderlyingException=-[NSEntityDescription objectID]: unrecognized selector sent to instance 0x60000351aec0} I already tried Reseting the environment back to production in CloudKit and Erasing all Contents and Settings in the simulator but I keep getting the same error. Is there something else I can do to fix this?
2
0
209
Oct ’25
NavigationStack path is being reset in NavigationSplitView details columns
I'm building a SwiftUI app for iPad using a NavigationSplitView as the navigation root. Below is a simplified version of the app's navigation. There are a Home Page and a Settings Page, each with its own NavigationStack. The page that appears in the detail column depends on the sidebar's selection value. The issue I'm facing is that when I navigate deeply into the Home Page's NavigationStack (e.g., to a Home Page Child view), switch to the Settings Page, and then switch back to the Home Page, the Home Page's navigation path has been reset to [] and the previous state is lost. The same issue occurs if I navigate deeply into the Settings Page (e.g., to a Settings Page Child view), switch to the Home Page, and then return to the Settings Page: the navigation state for the Settings Page is lost, and it reverts to the root of the NavigationStack. Why is this happening and how can I fix it so that switching pages in the sidebar doesn't reset the NavigationStack of each individual page in the detail column? Thank you. struct ContentView: View { @State var selection: String? @State var firstPath = [String]() @State var secondPath = [String]() var body: some View { NavigationSplitView { List(selection: $selection) { Text("Home") .tag("home") Text("Settings") .tag("settings") } } detail: { if selection == "home" { HomePage(path: $firstPath) } else { SettingsPage(path: $secondPath) } } } } struct HomePage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Home Page", value: "Home") .navigationDestination(for: String.self) { _ in Text("Home Page Child") } } } } struct SettingsPage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Settings Page", value: "Settings") .navigationDestination(for: String.self) { _ in Text("Settings Page Child") } } } } #Preview { ContentView() }
0
0
290
Aug ’25
Error querying optional Codable with SwiftData
I'm building a SwiftUI app using SwiftData. In my app I have a Customer model with an optional codable structure Contact. Below is a simplified version of my model: @Model class Customer { var name: String = "" var contact: Contact? init(name: String, contact: Contact? = nil) { self.name = name self.contact = contact } struct Contact: Codable, Equatable { var phone: String var email: String var allowSMS: Bool } } I'm trying to query all the Customers that have a contact with @Query. For example: @Query(filter: #Predicate<Customer> { customer in customer.contact != nil }) var customers: [Customer] However no matter how I set the predicate I always get an error: BugDemo crashed due to an uncaught exception NSInvalidArgumentException. Reason: keypath contact not found in entity Customer. How can I fix this so that I'm able to filter by contact not nil in my Model?
2
0
269
Jun ’25
Correct way to label TextField inside Form in SwiftUI
Hello everyone. I'm building a simple Form in a Multiplatform App with SwiftUI. Originally I had something like this. import SwiftUI struct OnboardingForm: View { @State var firstName: String = "" @State var lastName: String = "" @State var email: String = "" @State var job: String = "" @State var role: String = "" var body: some View { Form { TextField("First Name", text: $firstName, prompt: Text("Required")) TextField("Last Name", text: $lastName, prompt: Text("Required")) TextField("Email", text: $email, prompt: Text("Required")) TextField("Job", text: $job, prompt: Text("Required")) TextField("Role", text: $role, prompt: Text("Required")) } } } #Preview { OnboardingForm() } In macOS it looks ok but then in iOS it looks like this: and it's impossible to know what each field is for if all the prompts are the same. I tried adding LabeledContent around each text field and that solves it for iOS but then on macOS it looks like this: The labels are shown twice and the columns are out of alignment. I think I could get around it by doing something like this: #if os(iOS) LabeledContent { TextField("First Name", text: $firstName, prompt: Text("Required")) } label: { Text("First Name") } #else TextField("First Name", text: $firstName, prompt: Text("Required")) #endif but it seems to me like reinventing the wheel. Is there a "correct" way to declare TextFields with labels that works for both iOS and macOS?
2
0
1.1k
Feb ’25
Implement two lists side by side with SwiftUI on iPad
I'm currently building an App using a TabView as the main navigation method. In my app I would like to build a page similar to the Top Charts in the native App Store App with two lists side by side: So far I came up with this code (simplified demo): import SwiftUI struct Demo: View { var body: some View { TabView { Tab("Main Tab", systemImage: "tray.and.arrow.down.fill") { NavigationStack { HStack { List { Text("Left List") } List { Text("Right List") } } .navigationTitle("Demo") .navigationBarTitleDisplayMode(.inline) } } } } } #Preview { Demo() } However, I’m encountering a couple of issues: • Scrolling to the top of the left list doesn’t trigger the toolbar background effect, and the content overlaps with the tabs in a strange way. Scrolling to the top of the right list works as expected. • The navigation title is always hidden. I haven’t been able to find a solution to these problems. What would be the correct approach? Thank you!
1
0
592
Jan ’25
SwiftData rollback not updating the UI
I'm building a simple App using SwiftData. In my app a user can create, remove and edit posts. When editing, I want them to be able to hit "Save" to persist the changes or "Cancel" to discard the changes. The approach I'm using is to disable autosave and call modelContext.save() when saving and modelContext.rollback() when discarding the changes. So my modelContainer is defined as follows: WindowGroup { ContentView() .modelContainer(for: [Post.self], isAutosaveEnabled: false) } and I Save and Cancel like this: PostForm(post: post) .toolbar { ToolbarItemGroup(placement: .cancellationAction) { Button("Cancel") { if modelContext.hasChanges { modelContext.rollback() } dismiss() } } ToolbarItemGroup(placement: .confirmationAction) { Button("Save") { do { if modelContext.hasChanges { try modelContext.save() } } catch { fatalError("Failed to save post: \(error.localizedDescription)") } callback?() dismiss() } } } The issue I am facing is that after calling modelContext.rollback() my Posts aren't updating in the UI, they still show the changes. Restarting the app shows the Posts without the changes so I'm guessing that modelContext.rollback() is in fact discarding the changes and not persisting them in the Storage, the UI is the one that is not reacting to the change. Am I doing something wrong here? Is this approach correct?
2
2
559
Jul ’24
TabSection always show sections actions.
I'm giving a go to the new TabSection with iOS 18 but I'm facing an issue with sections actions. I have the following section inside a TabView: TabSection { ForEach(accounts) { account in Tab(account.name , systemImage: account.icon, value: SelectedTab.accounts(account: account)) { Text(account.name) } } } header: { Text("Accounts") } .sectionActions { AccountsTabSectionAddAccount() } I'm showing a Tab for each account and an action to create new accounts. The issue I'm facing is that when there are no accounts the entire section doesn't appear in the side bar including the action to create new accounts. To make matters worse the action doesn't show at all in macOS even when there are already accounts and the section is present in side bar. Is there some way to make the section actions always visible?
1
0
739
Jul ’24
Access Relationship value from deleted model tombstone in SwiftData.
I’m developing an app using SwiftData. In my app, I have two models: User and Address. A user can have multiple addresses. I’m trying to use SwiftData History tracking to implement some logic when addresses are deleted. Specifically, I need to determine which user the address belonged to. From the documentation, I understand that you can preserve attributes from deleted models in a tombstone object using @Attribute(.preserveValueOnDeletion). However, this isn’t working when I try to apply this to a relationship value. Below is a simplified example of my attempts so far. I suspect that simply adding @Attribute(.preserveValueOnDeletion) to a relationship isn’t feasible. If that’s indeed the case, what would be the recommended approach to identify the user associated with an address after it has been deleted? Thank you. @Model class User { var name: String @Relationship(deleteRule: .cascade, inverse: \Address.user) var addresses: [Address] = [] init(name: String) { self.name = name } } @Model class Address { var adress1: String var address2: String var city: String var zip: String @Attribute(.preserveValueOnDeletion) var user: User? init(adress1: String, address2: String, city: String, zip: String) { self.adress1 = adress1 self.address2 = address2 self.city = city self.zip = zip self.user = user } } for transaction in transactions { for change in transaction.changes { switch change { case .delete(let deleted): if let deleted = deleted as? any HistoryDelete<Address> { if let user = deleted.tombstone[\.user] { //this is never executed } } default: break } } }
Replies
1
Boosts
0
Views
88
Activity
2w
SwiftData not syncing to CloudKit
I have an app with SwiftData and CloudKit sync enabled, it was working fine but I recently noticed that the sync with CloudKit is not working anymore. All the changes are persisted locally just fine. When running in simulator (iOS 26/iPhone 17 Pro) I get the following error in the console: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2317): <NSCloudKitMirroringDelegate: 0x600003d14c30> - Attempting recovery from error: Error Domain=NSCocoaErrorDomain Code=134421 "Export encountered an unhandled exception while analyzing history in the store." UserInfo={NSLocalizedFailureReason=Export encountered an unhandled exception while analyzing history in the store., NSUnderlyingException=-[NSEntityDescription objectID]: unrecognized selector sent to instance 0x60000351aec0} I already tried Reseting the environment back to production in CloudKit and Erasing all Contents and Settings in the simulator but I keep getting the same error. Is there something else I can do to fix this?
Replies
2
Boosts
0
Views
209
Activity
Oct ’25
NavigationStack path is being reset in NavigationSplitView details columns
I'm building a SwiftUI app for iPad using a NavigationSplitView as the navigation root. Below is a simplified version of the app's navigation. There are a Home Page and a Settings Page, each with its own NavigationStack. The page that appears in the detail column depends on the sidebar's selection value. The issue I'm facing is that when I navigate deeply into the Home Page's NavigationStack (e.g., to a Home Page Child view), switch to the Settings Page, and then switch back to the Home Page, the Home Page's navigation path has been reset to [] and the previous state is lost. The same issue occurs if I navigate deeply into the Settings Page (e.g., to a Settings Page Child view), switch to the Home Page, and then return to the Settings Page: the navigation state for the Settings Page is lost, and it reverts to the root of the NavigationStack. Why is this happening and how can I fix it so that switching pages in the sidebar doesn't reset the NavigationStack of each individual page in the detail column? Thank you. struct ContentView: View { @State var selection: String? @State var firstPath = [String]() @State var secondPath = [String]() var body: some View { NavigationSplitView { List(selection: $selection) { Text("Home") .tag("home") Text("Settings") .tag("settings") } } detail: { if selection == "home" { HomePage(path: $firstPath) } else { SettingsPage(path: $secondPath) } } } } struct HomePage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Home Page", value: "Home") .navigationDestination(for: String.self) { _ in Text("Home Page Child") } } } } struct SettingsPage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Settings Page", value: "Settings") .navigationDestination(for: String.self) { _ in Text("Settings Page Child") } } } } #Preview { ContentView() }
Replies
0
Boosts
0
Views
290
Activity
Aug ’25
Error querying optional Codable with SwiftData
I'm building a SwiftUI app using SwiftData. In my app I have a Customer model with an optional codable structure Contact. Below is a simplified version of my model: @Model class Customer { var name: String = "" var contact: Contact? init(name: String, contact: Contact? = nil) { self.name = name self.contact = contact } struct Contact: Codable, Equatable { var phone: String var email: String var allowSMS: Bool } } I'm trying to query all the Customers that have a contact with @Query. For example: @Query(filter: #Predicate<Customer> { customer in customer.contact != nil }) var customers: [Customer] However no matter how I set the predicate I always get an error: BugDemo crashed due to an uncaught exception NSInvalidArgumentException. Reason: keypath contact not found in entity Customer. How can I fix this so that I'm able to filter by contact not nil in my Model?
Replies
2
Boosts
0
Views
269
Activity
Jun ’25
Correct way to label TextField inside Form in SwiftUI
Hello everyone. I'm building a simple Form in a Multiplatform App with SwiftUI. Originally I had something like this. import SwiftUI struct OnboardingForm: View { @State var firstName: String = "" @State var lastName: String = "" @State var email: String = "" @State var job: String = "" @State var role: String = "" var body: some View { Form { TextField("First Name", text: $firstName, prompt: Text("Required")) TextField("Last Name", text: $lastName, prompt: Text("Required")) TextField("Email", text: $email, prompt: Text("Required")) TextField("Job", text: $job, prompt: Text("Required")) TextField("Role", text: $role, prompt: Text("Required")) } } } #Preview { OnboardingForm() } In macOS it looks ok but then in iOS it looks like this: and it's impossible to know what each field is for if all the prompts are the same. I tried adding LabeledContent around each text field and that solves it for iOS but then on macOS it looks like this: The labels are shown twice and the columns are out of alignment. I think I could get around it by doing something like this: #if os(iOS) LabeledContent { TextField("First Name", text: $firstName, prompt: Text("Required")) } label: { Text("First Name") } #else TextField("First Name", text: $firstName, prompt: Text("Required")) #endif but it seems to me like reinventing the wheel. Is there a "correct" way to declare TextFields with labels that works for both iOS and macOS?
Replies
2
Boosts
0
Views
1.1k
Activity
Feb ’25
Implement two lists side by side with SwiftUI on iPad
I'm currently building an App using a TabView as the main navigation method. In my app I would like to build a page similar to the Top Charts in the native App Store App with two lists side by side: So far I came up with this code (simplified demo): import SwiftUI struct Demo: View { var body: some View { TabView { Tab("Main Tab", systemImage: "tray.and.arrow.down.fill") { NavigationStack { HStack { List { Text("Left List") } List { Text("Right List") } } .navigationTitle("Demo") .navigationBarTitleDisplayMode(.inline) } } } } } #Preview { Demo() } However, I’m encountering a couple of issues: • Scrolling to the top of the left list doesn’t trigger the toolbar background effect, and the content overlaps with the tabs in a strange way. Scrolling to the top of the right list works as expected. • The navigation title is always hidden. I haven’t been able to find a solution to these problems. What would be the correct approach? Thank you!
Replies
1
Boosts
0
Views
592
Activity
Jan ’25
SwiftData rollback not updating the UI
I'm building a simple App using SwiftData. In my app a user can create, remove and edit posts. When editing, I want them to be able to hit "Save" to persist the changes or "Cancel" to discard the changes. The approach I'm using is to disable autosave and call modelContext.save() when saving and modelContext.rollback() when discarding the changes. So my modelContainer is defined as follows: WindowGroup { ContentView() .modelContainer(for: [Post.self], isAutosaveEnabled: false) } and I Save and Cancel like this: PostForm(post: post) .toolbar { ToolbarItemGroup(placement: .cancellationAction) { Button("Cancel") { if modelContext.hasChanges { modelContext.rollback() } dismiss() } } ToolbarItemGroup(placement: .confirmationAction) { Button("Save") { do { if modelContext.hasChanges { try modelContext.save() } } catch { fatalError("Failed to save post: \(error.localizedDescription)") } callback?() dismiss() } } } The issue I am facing is that after calling modelContext.rollback() my Posts aren't updating in the UI, they still show the changes. Restarting the app shows the Posts without the changes so I'm guessing that modelContext.rollback() is in fact discarding the changes and not persisting them in the Storage, the UI is the one that is not reacting to the change. Am I doing something wrong here? Is this approach correct?
Replies
2
Boosts
2
Views
559
Activity
Jul ’24
TabSection always show sections actions.
I'm giving a go to the new TabSection with iOS 18 but I'm facing an issue with sections actions. I have the following section inside a TabView: TabSection { ForEach(accounts) { account in Tab(account.name , systemImage: account.icon, value: SelectedTab.accounts(account: account)) { Text(account.name) } } } header: { Text("Accounts") } .sectionActions { AccountsTabSectionAddAccount() } I'm showing a Tab for each account and an action to create new accounts. The issue I'm facing is that when there are no accounts the entire section doesn't appear in the side bar including the action to create new accounts. To make matters worse the action doesn't show at all in macOS even when there are already accounts and the section is present in side bar. Is there some way to make the section actions always visible?
Replies
1
Boosts
0
Views
739
Activity
Jul ’24