Building Robust ViewModels

Feb 28 2025 · Swift 5.9, iOS 17, Xcode 15.3

Lesson 02: State Management in ViewModels

Demo 2

Episode complete

Play next episode

Next
Transcript

Continue with your project from the first demo or open TheMet app in the Final demo 1 folder.

In TheMetStore, objects isn’t marked as @Published because the Observable protocol publishes all properties by default.

This network service property is private because the views shouldn’t access it directly. To check this, head to ContentView

and try to use it in the task:

try await store.service.getObjectIDs(from: query)
'service' is inaccessible due to 'private' protection level

Nope, private makes it inaccessible. Undo that change

TheMetStore has one other property: maxIndex.

Like objects, maxIndex is published by default, but there’s no reason the views should track its value.

It’s used in the init method.

And again in fetchObjects, to limit the number of downloaded objects.

You could declare it private, like service:

private let maxIndex: Int

In TheMetApp, you can still set its value when you create store:

@State var store = TheMetStore(10)

No problem.

But, suppose you want to include it in this “searched for” text back in the ContentView? Like this:

Text("You searched for \(store.maxIndex) '\(query)' objects")

private is too restrictive.

Go back to TheMetStore and delete private from maxIndex and change it from let to var. You’ll soon replace it with a property wrapper, but first, add a button to ContentView so you can see whether it’s tracking maxIndex.

Button("Change maxIndex") {
  store.maxIndex = 2
}

Refresh the preview, then tap this button. The text updates, although the list itself doesn’t get any shorter.

To be able to change maxIndex, without having views tracking its value, use the @ObservationIgnored property wrapper:

@ObservationIgnored var maxIndex: Int

Now, maxIndex is still public, but views won’t track its value.

Back to ContentView and tap the button. It works! The text doesn’t update with the new maxIndex value.

Go ahead and comment out or delete this Button. You can leave the maxIndex value in the text.

In TheMetApp, delete the argument from the store declaration.

See forum comments
Cinema mode Download course materials from Github
Previous: Adding Observation Properties Instruction Next: Conclusion