Skip to content

Navigator

ohitsdaniel edited this page Feb 5, 2021 · 8 revisions

Navigator

Facade type erasing the type of the underlying datasource

public struct Navigator

Initializers

init(path:go:goToPath:goBack:replace:dismiss:dismissSuccessor:didAppear:)

public init(path: @escaping () -> [IdentifiedScreen], go: @escaping (AnyScreen, ScreenID) -> Void, goToPath: @escaping ([AnyScreen], ScreenID) -> Void, goBack: @escaping (AnyScreen) -> Void, replace: @escaping ([AnyScreen]) -> Void, dismiss: @escaping (ScreenID) -> Void, dismissSuccessor: @escaping (ScreenID) -> Void, didAppear: @escaping (ScreenID) -> Void)

init(dataSource:)

Initialises a Navigator wrapping a Datasource object

init(dataSource: Navigator.Datasource)

Parameters

  • dataSource: The wrapped data source

Properties

stub

let stub

Methods

go(to:on:)

Append a screen after a given ScreenID.

public func go<S: Screen>(to screen: S, on id: ScreenID)

go(to:, on:) appends the given screen after the screen associated with the passed ScreenID. If you call go(to:, on:) for a ScreenID that is not associated with the last screen in the current routing path, the routing path after the ScreenID is replaced with [screen] and therefore cut off.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(to: C(), on: 1)
// New path
// [(A, 0), (B, 1)], (C, 2)]

Parameters

  • screen: Destination
  • id: ScreenID used to identify where the destination should be appended

go(to:on:)

Replace the path after a given ScreenID with the passed path.

public func go(to path: [AnyScreen], on id: ScreenID)

go(to:, on:) appends the given path after the screen associated with the passed ScreenID. If you call go(to:, on:) for a ScreenID that is not associated with the last screen in the current routing path, the routing path after the ScreenID is replaced with path and potentially cut off.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]

navigator.go(
 to: [C().eraseToAnyScreen(), D().eraseToAnyScreen()],
 on: 1
)

// New path
// [(A, 0), (B, 1)], (C, 2), (D, 3)]

Parameters

  • path: New path after id
  • id: ScreenID used to identify where the destination should be appended

goBack(to:)

Go back to the last occurence of the screen instance in the routing path.

public func goBack<S: Screen>(to screen: S)

The function appends the given screen after the screen associated with the passed ScreenID. If you call go(to:, on:) for a ScreenID that is not associated with the last screen in the current routing path, the routing path after the ScreenID is replaced with [screen] and therefore cut off.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2)]

navigator.goBack(to: A())

// New path
// [(A, 0)]

Parameters

  • screen: Destination

replace(path:)

Replace the current routing path with a new routing path.

public func replace(path: AnyScreen)

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]

navigator.replace(
  path: C().eraseToAnyScreen(), D().eraseToAnyScreen()
)

// New path
// [(C, 0), (D, 1)]

Parameters

  • path: The new routing path

replace(path:)

Replace the current routing path with a new routing path.

public func replace(path: [AnyScreen])

replace(path:) checks if a prefix of the new path was already part of the replaced routing path and makes sure to keep the IDs and hasAppeared state intact.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]

navigator.replace(
  path: [
    C().eraseToAnyScreen(),
    D().eraseToAnyScreen()
  ]
)

// New path
// [(C, 0), (D, 1)]

Parameters

  • path: The new routing path

dismiss(id:)

Removes the screen from the routing path.

public func dismiss(id: ScreenID)

dismiss(id:) does not care take the screen's presentation style into account and cuts the routing path up to the passed id.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]

navigator.dismiss(id: 2)

// New path
// [(A, 0), (B, 1)]

Parameters

  • id: The id identifying the screen that needs to be dismissed

dismissSuccessor(of:)

Removes the screen successors from the routing path.

public func dismissSuccessor(of id: ScreenID)

dismissSuccessor(of id:) does not care take the screen's presentation style into account and cuts the routing path after the passed id.

Example

// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]

navigator.dismissSuccessor(of id: 2)

// New path
// [(A, 0), (B, 1), (C, 2)]

Parameters

  • id: The id identifying the screen that needs to be dismissed

mock(path:go:goToPath:goBack:replace:dismiss:dismissSuccessor:didAppear:)

static func mock(path: @escaping () -> [IdentifiedScreen] = { fatalError("path() unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, go: @escaping (AnyScreen, ScreenID) -> Void = { _, _ in fatalError("go(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, goToPath: @escaping ([AnyScreen], ScreenID) -> Void = { _, _ in fatalError("append(path:, to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, goBack: @escaping (AnyScreen) -> Void = { _ in fatalError("goBack(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, replace: @escaping ([AnyScreen]) -> Void = { _ in fatalError("replace(path:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, dismiss: @escaping (ScreenID) -> Void = { _ in fatalError("dismiss(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, dismissSuccessor: @escaping (ScreenID) -> Void = { _ in fatalError("dismissSuccessor(of:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }, didAppear: @escaping (ScreenID) -> Void = { _ in fatalError("didAppear(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.") }) -> Navigator

debug()

Enable logging received function calls and path changes.

func debug() -> Navigator
Clone this wiki locally