-
Added:
Effect.task
, for wrapping async/await work in an effect.Effect.task { guard case let .some((data, _)) = try? await URLSession.shared .data(from: .init(string: "http://numbersapi.com/42")!) else { return "Could not load" } return String(decoding: data, as: UTF8.self) }
-
Added: an
Effect.catchToEffect
overload that takes a transform function, avoiding the need for an extramap
(thanks @eimantas).// before: return environment.apiClient.fetch() .catchToEffect() .map(MyAction.apiResponse) // after: return environment.apiClient.fetch() .catchToEffect(MyAction.apiResponse)
-
Added:
Effect.cancel(ids:)
, which can cancel multiple effects at once by taking multiple cancel identifiers.return .cancel(ids: OnAppearId(), ApiRequestId())
-
Added: Alert and action sheet helpers (
AlertState
andActionSheetState
) can now be configured with animated button actions (thanks @fonkadelic).Support comes with a slightly new API and a deprecation (read: breaking change) of the old API:
// before: primaryButton: .destructive(TextState("Delete"), send: .deleteButtonTapped), // after: primaryButton: .destructive(TextState("Delete"), action: .send(.deleteButtonTapped)),
The newer API comes with an overloaded
animation
parameter, for specifying an animation for the action when sent back to the reducer:primaryButton: .destructive( TextState("Delete"), action: .send(.deleteButtonTapped, animation: .default) ),
-
Added: Alert and action sheet helpers for UIKit (thanks @andreyz).
class MyViewController: UIViewController { let store: Store<MyState, MyAction> let viewStore: ViewStore<MyState, MyAction> private var cancellables: Set<AnyCancellable> = [] private weak var alertController: UIAlertController? ... func viewDidLoad() { ... self.viewStore.publisher .alert .sink { [weak self] alert in guard let self = self else { return } if let alert = alert { let alertController = UIAlertController(state: alert, send: { self.viewStore.send(.settings($0)) }) self.present(alertController, animated: true, completion: nil) self.alertController = alertController } else { self.alertController?.dismiss(animated: true, completion: nil) self.alertController = nil } } .store(in: &cancellables) } }
-
Updated:
WithViewStore.debug()
now prints a diff of view state whenever its body is evaluated. This can be used to determine what change to what portion of sub-state was responsible for the evaluation. -
Updated: code that prints file debug information uses
#fileID
now instead of#file
to reduce debug noise. -
Fixed:
Effect.throttle
should now clean up old values being debounced in itslatest: false
strategy, preventing the occasional old value from emitting (thanks @p4checo). -
Fixed:
Effect.debounce
should now always deliver on the scheduler it is provided. -
Fixed: A minimum deployment target of macOS 11 should now compile without error (thanks @aroben).
-
Infrastructure: Improved
ViewStore.publisher
documentation. -
Infrastructure: Added an Italian translation of the README (thanks @Bellaposa).
-
Infrastructure: Added a SwiftUI case study for focus state.
-
Infrastructure: The Tic-Tac-Toe demo has been modernized. It now uses SPM for modularization instead of frameworks.
-
Infrastructure: Some cleanup and modernization of demo code.