Skip to content

PathBuilders

ohitsdaniel edited this page Apr 29, 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.

static var empty: EmptyBuilder 

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

Methods

anyOf(_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

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

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 navigation 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(_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

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

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 navigation 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(_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

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

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 navigation 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(_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    ABuilder: PathBuilder,
    BBuilder: PathBuilder,
    CBuilder: PathBuilder,
    DBuilder: PathBuilder,
    EBuilder: PathBuilder
  >(
    _ a: ABuilder,
    _ b: BBuilder,
    _ c: CBuilder,
    _ d: DBuilder,
    _ e: EBuilder
  ) -> _PathBuilder<
      EitherABCDE<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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(_:_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    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<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content,
        FBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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(_:_:_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    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<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content,
        FBuilder.Content,
        GBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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(_:_:_:_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    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<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content,
        FBuilder.Content,
        GBuilder.Content,
        HBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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(_:_:_:_:_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    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<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content,
        FBuilder.Content,
        GBuilder.Content,
        HBuilder.Content,
        IBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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(_:_:_:_:_:_:_:_:_:_:)

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 navigation paths by passing an anyOf PathBuilder as a nesting argument.

static func anyOf<
    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<
        ABuilder.Content,
        BBuilder.Content,
        CBuilder.Content,
        DBuilder.Content,
        EBuilder.Content,
        FBuilder.Content,
        GBuilder.Content,
        HBuilder.Content,
        IBuilder.Content,
        JBuilder.Content
      >
    >
.screen(
//  ...
  nesting: PathBuilders.anyOf(
    SettingsScreen.Builder(store: settingsStore),
    DetailScreen.Builder(store: detailStore)
  )
)
...

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 navigation 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
       )
     )
 )
...

`if`(_:then:)

The if PathBuilder controls which PathBuilder is reponsible for building the navigation 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 navigation paths using the HomeScreen.Builder if the user isn't logged in. The condition is checked on each change of the navigation path.

Parameters

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

`if`(_:then:else:)

The if PathBuilder controls which PathBuilder is reponsible for building the navigation 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 navigation paths using the HomeScreen.Builder if the user isn't logged in. The condition is checked on each change of the navigation path.

Parameters

  • condition: Condition evaluated every time the navigation path is built.
  • then: PathBuilder used to build the navigation path, if the condition is true.
  • else: PathBuilder used to build the navigation 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,
    Successor: PathBuilder
  >(
    onAppear: @escaping (Bool) -> Void = { _ in },
    @ViewBuilder content build: @escaping (S) -> Content,
    nesting: Successor
  ) -> _PathBuilder<NavigationNode<Content, Successor.Content>> 

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

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

The Home screen builder extracts HomeScreen instances from the navigation 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 },
    @ViewBuilder content build: @escaping (S) -> Content
  ) -> _PathBuilder<NavigationNode<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

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

The Home screen builder extracts HomeScreen instances from the navigation 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,
    Successor: PathBuilder
  >(
    _ type: S.Type,
    onAppear: @escaping (Bool) -> Void = { _ in },
    @ViewBuilder content build: @escaping () -> Content,
    nesting: Successor
  ) -> _PathBuilder<NavigationNode<Content, Successor.Content>> 

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

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

The Home screen builder extracts HomeScreen instances from the navigation 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 },
    @ViewBuilder content build: @escaping () -> Content
  ) -> _PathBuilder<NavigationNode<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

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

The Home screen builder extracts HomeScreen instances from the navigation 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 navigation 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 unreachable.

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 navigation path, and otherwise the else PathBuilder will be used.

PathBuilders.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<EitherAB<If, Never>> 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 navigation path.

PathBuilders.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