IfLetStore and Effect cancellation on view disappear

The solution I came to use is somewhat a hybrid of what you've been discussing and an approach that @mbrandonw used in a TCA sample code.

Every composable feature alongside the reducer defines something like:

enum PermissionsTeardownToken: CaseIterable, Hashable {
  case locationManagerId
}

Which simply defines tokens for all long-running Effects for that reducer. So when parent to Permissions reducer decides to nil it's state out:

    case .stop:
      state.permissions = nil
      return .cancel(token: PermissionsTeardownToken.self)

Where cancel(token:) is a tiny extension on Effect:

extension Effect {
  static func cancel<T>(token: T.Type) -> Effect where T: CaseIterable, T: Hashable {
    .merge(token.allCases.map(Effect.cancel(id:)))
  }
}
3 Likes