Skip to content

ComposableEnvironment

maximkrouk edited this page May 5, 2022 · 1 revision

ComposableEnvironment

@available(
  *, deprecated,
  message:
    """
  If you are transitioning from `ComposableEnvironment`, you should replace this class by a type \
  conforming to `GlobalEnvironment` or `GlobalDependenciesAccessing`. Please make sure that you \
  are not overriding dependencies mid-chain, as all dependencies are shared globally when using \
  `GlobalEnvironment`. If your project depends on mid-chain dependencies overrides, using \
  `GlobalEnvironment` will likely produce incoherent results. In this case, you should continue \
  using `ComposableEnvironment`.
  
  If you are not transitioning from `ComposableEnvironment`, you should not have to use this type \
  at all. It is only provided to help transitioning projects from `ComposableEnvironment` to \
  `GlobalEnvironment`.
  """
)
open class ComposableEnvironment: GlobalEnvironment 

Inheritance

GlobalEnvironment, GlobalEnvironment

Initializers

init()

Instantiate a ComposableEnvironment instance with all dependencies sets to their defaults.

public required init() 

After using this initializer, you can chain with(_:_:) calls to set the values of individual dependencies. These values ill propagate to each childDerivedEnvironment as well as their own children DerivedEnvironment.

init()

public required init() 

Methods

with(_:_:)

Use this function to set the values of a given dependency for this environment and all its descendants.

@discardableResult
  public func with<V>(_ keyPath: WritableKeyPath<Dependencies, V>, _ value: V) -> Self 

Calls to this function are chainable, and you can specify any Dependencies's KeyPath, even if the current environment instance does not expose the corresponding dependency itself.

For example, if you define:

extension Dependencies {
  var uuidGenerator: () -> UUID {}
  var mainQueue: AnySchedulerOf {}
},

you can set their values in a LocalEnvironment instance and all its descendants like:

LocalEnvironment()
  .with(\.uuidGenerator, { UUID() })
  .with(\.mainQueue, .main)

aliasing(_:to:)

Identify a dependency to another one.

public func aliasing<Value>(
    _ dependency: WritableKeyPath<Dependencies, Value>,
    to default: WritableKeyPath<Dependencies, Value>
  ) -> Self 

You can use this method to synchronize identical dependencies from different domains. For example, if you defined a main dispatch queue dependency called .main in one domain and .mainQueue in another, you can identify both dependencies using

environment.aliasing(\.main, to: \.mainQueue)

The second argument provides its default value to all aliased dependencies, and all aliased dependencies returns this default value until the value any of the aliased dependencies is set.

You can set the value of any aliased dependency using any KeyPath:

environment
  .aliasing(\.main, to: \.mainQueue)
  .with(\.main, DispatchQueue.main)
// is equivalent to:
environment
  .aliasing(\.main, to: \.mainQueue)
  .with(\.mainQueue, DispatchQueue.main)

If you chain multiple aliases for the same dependency, the closest to the root is the one responsible for the default value:

environment
  .aliasing(\.main, to: \.mainQueue) // <- The default value will be the
  .aliasing(\.uiQueue, to: \.main)   //    default value of `mainqueue`

If dependencies aliased through DerivedEnvironment are aliased in the order of environment composition, with the dependency closest to the root environment providing the default value if no value is set for any aliased dependency.

Parameters

  • dependency: The KeyPath of the aliased dependency in Dependencies
  • to: A KeyPath of another dependency in Dependencies that serves as a reference value.
Clone this wiki locally