Relationships between structs and detecting changes

I'm currently working on an app which has a number of different data objects with relationships between them.

For example, there is a Building struct:

struct Building {
  let id: UUID
  var name: String
}

There is also an Address struct, which has a Building property:

struct Address: {
  let id: UUID
  var addressText: String
  var building: Building
}

When I change the name of the Building I would like it to update for all the corresponding Address objects. Because structs are value types, this doesn't happen at present.

  • I could fix this by changing struct to class, but because I'm working with SwiftUI that's not desirable.
  • I could fix this by updating the Address to store the id of the Building instead but having to look up the name of the corresponding building each time I want it feels messy to me.

Is there some other approach I'm missing? Or a recommended best practice way of handling relationships between structs?

You may try to use KVO, but that requires some work: https://stackoverflow.com/questions/54231759/is-it-possible-to-add-an-observer-on-struct-variable-in-swift

However, I do not fully understand your code and request.

  • Why do you need Building struct, and not store building name directly in Address ?
  • Where are all instances of Address stored ?
  • Same question for Buildings
  • Are they displayed In a List ?
  • Where do you change the name of a Building ?

In any case, I would update directly all relevant addresses when a name changes.

Storing the Building ID in Address is another good solution. In addition, you can create a computed var in Address to get directly the building name from its id.

Thanks @Claude31 for the suggestion - but it feels like that could be even more complicated than just referencing the ids. In answer to your questions:

  • The code example shown above is massively simplified - in practice the Building struct is much more complex.
  • The Address objects are stored in an array which belongs to a custom class. That class is an ObservableObject and is being used as an EnvironmentObject.
  • Yes, the Address and Building objects both get displayed in separate Lists.
  • The name of a Building is edited in a SwiftUI view, and can be edited using a TextField.

So, storing id and a computed var should do it:

struct Address: {
  let id: UUID
  var addressText: String
  var building: Building 
  var buildingName: String {
     // return the name of the Building from its id
  }
}

Hope that's relevant for your case.

Relationships between structs and detecting changes
 
 
Q