SwiftData - What is Best Practice for returning an object from a sheet

SwiftUI & SwiftData.

I have a view that lists SwiftData objects. Tapping on a list item navigates to a detail view. The list view also has a "New Object" button. Tapping it opens a sheet used to create a new object. There are, obviously, two possible outcomes from interacting with the sheet — a new object could be created or the user could cancel without creating a new object.

If the user creates a new object using the sheet, I want to open the detail view for that object. My thought was to do this in the onDismiss handler for the sheet. However, that handler takes no arguments.

What is best practice for handling this situation? In UIKit, I would return a Result<Object, Error> in a closure. That won't work here. What is the "correct" way to handle this that is compatible with SwiftData and the Observation framework?

Replies

hi Richard,

i'll answer this from the Core Data perspective, where a list is driven with a @FetchRequest. from all that i've read, it should work the same with SwiftData, where a list is driven by @Query.

my simple answer is: do nothing. in your "Add New Object view", the outcomes are:

  • Cancel = dismiss and do nothing.

  • Save = Create and save a new object to Core Data (SwiftData) and then dismiss. but do nothing else! the @FetchRequest (@Query) in your list view will pick up that a new object has been added, and redraw the list.

if your list view wanted to use what was the new object created in your list view, then i would have the "Add New Object view" take a closure as a parameter with signature (NewObject) -> Void that is defined in your list view, and have the save routine invoke that closure.

hope that helps,

DMG

  • "if your list view wanted to use what was the new object created in your list view [...]" Another approach, instead of using a closure, could be to pass a binding to the new object an an optional (@Binding var newObject: NewObjectModel?). In case of "cancel" nothing would be set, so it would still be nil. And the case of save it would be set to the newly created model object and the calling view could react on that (for example with the onChange modifier).

Add a Comment

Hi, DMG,

You're right - that is the obvious way to deal with the issue. I'm an old UIKit guy new to SwiftUI (and SwiftData and Observation Framework) so I was looking for a way to leverage the Observation framework, but a more traditional callback approach will certainly work.

Very helpful. Thanks,

Rick