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 screen ID.

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 screen ID. If you call go(to:, on:) for a screen ID that is not associated with the last screen in the current routing path, the routing path after the screen ID 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: Screen ID used to identify where the destination should be appended

go(to:on:)

Replace the path after a given screen ID 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 screen ID. If you call go(to:, on:) for a screen ID that is not associated with the last screen in the current routing path, the routing path after the screen ID 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: Screen ID 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 screen ID. If you call go(to:, on:) for a screen ID that is not associated with the last screen in the current routing path, the routing path after the screen ID 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