From 92e515e2b450f170dbcc30c116e2299e050e1498 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Thu, 4 Mar 2021 18:13:30 -0800 Subject: [PATCH] Root view model per-scene --- System/MetatextApp.swift | 11 +++---- .../PreviewViewModels/PreviewViewModels.swift | 3 +- .../View Models/RootViewModel.swift | 31 +++++++++---------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/System/MetatextApp.swift b/System/MetatextApp.swift index d6288f9..28def51 100644 --- a/System/MetatextApp.swift +++ b/System/MetatextApp.swift @@ -8,8 +8,6 @@ import ViewModels @main struct MetatextApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate - // swiftlint:disable:next force_try - private let viewModel = try! RootViewModel(environment: Self.environment) init() { try? AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default) @@ -17,10 +15,11 @@ struct MetatextApp: App { } var body: some Scene { - viewModel.registerForRemoteNotifications = appDelegate.registerForRemoteNotifications - - return WindowGroup { - RootView(viewModel: viewModel) + WindowGroup { + // swiftlint:disable:next force_try + RootView(viewModel: try! RootViewModel( + environment: Self.environment, + registerForRemoteNotifications: appDelegate.registerForRemoteNotifications)) } } } diff --git a/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift b/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift index 8c855fa..3c3bd05 100644 --- a/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift +++ b/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift @@ -69,7 +69,8 @@ public extension Instance { } public extension RootViewModel { - static let preview = try! RootViewModel(environment: environment) + static let preview = try! RootViewModel(environment: environment, + registerForRemoteNotifications: { Empty().eraseToAnyPublisher() }) } public extension IdentityContext { diff --git a/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift b/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift index 592cbb5..d2bc3a0 100644 --- a/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift @@ -7,28 +7,18 @@ import ServiceLayer public final class RootViewModel: ObservableObject { @Published public private(set) var navigationViewModel: NavigationViewModel? - public var registerForRemoteNotifications: (() -> AnyPublisher)? { - didSet { - guard let registerForRemoteNotifications = registerForRemoteNotifications else { return } - - userNotificationService.isAuthorized(request: false) - .filter { $0 } - .zip(registerForRemoteNotifications()) - .map { $1 } - .flatMap(allIdentitiesService.updatePushSubscriptions(deviceToken:)) - .sink { _ in } receiveValue: { _ in } - .store(in: &cancellables) - } - } @Published private var mostRecentlyUsedIdentityId: Identity.Id? private let environment: AppEnvironment + private let registerForRemoteNotifications: () -> AnyPublisher private let allIdentitiesService: AllIdentitiesService private let userNotificationService: UserNotificationService private var cancellables = Set() - public init(environment: AppEnvironment) throws { + public init(environment: AppEnvironment, + registerForRemoteNotifications: @escaping () -> AnyPublisher) throws { self.environment = environment + self.registerForRemoteNotifications = registerForRemoteNotifications allIdentitiesService = try AllIdentitiesService(environment: environment) userNotificationService = UserNotificationService(environment: environment) @@ -42,6 +32,14 @@ public final class RootViewModel: ObservableObject { .sink { [weak self] in self?.identitySelected(id: $0) } .store(in: &cancellables) + userNotificationService.isAuthorized(request: false) + .filter { $0 } + .zip(registerForRemoteNotifications()) + .map { $1 } + .flatMap(allIdentitiesService.updatePushSubscriptions(deviceToken:)) + .sink { _ in } receiveValue: { _ in } + .store(in: &cancellables) + userNotificationService.events .sink { [weak self] in self?.handle(event: $0) } .store(in: &cancellables) @@ -128,11 +126,10 @@ private extension RootViewModel { .store(in: &self.cancellables) if identityContext.identity.authenticated, - !identityContext.identity.pending, - let registerForRemoteNotifications = self.registerForRemoteNotifications { + !identityContext.identity.pending { self.userNotificationService.isAuthorized(request: true) .filter { $0 } - .zip(registerForRemoteNotifications()) + .zip(self.registerForRemoteNotifications()) .filter { identityContext.identity.lastRegisteredDeviceToken != $1 } .map { ($1, identityContext.identity.pushSubscriptionAlerts) } .flatMap(identityContext.service.createPushSubscription(deviceToken:alerts:))