Skip to content

Commit

Permalink
0172
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrandonw committed Dec 21, 2021
1 parent 87f67ea commit 0d018da
Show file tree
Hide file tree
Showing 35 changed files with 3,004 additions and 0 deletions.
7 changes: 7 additions & 0 deletions 0172-modularization-pt2/Inventory/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
77 changes: 77 additions & 0 deletions 0172-modularization-pt2/Inventory/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// swift-tools-version:5.5

import PackageDescription

let package = Package(
name: "Inventory",
platforms: [.iOS(.v15)],
products: [
.library(name: "AppFeature", targets: ["AppFeature"]),
.library(name: "InventoryFeature", targets: ["InventoryFeature"]),
.library(name: "ItemFeature", targets: ["ItemFeature"]),
.library(name: "ItemRowFeature", targets: ["ItemRowFeature"]),
.library(name: "Models", targets: ["Models"]),
.library(name: "ParsingHelpers", targets: ["ParsingHelpers"]),
.library(name: "SwiftUIHelpers", targets: ["SwiftUIHelpers"])
],
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "0.7.0"),
.package(url: "https://github.com/pointfreeco/swift-identified-collections", from: "0.3.2"),
.package(url: "https://github.com/pointfreeco/swift-parsing", from: "0.3.1"),
],
targets: [
.target(
name: "AppFeature",
dependencies: [
"InventoryFeature",
"Models",
"ParsingHelpers",
.product(name: "Parsing", package: "swift-parsing"),
]
),
.target(
name: "InventoryFeature",
dependencies: [
"ItemRowFeature",
"Models",
"ParsingHelpers",
"SwiftUIHelpers",
.product(name: "CasePaths", package: "swift-case-paths"),
.product(name: "Parsing", package: "swift-parsing"),
.product(name: "IdentifiedCollections", package: "swift-identified-collections"),
]
),
.target(
name: "ItemFeature",
dependencies: [
"Models",
"SwiftUIHelpers",
.product(name: "CasePaths", package: "swift-case-paths"),
]
),
.target(
name: "ItemRowFeature",
dependencies: [
"ItemFeature",
"Models",
"ParsingHelpers",
"SwiftUIHelpers",
.product(name: "CasePaths", package: "swift-case-paths"),
.product(name: "Parsing", package: "swift-parsing"),
]
),
.target(name: "Models"),
.target(
name: "ParsingHelpers",
dependencies: [
.product(name: "Parsing", package: "swift-parsing")
]
),
.target(
name: "SwiftUIHelpers",
dependencies: [
.product(name: "CasePaths", package: "swift-case-paths")
]
),
]
)
3 changes: 3 additions & 0 deletions 0172-modularization-pt2/Inventory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Inventory

A description of this package.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import InventoryFeature
import ItemFeature
import ItemRowFeature
import Models
import Parsing
import ParsingHelpers
import SwiftUI

enum AppRoute {
case one
case inventory(InventoryRoute?)
case three
}

let deepLinker = PathComponent("one")
.skip(PathEnd())
.map { AppRoute.one }
.orElse(
PathComponent("inventory")
.take(inventoryDeepLinker)
.map(AppRoute.inventory)
)
.orElse(
PathComponent("three")
.skip(PathEnd())
.map { .three }
)

public enum Tab {
case one, inventory, three
}

public class AppViewModel: ObservableObject {
@Published var inventoryViewModel: InventoryViewModel
@Published var selectedTab: Tab

public init(
inventoryViewModel: InventoryViewModel = .init(),
selectedTab: Tab = .one
) {
self.inventoryViewModel = inventoryViewModel
self.selectedTab = selectedTab
}

public func open(url: URL) {
var request = DeepLinkRequest(url: url)
if let route = deepLinker.parse(&request) {
switch route {
case .one:
self.selectedTab = .one

case let .inventory(inventoryRoute):
self.selectedTab = .inventory
self.inventoryViewModel.navigate(to: inventoryRoute)

case .three:
self.selectedTab = .three
}
}
}
}

public struct ContentView: View {
@ObservedObject var viewModel: AppViewModel

public init(viewModel: AppViewModel) {
self.viewModel = viewModel
}

public var body: some View {
TabView(selection: self.$viewModel.selectedTab) {
Button("Go to 2nd tab") {
self.viewModel.selectedTab = .inventory
}
.tabItem { Text("One") }
.tag(Tab.one)

NavigationView {
InventoryView(viewModel: self.viewModel.inventoryViewModel)
}
.tabItem { Text("Inventory") }
.tag(Tab.inventory)

Text("Three")
.tabItem { Text("Three") }
.tag(Tab.three)
}
.onOpenURL { url in
self.viewModel.open(url: url)
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(viewModel: .init(selectedTab: .inventory))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Combine
import InventoryFeature
import UIKit

public class ContentViewController: UITabBarController {
let viewModel: AppViewModel
private var cancellables: Set<AnyCancellable> = []

public init(viewModel: AppViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override public func viewDidLoad() {
super.viewDidLoad()

let oneLabel = UILabel()
oneLabel.text = "One"
oneLabel.sizeToFit()

let one = UIViewController()
one.tabBarItem.title = "One"
one.view.addSubview(oneLabel)
oneLabel.center = one.view.center

let inventory = UINavigationController(
rootViewController: InventoryViewController(
viewModel: self.viewModel.inventoryViewModel
)
)
inventory.tabBarItem.title = "Inventory"

let threeLabel = UILabel()
threeLabel.text = "Three"
threeLabel.sizeToFit()

let three = UIViewController()
three.tabBarItem.title = "Three"
three.view.addSubview(threeLabel)
threeLabel.center = three.view.center

self.setViewControllers([one, inventory, three], animated: false)

self.viewModel.$selectedTab
.sink { [unowned self] tab in
switch tab {
case .one:
self.selectedIndex = 0
case .inventory:
self.selectedIndex = 1
case .three:
self.selectedIndex = 2
}
}
.store(in: &self.cancellables)
}

override public func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
guard let index = tabBar.items?.firstIndex(of: item)
else { return }

switch index {
case 0:
self.viewModel.selectedTab = .one
case 1:
self.viewModel.selectedTab = .inventory
case 2:
self.viewModel.selectedTab = .three
default:
break
}
}
}
Loading

0 comments on commit 0d018da

Please sign in to comment.