Created
December 5, 2023 12:22
-
-
Save cabeca/d58af6e3965cdc7ed37aa2d3bea7e9d2 to your computer and use it in GitHub Desktop.
example1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
```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