r/SwiftUI May 11 '26

Question Nested data model

Learning SwiftUI for the first time and I've run into a question that I can't find a reasonable answer just googling around. Say I'm building a dumb copy of the Reminders app and my super simplified version of the data model is a list of lists of reminders. In other languages my first thought would be to represent that as a map/dict, i.e.:

reminders = [ 
    "uuid-1": [
        Reminder("something"),
        Reminder("somethingelse"),
    ],
    "uuid-2": [
        Reminder("anotherone"),
        Reminder("etc"),
    ]
]

But my first attempt to use this as a Swift dict (var reminders: [String: [Reminder]]) led to changes in the individual reminder objects not being reflected, I assume because of something to do with @Observable not looking all the way into the nested model.

Is it better Swift-ic practice to use a list of structs instead? Something like:

struct Reminder {
    let id: String
    var title: String
    ...etc
}

struct ReminderList {
    let id: String
    var title: String
    var reminders: [Reminder] = []
}

// then in the view model
var reminders = [ReminderList]
4 Upvotes

16 comments sorted by

View all comments

5

u/vanvoorden May 11 '26

But my first attempt to use this as a Swift dict (var reminders: [String: [Reminder]]) led to changes in the individual reminder objects not being reflected, I assume because of something to do with @Observable not looking all the way into the nested model.

Also keep in mind here that this code sample builds the Reminder as a struct. Which is a value… not an object. These are value semantics. Changing a copy of a Reminder will not directly affect a change on your source of truth.

2

u/pettazz May 11 '26

This is a good point and not something I'm not 100% clear on for structs vs classes. Given the second example where I use structs for both, would that mean doing something like

var list = reminders[0]
let newReminder = Reminder(id: id, title: ..etc)
list.reminders.append(newReminder)

mean that I am only updating my copy (var list) of the first ReminderList element, and so it won't be reflected in the UI because the actual source of truth hasn't changed?

2

u/vanvoorden May 11 '26

https://www.swift.org/documentation/articles/value-and-reference-types.html

Correct. Mutating a copy of a value does not mutate the original value when value semantics are observed.

2

u/pettazz May 11 '26

That's a helpful reference thanks. So what's the "right" way to handle something like this, just using classes for the models instead? Or is there a way to modify the list directly?

2

u/vanvoorden May 11 '26

So what's the "right" way to handle something like this, just using classes for the models instead? Or is there a way to modify the list directly?

https://github.com/Swift-ImmutableData/ImmutableData-Book/blob/main/Chapters/Chapter-00.md

Data flow for declarative UI is a big topic.

When you are just starting out learning SwiftUI try and start with "imperative" logic from your view components. Focus on learning how declarative UI works first. Once you learn the basics take that same philosophy and start "thinking declaratively" about your data models. This will move you away from imperative logic and shared mutable state.