使用 SwiftUI 接收 APNS 后显示视图

Display a view after receiving APNS with SwiftUI

我想在我的应用程序收到 APNS 推送通知后显示一个视图。我正在使用 SwiftUI。我按照本教程 (https://blckbirds.com/post/how-to-navnigate-between-views-in-swiftui-by-using-an-environmentobject/) 创建了一个 motherView 和一个 ViewRouter。

MotherView 看起来像这样:

struct MotherView: View {

//    MARK: - Properties
    @EnvironmentObject var viewRouter: ViewRouter
    @State private var isMenuVisible: Bool = false

    var body: some View {
        VStack {
            if viewRouter.currentPage == Constants.Views.login {
                Login_SwiftUIView()
            } else if viewRouter.currentPage == Constants.Views.main {
                MainView(withMenu: $isMenuVisible)
            } else if viewRouter.currentPage == Constants.Views.menu {
                Menu_SwiftUI(withMenu: $isMenuVisible)
            } else if viewRouter.currentPage == Constants.Views.push {
                PushView()
            }
        }
    }
}

ViewRouter 是一个 ObservableObjectClass

class ViewRouter: ObservableObject {

    let objectWillChange = PassthroughSubject<ViewRouter,Never>()

    var currentPage: Constants.Views = Constants.Views.login {
        didSet {
            objectWillChange.send(self)
        }
    }
}

AppDelegate 在收到推送通知后调用此函数:

func presentView(with pushNotification: [String: AnyObject]) {
    //Here I want to set the viewRouter.currentPage = Constants.View.push
}

你对解决这个问题有什么建议?

这是可能的方法。

1) 在 ViewRouter 中使用原生 Combine 发布作为

class ViewRouter: ObservableObject {
    @Published var currentPage: Constants.Views = Constants.Views.login
}

2) 在AppDelegate

中创建ViewRouter的成员实例
class AppDelegate {
   var viewRouter = ViewRouter()

...

func presentView(with pushNotification: [String: AnyObject]) {
    // set here new value
    self.viewRouter.currentPage = Constants.View.push

}

3) 在 SceneDelegate 中使用 AppDelegate 中的 viewRouter 作为 ContentView 的环境对象(或 MotherView,如果将其用作根视图)

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {

            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let contentView = ContentView().environmentObject(appDelegate.viewRoute)

            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)

因此,您使用一个 ViewRouteAppDelegate 中修改并在 MotherView 中处理的对象。