我试图弄清楚我在SwiftUI生命周期中制作的应用程序的导航。根据启动时确定的设置,用户可以从三个视图之一开始。如果用户从推送通知中打开应用程序,则他们应该看到视频视图(WrappedVideoViewController)。否则,如果他们已经登录,则应该看到“主页”视图,否则,应该看到“登录”视图。我使用ContentView作为父项:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var notifService: NotificationService
@EnvironmentObject var authState: AuthenticationState
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@ObservedObject var viewRouter: ViewRouter
init() {
self.viewRouter = ViewRouter.shared
}
var body: some View {
print("in ContentView body")
switch viewRouter.currentScreen {
case .home:
print("home")
return AnyView(Home(innerGradientColor: Color.homeActiveInner, outerGradientColor: Color.homeActiveOuter))
case .login:
print("login")
return
AnyView(Login()
.environmentObject(AuthenticationState.shared))
case .video:
print("video")
return AnyView(WrappedVideoViewController())
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(AuthenticationState.shared)
.environmentObject(NotificationService())
}
}
我的ViewRouter类是一个ObservableObject,用于控制显示哪个屏幕。目前,我有这个:
//
// NavigationState.swift
// BumpCall-SwiftUI
//
// Created by Ben on 1/22/21.
//
import Foundation
import SwiftUI
enum Screen {
case home
case video
case login
}
class ViewRouter: ObservableObject {
var authState: AuthenticationState
var notifService: NotificationService
static var shared = ViewRouter(authState: AuthenticationState.shared, notifService: NotificationService.shared)
init(authState: AuthenticationState, notifService: NotificationService) {
self.authState = authState
self.notifService = notifService
if notifService.dumbData != nil {
currentScreen = .video
} else if (notifService.dumbData == nil && authState.isLoggedIn()) {
currentScreen = .home
} else {
currentScreen = .login
}
}
@Published var currentScreen: Screen
}
这很棘手,因为ViewRouter依赖于其他两个ObservableObjects,我正在尝试使用init()处理它。看来AuthenticationState类工作正常,因为打开应用程序后,如果您登录了,它确实会将您发送到主屏幕。但是,从通知中打开也会将我发送到主屏幕。NotificationService在didReceive响应中更改ViewRouter单例:方法:
class NotificationService: NSObject, ObservableObject {
@Published var dumbData: UNNotificationResponse?
static var shared = NotificationService()
override init() {
super.init()
UNUserNotificationCenter.current().delegate = self
}
}
extension NotificationService: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("presenting notification")
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
ViewRouter.shared.notifService.dumbData = response
print("Notification service didReceive response")
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) { }
}
但是单例不得更新,以使ContentView注意到。这太令人费解了,已经使我困惑了好几天,任何帮助将不胜感激。
问题是ViewRouter
init()
将被调用一次。如前所述,当用户登录时,currentScreen
将初始化为.home
。但是,此变量以后将永远不会更改。
你基本上要,什么是一套currentScreen
以.video
通知委托内。
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
ViewRouter.shared.currentScreen = .video //<< here set video
print("Notification service didReceive response")
completionHandler()
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句