Value of type 'Parsers.Map<PathComponent, Tab>' has no member 'orElse'
BrunoCerberus opened this issue · 2 comments
BrunoCerberus commented
I was just following this video https://www.pointfree.co/episodes/ep168-swiftui-navigation-the-point and got this problem
let deepLinker = PathComponent("one").map { Tab.one }
.orElse(PathComponent("inventory").map { .inventory })
.orElse(PathComponent("three").map { .three })
What should be the same equivalent for orElse
?
BrunoCerberus commented
I've found this lib provided by them as well, it works as a equivalent of previous implementation
agarrharr commented
I ended up using swift-url-routing as well. This is what I ended up with in case it's useful for anyone else.
ContentView.swift:
import SwiftUI
import URLRouting
enum InventoryRoute {
case none
case add(name: String, quantity: Int)
}
enum AppRoute {
case one
case inventory(InventoryRoute)
case three
}
let inventoryRouter = OneOf {
Route(.case(InventoryRoute.none))
Route(.case(InventoryRoute.add(name:quantity:))) {
Path { "add" }
Query {
Field("name", default: "New item")
Field("quantity", default: 1) { Digits() }
}
}
}
let appRouter = OneOf {
Route(.case(AppRoute.one)) {
Path { "one" }
}
Route(.case(AppRoute.inventory)) {
Path { "inventory" }
inventoryRouter
}
Route(.case(AppRoute.three)) {
Path { "three" }
}
}
enum Tab {
case one, inventory, three
}
class AppViewModel: ObservableObject {
@Published var inventoryViewModel: InventoryViewModel
@Published var selectedTab: Tab
init(
inventoryViewModel: InventoryViewModel = .init(),
selectedTab: Tab = .one
) {
self.inventoryViewModel = inventoryViewModel
self.selectedTab = selectedTab
}
func open(url: URL) {
do {
switch try appRouter.match(url: url) {
case .one:
selectedTab = .one
inventoryViewModel.route = nil
case let .inventory(inventoryRoute):
selectedTab = .inventory
self.inventoryViewModel.navigate(to: inventoryRoute)
case .three:
selectedTab = .three
inventoryViewModel.route = nil
}
} catch { }
}
}
extension InventoryViewModel {
func navigate(to route: InventoryRoute) {
switch route {
case .none:
self.route = nil
case let .add(name: name, quantity: quantity):
self.route = .add(ItemViewModel(item: .init(name: name, status: .inStock(quantity: quantity))))
}
}
}
struct ContentView: View {
@ObservedObject var viewModel: AppViewModel
var body: some View {
TabView(selection: $viewModel.selectedTab) {
Button("Go to Inventory") {
viewModel.selectedTab = .inventory
}
.tabItem { Text("One") }
.tag(Tab.one)
NavigationView {
InventoryView(viewModel: viewModel.inventoryViewModel)
}
.tabItem { Text("Inventory") }
.tag(Tab.inventory)
Text("Three")
.tabItem { Text("Three") }
.tag(Tab.three)
}
.onOpenURL { url in
viewModel.open(url: url)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(viewModel: .init())
}
}