Skip to content

PathBuilders

ohitsdaniel edited this page Feb 19, 2021 · 9 revisions

PathBuilders

Namespace enum for all available PathBuilders

public enum PathBuilders

Properties

empty

The empty PathBuilder does not build any screen and just returns nil for all screens.

var empty: _PathBuilder<Never>

The .empty PathBuilder can be used as a stub value.

Methods

anyOf(_:_:)

static func anyOf<A, B, ABuilder: PathBuilder, BBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder) -> _PathBuilder<EitherAB<A, B>> where ABuilder.Content == A, BBuilder.Content == B
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:)

static func anyOf<A, B, C, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder) -> _PathBuilder<EitherABC<A, B, C>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:)

static func anyOf<A, B, C, D, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder) -> _PathBuilder<EitherABCD<A, B, C, D>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:)

static func anyOf<A, B, C, D, E, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder) -> _PathBuilder<EitherABCDE<A, B, C, D, E>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:_:)

static func anyOf<A, B, C, D, E, F, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder, FBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder, _ f: FBuilder) -> _PathBuilder<EitherABCDEF<A, B, C, D, E, F>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E, FBuilder.Content == F
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:_:_:)

static func anyOf<A, B, C, D, E, F, G, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder, FBuilder: PathBuilder, GBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder, _ f: FBuilder, _ g: GBuilder) -> _PathBuilder<EitherABCDEFG<A, B, C, D, E, F, G>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E, FBuilder.Content == F, GBuilder.Content == G
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:_:_:_:)

static func anyOf<A, B, C, D, E, F, G, H, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder, FBuilder: PathBuilder, GBuilder: PathBuilder, HBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder, _ f: FBuilder, _ g: GBuilder, _ h: HBuilder) -> _PathBuilder<EitherABCDEFGH<A, B, C, D, E, F, G, H>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E, FBuilder.Content == F, GBuilder.Content == G, HBuilder.Content == H
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:_:_:_:_:)

static func anyOf<A, B, C, D, E, F, G, H, I, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder, FBuilder: PathBuilder, GBuilder: PathBuilder, HBuilder: PathBuilder, IBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder, _ f: FBuilder, _ g: GBuilder, _ h: HBuilder, _ i: IBuilder) -> _PathBuilder<EitherABCDEFGHI<A, B, C, D, E, F, G, H, I>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E, FBuilder.Content == F, GBuilder.Content == G, HBuilder.Content == H, IBuilder.Content == I
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

anyOf(_:_:_:_:_:_:_:_:_:_:)

static func anyOf<A, B, C, D, E, F, G, H, I, J, ABuilder: PathBuilder, BBuilder: PathBuilder, CBuilder: PathBuilder, DBuilder: PathBuilder, EBuilder: PathBuilder, FBuilder: PathBuilder, GBuilder: PathBuilder, HBuilder: PathBuilder, IBuilder: PathBuilder, JBuilder: PathBuilder>(_ a: ABuilder, _ b: BBuilder, _ c: CBuilder, _ d: DBuilder, _ e: EBuilder, _ f: FBuilder, _ g: GBuilder, _ h: HBuilder, _ i: IBuilder, _ j: JBuilder) -> _PathBuilder<EitherABCDEFGHIJ<A, B, C, D, E, F, G, H, I, J>> where ABuilder.Content == A, BBuilder.Content == B, CBuilder.Content == C, DBuilder.Content == D, EBuilder.Content == E, FBuilder.Content == F, GBuilder.Content == G, HBuilder.Content == H, IBuilder.Content == I, JBuilder.Content == J
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.builder(store: settingsStore),
    DetailScreen.builder(store: detailStore)
  )
)
...

If a screen can have more than one possible successor, the AnyOf PathBuilder allows to branch out. In the example, the Home Screen can either route to the Settings or the Detail screen. We express these two possible routing paths by passing an anyOf PathBuilder as a nesting argument.

Read AnyOf PathBuilders as "any of the listed PathBuilder builds the path". Given our example, the settings and the detail screen can follow after the home screen. AnyOf allows us to branch out in this case. The resulting app routing tree would be:

          -- Settings
  Home ---
          -- Detail

Keep in mind, that the order of the listed PathBuilders matters. The first PathBuilders that can handle the path will build it.

⚠️ The anyOf PathBuilder is limited to 10 elements, stack .anyOf PathBuilders if a screen can be followed up by more than ten screens ⚠️

 .screen(
   //  ...
     nesting: .anyOf(
       .anyOf(
       // ... up to 10 `PathBuilder`s here
       ),
       .anyOf(
       // ... the other `PathBuilder`s
       )
     )
 )
...

conditional(either:or:basedOn:)

The conditional PathBuilder controls which PathBuilder is reponsible for building the routing path based on condition. In some cases, you want to make sure that the user will never be able to reach certain parts of your application. For example, you might want to show a login screen as long the user hasn't logged in. For these cases, you can use a conditional PathBuilders.

static func conditional<If: PathBuilder, Else: PathBuilder>(either: If, or: Else, basedOn condition: @escaping () -> Bool) -> some PathBuilder

Example

  .conditional(
    either: HomeScreen.builder(store: homeStore),
    or: LoginScreen.builder(store: loginStore),
    basedOn: { user.isLoggedIn }
  )

The example here would never built routing paths using the HomeScreen.nuilder if the user isn't logged in. The condition is checked on each change of the routing path.

Parameters

  • either: PathBuilder used to build the routing path, if the condition is true.
  • or: PathBuilder used to build the routing path, if the condition is false.
  • basedOn: Condition evaluated every time the routing path is built.

`if`(_:then:)

The if PathBuilder controls which PathBuilder is reponsible for building the routing path based on condition.

static func `if`<If: PathBuilder>(_ condition: @escaping () -> Bool, then builder: If) -> _PathBuilder<EitherAB<If.Content, Never>>

In some cases, you want to make sure that the user will never be able to reach certain parts of your application. For example, you might want to show a login screen as long the user hasn't logged in. For these cases, you can use a conditional PathBuilders.

Example

.if(
 { user.isLoggedIn },
 then: HomeScreen.builder(store: homeStore)
)

The example here would never built routing paths using the HomeScreen.nuilder if the user isn't logged in. The condition is checked on each change of the routing path.

Parameters

  • condition: Condition evaluated every time the routing path is built.
  • then: PathBuilder used to build the routing path, if the condition is true.

`if`(_:then:else:)

The if PathBuilder controls which PathBuilder is reponsible for building the routing path based on condition.

static func `if`<If: PathBuilder, Else: PathBuilder>(_ condition: @escaping () -> Bool, then thenBuilder: If, else elseBuilder: Else) -> _PathBuilder<EitherAB<If.Content, Else.Content>>

In some cases, you want to make sure that the user will never be able to reach certain parts of your application. For example, you might want to show a login screen as long the user hasn't logged in. For these cases, you can use a conditional PathBuilders.

Example

.if(
 { user.isLoggedIn },
 then: HomeScreen.builder(store: homeStore),
 else: LoginScreen.builder(store: loginStore)
)

The example here would never built routing paths using the HomeScreen.nuilder if the user isn't logged in. The condition is checked on each change of the routing path.

Parameters

  • condition: Condition evaluated every time the routing path is built.
  • then: PathBuilder used to build the routing path, if the condition is true.
  • else: PathBuilder used to build the routing path, if the condition is false.

`if`(`let`:then:else:)

The ifLet PathBuilder unwraps an optional value and provides it to the PathBuilder defining closure.

static func `if`<LetContent, If: PathBuilder, Else: PathBuilder>(`let`: @escaping () -> LetContent?, then: @escaping (LetContent) -> If, else: Else) -> _PathBuilder<EitherAB<If.Content, Else.Content>>

Example

.if(
   let: { store.detailStore },
   then: { detailStore in
     DetailScreen.builder(store: detailStore)
   },
    else: // fallback if the value is not set.
)

Parameters

  • let: Closure unwrapping a value.
  • then: Closure defining the PathBuilder based on the unwrapped screen object.
  • else: Fallback pathbuilder used if the screen cannot be unwrapped.

`if`(`let`:then:)

The ifLet PathBuilder unwraps an optional value and provides it to the PathBuilder defining closure.

static func `if`<LetContent, If: PathBuilder>(`let`: @escaping () -> LetContent?, then: @escaping (LetContent) -> If) -> _PathBuilder<EitherAB<If.Content, Never>>

Example

.if(
   let: { store.detailStore },
   then: { detailStore in
     DetailScreen.builder(store: detailStore)
   },
    else: // fallback if the value is not set.
)

Parameters

  • let: Closure unwrapping a value.
  • then: Closure defining the PathBuilder based on the unwrapped screen object.

`if`(screen:else:)

The if screen PathBuilder unwraps a screen, if the path element matches the screen type, and provides it to the PathBuilder defining closure.

static func `if`<S: Screen, If: PathBuilder, Else: PathBuilder>(screen pathBuilder: @escaping (S) -> If, else: Else) -> _PathBuilder<EitherAB<If.Content, Else.Content>>
.if(
 screen: { (screen: DetailScreen) in
   DetailScreen.builder(store.detailStore(for: screen.id))
 },
 else: // fallback
)

Parameters

  • screen: Closure defining the PathBuilder based on the unwrapped screen object.
  • else: Fallback pathbuilder used if the screen cannot be unwrapped.

`if`(screen:)

The if screen PathBuilder unwraps a screen, if the path element matches the screen type, and provides it to the PathBuilder defining closure.

static func `if`<S: Screen, If: PathBuilder>(screen pathBuilder: @escaping (S) -> If) -> _PathBuilder<EitherAB<If.Content, Never>>
.if(
 screen: { (screen: DetailScreen) in
   DetailScreen.builder(store.detailStore(for: screen.id))
 }
)

Parameters

  • screen: Closure defining the PathBuilder based on the unwrapped screen object.

screen(onAppear:content:nesting:)

PathBuilder responsible for a single screen.

static func screen<S: Screen, Content: View, SuccessorBuilder: PathBuilder, Successor>(onAppear: @escaping (Bool) -> Void = { _ in }, content build: @escaping (S) -> Content, nesting: SuccessorBuilder) -> _PathBuilder<Routed<Content, Successor>> where SuccessorBuilder.Content == Successor

The screen PathBuilder describes how a single screen is built. The content closure is only called if the path element's content of type HomeScreen.

Example

 PathBuilder.screen(
  content: { (screen: HomeScreen) in
    HomeView(...)
  },
   nesting: ...
)

The Home screen builder extracts HomeScreen instances from the routing path and uses it's nesting PathBuilder to build the remaining path.

Parameters

  • onAppear: Called whenever the screen appears. The passed bool is true, if it is the screens initial appear.
  • content: Closure describing how to build a SwiftUI view given the screen data.
  • nesting: Any PathBuilder that can follow after this screen

screen(onAppear:content:)

PathBuilder responsible for a single screen.

static func screen<S: Screen, Content: View>(onAppear: @escaping (Bool) -> Void = { _ in }, content build: @escaping (S) -> Content) -> _PathBuilder<Routed<Content, Never>>

The screen PathBuilder describes how a single screen is built. The content closure is only called if the path element's content of type HomeScreen.

Example

 PathBuilder.screen(
  content: { (screen: HomeScreen) in
    HomeView(...)
  }
 )

The Home screen builder extracts HomeScreen instances from the routing path and uses it's nesting PathBuilder to build the remaining path.

Parameters

  • onAppear: Called whenever the screen appears. The passed bool is true, if it is the screens initial appear.
  • content: Closure describing how to build a SwiftUI view given the screen data.

screen(_:onAppear:content:nesting:)

Creates a PathBuilder responsible for a single screen.

static func screen<S: Screen, Content: View, SuccessorBuilder: PathBuilder, Successor>(_ type: S.Type, onAppear: @escaping (Bool) -> Void = { _ in }, content build: @escaping () -> Content, nesting: SuccessorBuilder) -> _PathBuilder<Routed<Content, Successor>> where SuccessorBuilder.Content == Successor

The screen PathBuilder describes how a single screen is built. The content closure is only called if the path element's content of type HomeScreen.

Example

PathBuilder.screen(
  HomeScreen.self,
  content: {
    HomeView(...)
  },
  nesting: ...
)

The Home screen builder extracts HomeScreen instances from the routing path and uses it's nesting PathBuilder to build the remaining path.

Parameters

  • type: Defines which screens are handled by the PathBuilder.
  • onAppear: Called whenever the screen appears. The passed bool is true, if it is the screens initial appear.
  • content: Closure describing how to build a SwiftUI view, if the current path element is of the defined screen type.
  • nesting: Any PathBuilder that can follow after this screen

screen(_:onAppear:content:)

PathBuilder responsible for a single screen.

static func screen<S: Screen, Content: View>(_ type: S.Type, onAppear: @escaping (Bool) -> Void = { _ in }, content build: @escaping () -> Content) -> _PathBuilder<Routed<Content, Never>>

The screen PathBuilder describes how a single screen is built. The content closure is only called if the path element's content of type HomeScreen.

Example

PathBuilder.screen(
  HomeScreen.self,
  content: {
    HomeView(...)
  }
)

The Home screen builder extracts HomeScreen instances from the routing path and uses it's nesting PathBuilder to build the remaining path.

Parameters

  • type: Defines which screens are handled by the PathBuilder.
  • onAppear: Called whenever the screen appears. The passed bool is true, if it is the screens initial appear.
  • content: Closure describing how to build a SwiftUI view, if the current path element is of the defined screen type.

wildcard(screen:pathBuilder:)

Wildcard PathBuilders replace any screen with a predefined one.

static func wildcard<S: Screen, ContentBuilder: PathBuilder, Content>(screen: S, pathBuilder: ContentBuilder) -> _PathBuilder<WildcardView<Content,S>> where ContentBuilder.Content == Content

Based on the example for the conditional PathBuilder, you might run into a situation in which your deeplink parser parses a routing path that can only be handled by the homeScreenBuilder. This would lead to an empty application, which is unfortunate.

To mitigate this problem, you can combine a conditional PathBuilder with a wildcard PathBuilder:

.conditional(
    either: .wildcard(
        screen: HomeScreen(),
        pathBuilder: HomeScreen.builder(store: homeStore)
    ),
    or: wildcard(
        screen: LoginScreen(),
        loginScreen(store: loginStore)
   ),
    basedOn: { user.isLoggedIn }
)

This is example basically states: Whatever path I get, the first element should be a defined screen.

⚠️ Warning ⚠️

If you use a wildcard PathBuilder in as part of an anyOf PathBuilder, make sure it is the last one in the list. If it isn't, it will swallow all screens and the PathBuilders listed after the wildcard will be ignored.

Parameters

  • screen: The screen that replaces the current path element.
  • pathBuilder: The PathBuilder used to build the altered path.

ifLetStore(store:then:else:)

A PathBuilder that safely unwraps a store of optional state in order to show one of two views.

static func ifLetStore<State: Equatable, Action, If, Else, IfBuilder: PathBuilder, ElseBuilder: PathBuilder>(store: Store<State?, Action>, then: @escaping (Store<State, Action>) -> IfBuilder, else: ElseBuilder) -> _PathBuilder<EitherAB<If, Else>> where IfBuilder.Content == If, ElseBuilder.Content == Else

When the underlying state is non-nil, the then closure will be performed with a Store that holds onto non-optional state to build the routing path, and otherwise the else PathBuilder will be used.

PathBuilder.ifLetStore(
  store: store.scope(state: \SearchState.results, action: SearchAction.results),
  then: { store in DetailScreen.builder(store: store) },
  else: NotFoundScreen.builder()
)

Parameters

  • store: The store scoping to the optional state
  • then: Closure defining how to build the path building given a non-optional store
  • else: The PathBuilder used, if the scoped state is nil

ifLetStore(store:then:)

A PathBuilder that safely unwraps a store of optional state in order to show one of two views.

static func ifLetStore<State: Equatable, Action, If, IfBuilder: PathBuilder>(store: Store<State?, Action>, then: @escaping (Store<State, Action>) -> IfBuilder) -> _PathBuilder<If> where IfBuilder.Content == If

When the underlying state is non-nil, the then closure will be performed with a Store that holds onto non-optional state to build the routing path.

PathBuilder.ifLetStore(
  store: store.scope(state: \SearchState.results, action: SearchAction.results),
  then: { store in DetailScreen.builder(store: store) }
)

Parameters

  • store: The store scoping to the optional state
  • then: Closure defining how to build the path building given a non-optional store
Clone this wiki locally