The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
Provide aliases to improve cohabitation with protocol reducers
1 year ago
When importing versions of TCA defining `ReducerProtocol`, there will likely be ambiguities when using the @Dependency property wrapper, or the DependencyKey protocol. As this library will give way to TCA, the preferred approach is the following:
Define a typealias to both TCA's types in a module you own (or in your application if you're not using modules):
```swift
import ComposableArchitecture
public typealias DependencyKey = ComposableArchitecture.DependencyKey
public typealias Dependency = ComposableArchitecture.Dependency
```
Because these typeliases are defined in modules you own, they will be preferred to external definitions when resolving types.
Replace all occurrences of `DependencyKey` by `Compatible.DependencyKey` and `@Dependency` by `@Compatible.Dependency`. You can use Xcode search/replace in all files for this purpose.
In this state, your project should build without ambiguities and you can start transitioning to reducer protocols at your rhythm.
This is a simple maintenance release.
* Added support for recursive environments thanks to @maximkrouk.
A new `ComposableDependencies` module can be used when you only want to define dependencies without having to commit to `ComposableEnvironment` or `GlobalEnvironment` at this level[^1]. These dependencies can then be imported and used by either environment's style (thanks @maximkrouk).
[^1]: You don't need to import `ComposableDependencies` if you're already importing `ComposableEnvironment` or `GlobalEnvironment` where you declare your dependency.
You can now call `Dependencies.reset()` to reset dependencies to their default when testing features using `GlobalEnvironment`. This method is not available for `ComposableEnvironment`, as you can create new environment instances instead.
`GlobalEnvironment` and dependency aliases
2 years ago
### `GlobalEnvironment`
The library is now split into two mutually exclusive modules:
- `ComposableEnvironment`, when you need to update a dependency value mid-chain
- `GlobalEnvironment`, when your dependencies are shared among all your environments with the same values.
Requirements for both modules are different. `GlobalEnvironment` is the simplest one to implement and should fit most cases.
If your project doesn't require mid-chain overrides of dependencies, we recommend adopting `GlobalEnvironment`, which can be as simple as conforming your environment type to a marker protocol.
The API is kept as similar as possible, so you can migrate a project from one to another without having to change much code.
### Dependency aliases
You can now identify dependencies defined with different names in different domains. For example, if you defined `main` for the main queue in one domain and `mainQueue` in another, you can alias the former with the latter using:
```swift
environment.aliasing(\.main, to: \.mainQueue)
```
Both properties will then return the same dependency value.
Aliasing can also be defined when using the `@DerivedEnvironment` property wrapper.
### `ComposableDependencies`
The `ComposableDependencies` type, where you install your computed properties to access your dependencies, has been renamed `Dependencies`. An Xcode "fix-it" is provided.
AutoComposableEnvironment
2 years ago
You can now optionally forgo `@Dependency` and `@DerivedEnvironment` declarations:
- You can directly access dependencies using their property name defined in `ComposableDepencies` directly in your `ComposableEnvironment` subclass, as if you defined `@Dependency(\.someDependency) var someDependency`.
- You can use environment-less pullbacks. They will vend your derived feature's reducer a derived environment of the expected type. This is equivalent to defining `@DerivedEnvironment<ChildEnvironment> var child` in your parent's environment, and using `[β¦], environment:\.child)` when pulling-back.
You still need `@Dependency` if you want to customize the exposed name of your dependency in your environment, like
```swift
@Dependency(\.someDependency) var anotherNameForTheDependency
```
You still need `@DerivedEnvironment` if you want to override the dependencies inside the environment's chain:
```swift
@DerivedEnvironment var child = ChildEnvironment().with(\.someDependency, someValue)
```
The example app was updated to show how this feature can be used and mixed with the property-wrapper approach.
This release removes the restriction which prohibited dependencies values to be modified once the chain of environment was accessed for the first time.
This safeguard was installed because environments did retrieve dependencies from their parent only once, on first access (for performance reasons), without any updating mechanism.
This restriction is now lifted and environments are now spotting when their parent's dependencies have potentially changed, and update accordingly.
@Inlinable and @usableFromInline decoration were removed to avoid polluting the ABI of the library.
The performance gain was hypothetic, and they may be reinstated someday if their positive influence is clearly assessed.
Premature optimization is the root of all evil.