Skip to content

Instantly share code, notes, and snippets.

@cabeca
Created December 5, 2023 12:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cabeca/d58af6e3965cdc7ed37aa2d3bea7e9d2 to your computer and use it in GitHub Desktop.
Save cabeca/d58af6e3965cdc7ed37aa2d3bea7e9d2 to your computer and use it in GitHub Desktop.
example1
```swift
public class AccountViewModel: ObservableObject {
// swiftlint:disable:next line_length
public typealias Services = MilestonesAccountSectionViewModel.Services & ProfileAccountSectionViewModel.Services & ReservationsAccountSectionViewModel.Services & ContactUsAccountSectionViewModel.Services & FooterAccountSectionViewModel.Services & AboutUsAccountSectionViewModel.Services
public typealias Context = ProfileAccountSectionViewModel.Context & ReservationsAccountSectionViewModel.Context & FooterAccountSectionViewModel.Context
enum Route: Equatable {
case milestones(MilestonesAccountSectionViewModel.Route)
case profile(ProfileAccountSectionViewModel.Route)
case reservations(ReservationsAccountSectionViewModel.Route)
case preferences(PreferencesAccountSectionViewModel.Route)
case contactUs(ContactUsAccountSectionViewModel.Route)
case footer(FooterAccountSectionViewModel.Route)
case aboutUs(AboutUsAccountSectionViewModel.Route)
}
let milestonesAccountSectionViewModel: MilestonesAccountSectionViewModel
let profileAccountSectionViewModel: ProfileAccountSectionViewModel
let reservationsAccountSectionViewModel: ReservationsAccountSectionViewModel
let preferencesAccountSectionViewModel: PreferencesAccountSectionViewModel
let aboutUsAccountSectionViewModel: AboutUsAccountSectionViewModel
let contactUsAccountSectionViewModel: ContactUsAccountSectionViewModel
let footerAccountSectionViewModel: FooterAccountSectionViewModel
@Published var route: Route?
@Dependency(\.featuresStore.milestonesEnabled) var milestonesEnabled
private let services: Services
private let context: Context
public init(
services: Services,
context: Context,
onSignout: @escaping () -> Void
) {
self.services = services
self.context = context
self.milestonesAccountSectionViewModel = MilestonesAccountSectionViewModel(
services: services
)
self.profileAccountSectionViewModel = ProfileAccountSectionViewModel(
services: services,
context: context
)
self.reservationsAccountSectionViewModel = ReservationsAccountSectionViewModel(
services: services,
context: context
)
self.preferencesAccountSectionViewModel = PreferencesAccountSectionViewModel()
self.aboutUsAccountSectionViewModel = AboutUsAccountSectionViewModel(
services: services
)
self.contactUsAccountSectionViewModel = ContactUsAccountSectionViewModel(
services: services
)
self.footerAccountSectionViewModel = FooterAccountSectionViewModel(
services: services,
context: context,
onSignout: onSignout
)
bind(&$route, case: /Route.milestones, to: &milestonesAccountSectionViewModel.$route)
bind(&$route, case: /Route.profile, to: &profileAccountSectionViewModel.$route)
bind(&$route, case: /Route.reservations, to: &reservationsAccountSectionViewModel.$route)
bind(&$route, case: /Route.preferences, to: &preferencesAccountSectionViewModel.$route)
bind(&$route, case: /Route.contactUs, to: &contactUsAccountSectionViewModel.$route)
bind(&$route, case: /Route.footer, to: &footerAccountSectionViewModel.$route)
bind(&$route, case: /Route.aboutUs, to: &aboutUsAccountSectionViewModel.$route)
}
// MARK: - URLActions
public func receive(urlAction: URLAction) {
switch urlAction {
case .account:
break
case .milestones:
milestonesAccountSectionViewModel.receive(urlAction: urlAction)
case .showPlan, .verifyAndChangeEmail, .offersAndPromotions, .inviteAFriend:
profileAccountSectionViewModel.receive(urlAction: urlAction)
case .drivingHabits:
reservationsAccountSectionViewModel.receive(urlAction: urlAction)
case .carKeyIcon, .appIcon:
preferencesAccountSectionViewModel.receive(urlAction: urlAction)
case .stations:
aboutUsAccountSectionViewModel.receive(urlAction: urlAction)
default:
break
}
}
}
import Combine
import SwiftUINavigation
/// Use this function to bind a child view model route enum into a case of a parent view model route enum
/// - Parameters:
/// - parentRoutePublisher: The parent route publisher
/// - casePath: The case of the parent route
/// - childRoutePublisher: The child route publisher
public func bind<ChildRoute: Equatable, ParentRoute: Equatable>(
_ parentRoutePublisher: inout Published<ParentRoute?>.Publisher,
case parentCasePath: CasePath<ParentRoute, ChildRoute>,
to childRoutePublisher: inout Published<ChildRoute?>.Publisher
) {
childRoutePublisher
.map { childRoute in
childRoute.map { parentCasePath.embed($0) }
}
.removeDuplicates()
.dropFirst()
.assign(to: &parentRoutePublisher)
parentRoutePublisher
.map { parentRoute in
guard let parentRoute, let childRoute = parentCasePath.extract(from: parentRoute) else { return nil }
return childRoute
}
.removeDuplicates()
.assign(to: &childRoutePublisher)
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment