* Pass state to `SwitchStore.init` view builder
Rather than rely on many, many overloads of `SwitchStore.init` to
strictly accept only `CaseLet`s and an optional, final `Default` view,
let's introduce a single initializer without constraints that is passed
the current state whenever the case changes. This state can be switched
on and route to the appropriate view via `CaseLet`.
The pros:
* We get exhaustive switching at compile time.
* We get more flexibility in the view layer. Previously, any
customization needed to be pushed into the `CaseLet` builder, but
now `CaseLet` can freely apply view modifiers.
* We can deprecate and eventually remove the many, many initializer
overloads, and hopefully slim down binary size in the process, and
improve view builder compile times when dealing with `SwitchStore`.
We can also deprecate and eventually remove `Default`.
The cons:
* It's slightly more verbose and repetitive. You have a `SwitchStore`
and then a `switch` inside it with many `case`s with `CaseLet`s
inside them, and the `case .screen:` is followed by
`CaseLet(/State.screen, ...)`.
* One is free to extract the state's associated value(s) and use it to
render a view, but this view will be inert and will not re-render if
the value it depends on changes in the store. This can lead to some
surprises, but we can document against the pattern, and maybe in the
future we can use something like macros to prevent this from being
possible.
* You can still get things wrong if you're not careful: there's
nothing enforcing that the `case` you switch on is the same case you
send to `CaseLet`, so `case .screenA: CaseLet(/State.screenB, ...)`
is possible. While unlikely, it's still a copy-paste error in
waiting.
* wip
* wip
* wip
* Bump
* fix test
* clean up
* clean up
* clean up
* wip
---------
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* Add `Effect.send`
With the `Effect<Action, Failure>` -> `Effect<Action>` migration,
`Effect.init(value:)` and `Effect.init(error:)` no longer make sense. We
will be retiring the latter some time in the future, so let's also get a
head start and rename the former to `Effect.send`.
For now it will call `Effect.init(value:)` under the hood, but in the
future we will want a non-Combine-driven way of running synchronous
effects.
* format fix
* wip
* fix
* wip
* wip
The -`able` naming evokes protocols in Swift, and is an outlier when
considered alongside the rest of TCA's binding tools:
- `BindingAction`: concrete type
- `BindableAction`: protocol
- `BindingReducer`: concrete type
So, let's make things consistent.
The one caveat is that Swift diagnostics for such a deprecation aren't
great, so users won't get proactive warnings here for the time being:
https://github.com/apple/swift/issues/63139
We may just want to keep the deprecation around till it does...
* Add `prepareDependencies` to `Store.init`:wq
* wip
* test and doc
* update TTT previews to use new trailing closure style"
* wip
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
It occurred to us that this solution unfortunately is incompatible with
view actions. We have an alternate solution that works, so I'll PR that
in the future if no others materialize!
* Simpler bindable view state
* wip
* wip
* Remove `BindingStore`
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Make BindingState conditionally sendable.
* Fixed tests
* Update bindings article
* Add some additional contextual information to the runtime warnings
* update some docs
* lots more docs
* test clean up
* Improve diagnostic
* Put back `BindingReducer()` in the form study
* clean up
* Improve DocC references
* Remove DocC references for `@`'d property wrappers.
* wip
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* bump navigation
* bump swiftui-navigation
* Add SearchView preview
* make login sendable
* use button state builder
* format
* bump swift and platform version
* remove unused test clock
* Add quotes to scheme
* Avoid failure when setting test dependency values
It's currently possible to emit XCTest failures when testing reducers
that access dependency values that emit failure upon access, which
includes the calendar, locale, time zone, and URL session dependencies.
We may need a more holistic solution for folks that define these kinds
of dependencies outside the library, but this will make the
library-level failures a bit more lenient.
* wip
* a few more tests
Co-authored-by: Brandon Williams <mbrandonw@hey.com>
* Remove unnecessary dependencies in SwiftUI-CaseStudies
* Remove unnecessary dependencies in other-CaseStudies
* Add MARK headers to every SwiftUI-CaseStudies
* Restore Swift 5.5 compatibility
As pointed out in #1489, we somehow lost compatibility with Swift 5.5
(Xcode 13.2). While we hope to drop support when we hit 1.0, let's try
to keep compatiblity in the meantime.
* Update DependencyValues.swift
* Update Sources/Dependencies/DependencyValues.swift
Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com>
* Require Swift 5.6
* Update ci.yml
Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com>
* Remove a few dependencies to UIKit in SwiftUI's CaseStudies
* Update Examples/CaseStudies/SwiftUICaseStudies/02-Effects-Basics.swift
* Update Examples/CaseStudies/SwiftUICaseStudies/02-Effects-Cancellation.swift
Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com>