如何在通知点击时重定向到特定的 ViewController?

Posted

技术标签:

【中文标题】如何在通知点击时重定向到特定的 ViewController?【英文标题】:How to redirect to a particular ViewController on Notification Click? 【发布时间】:2019-08-20 07:05:35 【问题描述】:

一旦用户点击推送通知,我想重定向到特定屏幕。为此,我尝试了以下代码并成功显示了视图,但是在将特定视图设置为 RootViewController 后,我无法使用应用导航流程。

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
    //let alertMsg = (userInfo["aps"] as! NSDictionary)["alert"] as! NSDictionary
    //let payload = userInfo["sendbird"] as! NSDictionary

    //APS DATA
    if let apsData = userInfo["aps"] as? Dictionary<String, Any> 
        print(apsData)
    

    //USER DATA
    if let userData = userInfo["user_details"] as? Dictionary<String, Any> 
        print(userData)
    

    //NOTIFICATION DATA
    if let notificationData = userInfo["notification_details"] as? Dictionary<String, Any> 
        print(notificationData)

        let nNotificationType   = notificationData["notification_type"] as! Int
        let nNotificationID     = notificationData["notification_id"] as! Int
    


    let storyBoard : UIStoryboard = UIStoryboard(name: "Group", bundle:nil)

    if Device.IS_IPHONE_X 
        let controller = storyBoard.instantiateViewController(withIdentifier: "GroupInfoViewController_iPhoneX") as! GroupInfoViewController
                let navController = UINavigationController.init(rootViewController: controller)
    
    else 
        let controller = storyBoard.instantiateViewController(withIdentifier: "GroupInfoViewController_iPhone8") as! GroupInfoViewController
                let navController = UINavigationController.init(rootViewController: controller)
    

    // Your custom way to parse data
    completionHandler(UIBackgroundFetchResult.newData)

请指导我在通知点击时移动到特定 ViewController 后如何使用正常的应用导航。和安卓应用一样。

请指导我

【问题讨论】:

您可以在 viewDidload/viewDidAppear 中从根视图控制器推送特定的视图控制器。 @mumu,你的意思是说我在初始控制器中编写代码以推送到特定控制器? 是的,我是这个意思。 @kuldeep @mumu,让我试试这个。 【参考方案1】:

经过一些研发,我找到了可行的解决方案,可以通过 PRESENTEDPUSHED ViewController 上的通知点击移动到特定控制器。

这是工作代码。

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
 DispatchQueue.main.asyncAfter(deadline: .now() + 1)  // change your delay here

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

        if Device.IS_IPHONE_X 
            let vc = storyboard.instantiateViewController(withIdentifier: "GroupInfoViewController_iPhoneX") as! GroupInfoViewController
            vc.nNotificationID = notificationID
            if let topVC = UIApplication.getTopViewController() 
                topVC.navigationController?.pushViewController(vc, animated: false)
            
        
        else 
            let vc = storyboard.instantiateViewController(withIdentifier: "GroupInfoViewController_iPhone8") as! GroupInfoViewController
            vc.nNotificationID = notificationID
            if let topVC = UIApplication.getTopViewController() 
                topVC.navigationController?.pushViewController(vc, animated: false)
            
        
       

扩展

public extension UIApplication 
    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? 

        if let nav = base as? UINavigationController 
            return getTopViewController(base: nav.visibleViewController)

         else if let tab = base as? UITabBarController, let selected = tab.selectedViewController 
            return getTopViewController(base: selected)

         else if let presented = base?.presentedViewController 
            return getTopViewController(base: presented)
        
        return base
    

【讨论】:

【参考方案2】:

创建一个这样的函数:

func handleNotification(userInfo: [String:Any]) 

         DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
            if let mainNav = AppDelegate.shared.window?.rootViewController as? UINavigationController 
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC

            mainNav.pushViewController(vc, animated: false)

        


你也可以在userInfo中传递信息,如果你想执行某些操作或者只是删除了那个参数。

并在你的 this 方法中调用这个函数

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

    print("APNs received with: \(userInfo)")
    self.handleNotification(userInfo: userInfo as! [String : Any])



【讨论】:

我收到此错误:类型“DispatchQueue”没有成员“延迟” @Kuldeep...哦,抱歉,这是创建的扩展,您可以使用普通的DispatchQueue 方法它会起作用 它只适用于那些被推送的控制器,但这不适用于那些被呈现的控制器。我怎样才能在呈现的控制器中做到这一点? @Kuldeep...精心呈现的控制器不在您需要为此做些什么的层次结构中 你能给我一些指导吗?【参考方案3】:
 let vc = storyboard.instantiateViewController(withIdentifier: "YourVC") as! 
 YourVC
 mainNav.pushViewController(vc, animated: false)

使用 push 或 present 将一个视图控制器传递给另一个视图控制器

【讨论】:

以上是关于如何在通知点击时重定向到特定的 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章

重定向以查看 IOS 通知栏中的点击推送消息

如何在mvc中单击按钮时重定向到另一个页面和特定的div

react-native-fcm点击托盘通知后如何在特定页面上重定向

点击推送通知不会重定向到特定页面

从 AppDelegate 重定向到特定屏幕:点击通知

在角度 UI 路由器中单击时重定向到相应的单个产品页面