如何在 Swift 的 didReceiveRemoteNotification 上从 App Delegate 推送视图控制器?

How to push a view controller from App Delegate on didReceiveRemoteNotification in Swift?

我找不到任何明确的答案,我开始挣扎。到目前为止,我最接近的是 present 所需的视图控制器,但显然它是模态显示的,而不是标签栏或导航栏。

我的 AppDelegate 中有 didReceiveRemoteNotification 函数来尝试处理 Firebase 推送通知。本质上,我希望能够根据我在 Firebase 控制台上分配的键值对自动切换到我的应用程序中的特定视图控制器。

到目前为止,我的 App Delegate 如下所示:

AppDelegate

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        let info = userInfo as NSDictionary
        let name: String = info.value(forKey: "view-controller") as! String

    switch name {
    case "controller1":
        print("controller1")
        let storyBoard = UIStoryboard.getMainStoryboard().instantiateInitialViewController()
        UIApplication.shared.delegate!.window!!.rootViewController = storyBoard
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            print("Time now reached")
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC
            self.window?.rootViewController?.present(controller1VC, animated: true)
        }
    default:
        print("Nothing")
    }

}

// and an extension I have...

extension UIStoryboard {
public class func getMainStoryboard() -> UIStoryboard {
    return UIStoryboard(name: "Main", bundle: nil)
}
}

如您所见,我已将 name 转换为 String,这样我就可以处理它,然后根据结果切换它。它将实例化始终是 MainMenuVC 的初始视图控制器,然后在延迟 5 秒后(这纯粹是出于测试原因而存在)我希望它推送到 Controller1VC。

AppDelegate 或 View Controller 方法?

我走对了吗?或者最好将结果传递给 MainMenuVC 并实现一些逻辑,然后执行相对简单的 performSegue

作为侧边栏,我从 Firebase 接收和读取数据非常好,我只需要让它开始运行!

提前感谢您提供任何指导。

在你的情况下,我建议将 rootVC 作为 UINavigationController 并执行

let storyboard = UIStoryboard(name: "Main", bundle: nil)

let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC

let nav = self.window?.rootViewController as! UINavigationController

nav.pushViewController(controller1VC, animated: true)

Sh_Khan 和我在这个帖子中找到的答案的帮助下,我设法让它按照我的需要工作:

我的初始视图控制器是一个 tabBar,因此,这对我来说是正确的代码:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    let info = userInfo as NSDictionary
    let name: String = info.value(forKey: "view-controller") as! String

    switch name {
    case "controller1":
            let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
            let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC
            let tabBar = self.window?.rootViewController as? UITabBarController
            let nav = tabBar?.selectedViewController as? UINavigationController
            nav?.pushViewController(controller1VC, animated: true)
    default:
        print("Nothing")
    }
}

因此,这段代码实际上会将 tabBar 转换为 UINavigationController,从而使 pushViewController 能够正常工作。

我希望这对其他人有帮助。