-
Added:
Store.unchecked
creates a store that opts out of main thread checks. Use this function to create background stores that are not intended to drive UI. -
Changed: Dynamic member lookup on view stores to bindable state has been deprecated in favor of a new
ViewStore.binding
overload that takes a key path to bindable state. I.e.,viewStore.$field
changes toviewStore.binding(\.$field)
.The dynamic member lookup syntax introduced in 0.26.0 unfortunately broke support for reducers layering logic onto mutations of nested fields of bindable state via pattern matching, e.g.:
switch action { case .binding(\.$userSettings.displayName):
To restore this functionality, we must work directly with the equivalent nested key path in the view, instead.
// before: TextField("Display name", text: viewStore.$userSettings.displayName) // after: TextField("Display name", text: viewStore.binding(\.$userSettings.displayName))
For more information on this change, see #810.
-
Changed: The
Store
now comes with a main thread check by default. If a store is created or interacted with off the main thread, including sending actions, scoping, or receiving/completing effects off the main thread, a breakpoint will catch in debug builds. If you are using a store on a non-main thread, use the newStore.unchecked
static function to construct a store instead. -
Changed: Alert APIs have been updated to call the new SwiftUI APIs under the hood when available. As such, the following changes have been made:
AlertState
has introduced a new initializer that takes any number of buttons.ActionSheetState
has been renamed toConfirmationDialogState
.ConfirmationDialogState
has introduced a new initializer that exposestitleVisibility
.View.actionSheet
has been renamed toView.confirmationDialog
.
-
Changed: Animated view store bindings now match the behavior of vanilla SwiftUI (thanks @iampatbrown).
-
Changed: store publisher subscriptions are now deterministic (thanks @iampatbrown).
This change mainly affects UIKit-based apps that call
viewStore.publisher.sink
. The vanilla Combine behavior of the store's current value subject is non-deterministic. That is multiple subscriptions to a single subject do not receive output in a deterministic order. Stores are now driven by a custom publisher, instead, that emits values to subscribers in a deterministic way.In previous versions of the Composable Architecture, view store binding animations could not be overridden with
withAnimation
blocks, which is the opposite behavior of bindings derived from@State
,@ObservedObject
, etc. -
Cleaned up: The
Store.ifLet
UIKit helper has been simplified (thanks @iampatbrown). -
Fixed: Xcode 12.4 support.
-
Deprecated: The
Store.publisherScope
method has been deprecated, as it was only used to drive the previous implementation ofStore.ifLet
. If you depend on this method, please let us know how. -
Removed: Deprecations introduced before swift-composable-architecture 0.17.0 have been removed. If you are upgrading from an earlier version, do so incrementally to see these notices and fix-its.
-
Infrastructure: cleaned up speech recognition case study.