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

Ios 如何在通知单击时重定向到特定的ViewController?,ios,swift,push-notification,Ios,Swift,Push Notification,我想在用户点击推送通知后重定向到特定屏幕。为此,我尝试了下面的代码并成功呈现了视图,但在将特定视图设置为RootViewController后,我无法使用应用程序导航流 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBac

我想在用户点击推送通知后重定向到特定屏幕。为此,我尝试了下面的代码并成功呈现了视图,但在将特定视图设置为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)
}
func应用程序(application:UIApplication,DidReceiveMemoteNotification用户信息:[AnyHashable:Any],fetchCompletionHandler completionHandler:@escaping(UIBackgroundFetchResult)->Void){
//让alertMsg=(userInfo[“aps”]as!NSDictionary)[“alert”]as!NSDictionary
//让payload=userInfo[“sendbird”]作为!NSDictionary
//APS数据
如果让apsData=userInfo[“aps”]作为字典{
打印(apsData)
}
//用户数据
如果让userData=userInfo[“用户详细信息”]作为字典{
打印(用户数据)
}
//通知数据
如果让notificationData=userInfo[“通知详细信息”]作为字典{
打印(通知数据)
将nNotificationType=notificationData[“通知类型”]设为!Int
让nNotificationID=notificationData[“通知\u id”]as!Int
}
让故事板:UIStoryboard=UIStoryboard(名称:“组”,捆绑:nil)
如果Device.IS_IPHONE_X{
让controller=storyBoard.instanceeviewcontroller(标识符为:“GroupInfoViewController\uiPhonex”)作为!GroupInfoViewController
让navController=UINavigationController.init(rootViewController:controller)
}
否则{
让controller=storyBoard.instanceeviewcontroller(标识符为:“GroupInfoViewController\uiPhone8”)作为!GroupInfoViewController
让navController=UINavigationController.init(rootViewController:controller)
}
//您的自定义数据解析方法
completionHandler(UIBackgroundFetchResult.newData)
}
请指导我如何在点击通知移动到特定ViewController后使用普通应用程序导航。和android应用程序一样


请指导我创建如下函数:

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])


}

创建如下函数:

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])


}
使用“推送”或“显示”将一个视图控制器传递给另一个视图控制器


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

经过一些研发后,我找到了一个工作解决方案,可以在通知点击时移动到特定的控制器,点击PRESENTED或push
视图控制器

这是工作代码

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
    }
}

经过一些研究和开发,我找到了一个有效的解决方案,即在点击显示的或按下的视图控制器时移动到特定的控制器

这是工作代码

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
    }
}


您可以在ViewDiLoad/ViewDidDisplay中从根视图控制器推送特定的视图控制器。@mumu,您的意思是说我在初始控制器中编写代码来推送特定的控制器?是的,我是说@kuldeep@mumu,让我试试这个。你可以在viewDidload/ViewDidDisplay中从根视图控制器推送特定的视图控制器。@mumu,你的意思是说我在初始控制器中编写代码以推送到特定的控制器?是的,我的意思是@kuldeep@mumu,让我试试这个。我得到了这个错误:类型“DispatchQueue”没有成员“delay”@Kuldeep…哦,对不起,这是创建的扩展。你可以使用普通的
DispatchQueue
方法。它只在推送的控制器中工作,但在呈现的控制器中不工作。如何在呈现的控制器中执行此操作?@Kuldeep…呈现良好的控制器不在层次结构中。您需要为此做些什么吗?您可以为我提供一些指导吗?我收到了此错误:类型“DispatchQueue”没有成员“delay”@Kuldeep…哦,对不起,这是创建的扩展,您可以使用普通的
DispatchQueue
方法它只在被推送的控制器中起作用,但在被呈现的控制器中不起作用。如何在呈现的控制器中执行此操作?@Kuldeep…呈现良好的控制器不在层次结构中。您需要为此做些什么,您能给我一些指导吗?