Skip to content

2.5.0

Latest

Choose a tag to compare

@NikSativa NikSativa released this 06 Nov 14:42

UIState and ManagedState have the same interface. Both types support Combine, ObservableObject, and the Observation framework. Both types protect the value with a lock.

Access to a property of the value:

  • state.title is the value of the property. With the Observation framework, the read tracks the whole value.
  • $state[\.title] is the value of the property. The read tracks only title. A nested key path, such as $state[\.trip.title], is one field.
  • $state.title is a SwiftUI Binding<String>. A read through the binding tracks only title.
  • $state.ui.title is a UIBinding<String>. The new property ui returns the same binding as $state().

If the type of a field is not Equatable, a read of the field tracks the whole value.

Observation:

  • An observer that reads one field gets a notification only when that field gets a different value.
  • An observer that reads wrappedValue gets a notification for each change.
  • The observers get the notification before the value changes, as with the @Observable macro.

Locks:

  • The new type StateLock replaces ManagedStateLock. The new variable StateDefaultLock replaces ManagedStateDefaultLock. The old names are deprecated.
  • UIState has the new initializer init(wrappedValue:lock:) and the new method withLock(_:). If the initializer gets no lock, the state uses StateDefaultLock. The default value is .synced.
  • UIState and ManagedState notify the subscribers and observers while they hold the lock. If a subscriber reads the state and the state uses a non-recursive custom lock, a deadlock occurs.

Changes that need an update of your code:

  • $state.title no longer returns a UIBinding. Use $state.ui.title.
  • $state.title no longer returns the value of the property. Use $state[\.title].
  • $state.title = value no longer compiles. Write state.title = value, or write $state.withLock { $0.title = value }.
  • objectWillChange of UIState emits before each change. It does not emit when a subscriber subscribes.
  • UIState.publisher is a constant. Code that assigns a value to it no longer compiles.
  • CombineExt imports SwiftUI.

Fixes:

  • ARC releases a UIState instance when no code holds it. Before this release, the current value of the publisher kept a strong reference to the instance.
  • The first access to UIState.publisher from more than one thread is safe.