如何让你的推送通知打开某个视图控制器?

How to make your push notification Open a certain view controller?

我查看了 SO,但我找不到任何讨论当您收到推送通知时如何打开特定视图控制器的问题。 例如,如果您正在创建一个像 WhatsApp 这样的应用程序,并且您收到两个不同的推送通知,即来自两个不同用户的消息,您将如何从应用程序委托定向到相应的 viewController?

据我所知,在 appDelegate 给你的 userinfo 字典中,你可以为特定的 viewController 提供一个 ID,但我不知道如何向特定的视图控制器致敬,所以然后你可以再次指向那个 viewController。 请在您的回答中附上代码片段

**** Swift 或 Objective-C 答案均可接受 ****

您可以在应用委托中使用此代码检测应用是否从通知中打开。当应用程序状态为 UIApplicationStateInactive 时,您需要在应用程序激活之前设置初始视图控制器。您可以在那里执行任何逻辑来决定应打开哪个视图控制器以及应在该视图控制器中显示哪些内容。

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    if(application.applicationState == UIApplicationStateActive) {

        //app is currently active, can update badges count here

    } else if(application.applicationState == UIApplicationStateBackground){

        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here

    } else if(application.applicationState == UIApplicationStateInactive){

        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here

        self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

        UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];

        self.window.rootViewController = viewController;
        [self.window makeKeyAndVisible];

    }

}

这是 Swift 3 版本 switch/case 而不是 if/else

    open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    switch application.applicationState {
    case .active:
        print("do stuff in case App is active")
    case .background:
        print("do stuff in case App is in background")
    case .inactive:
        print("do stuff in case App is inactive")
    }
}
//This method is called when user tap on the notification

      func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

           print("user clicked on the notification")
           let userInfo = response.notification.request.content.userInfo

           print(userInfo)

           //check your response and navigate to specific view controller
           moveToNextViewController()
      }

     func moveToNextViewController() {
    //Add code for present or push view controller
           let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewController") as! ViewController                    
          self.navigationController?.pushViewController(vc, animated: true)
    }

当用户点击通知时调用此方法。在 appdelegate

中实现
var navigationC: UINavigationController?

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    if USERDEFAULT.value(forKey: "isLogin") != nil  {
        let tabbarvc = MainStoryboard.instantiateViewController(withIdentifier: "TabBarVC") as! TabBarVC
        self.navigationC = UINavigationController(rootViewController: tabbarvc)
    }else {
        let loginvc = MainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
        self.navigationC = UINavigationController(rootViewController: loginvc)
    }

    self.navigationC?.setNavigationBarHidden(true, animated: false)
    self.window?.clipsToBounds = true
    self.window?.rootViewController = navigationC
    self.window?.makeKeyAndVisible()

    return true
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    print("-------------\nUser info in notification -> \(userInfo)\n-------------")
    let dict = userInfo["aps"] as? NSDictionary ?? [:]
    if USERDEFAULT.value(forKey:"isLogin") != nil{
        let type = dict["type"] as? Int ?? 0
        switch type {
        case 0:
            break
        case 1:
            for vc in self.navigationC!.viewControllers {
                if vc is TabBarVc {
                    let  exam = dict["exam"] as? String ?? ""
                    if exam == ""{
                        let TestVC = MainStoryboard.instantiateViewController(withIdentifier: "TestVC") as! TestVC
                        TestVC.chapterId = dict["chapter_id"] as? String ?? ""
                        TestVC.strSubTitle = dict["chapter"] as? String ?? ""
                        self.navigationC?.isNavigationBarHidden = true
                        self.navigationC?.pushViewController(TestVC, animated: true)
                    }else if exam != ""{
                        let ExamTestVC = MainStoryboard.instantiateViewController(withIdentifier: "ExamTestVC") as! ExamTestVC
                        ExamTestVC.examId = dict["exam_id"] as? String ?? ""
                        ExamTestVC.strSubTitle = dict["exam"] as? String ?? ""
                        self.navigationC?.isNavigationBarHidden = true
                        self.navigationC?.pushViewController(ExamTestVC, animated: true)
                    }
                    return;
                }
            }
            break

        case 2:
            for vc in self.navigationC!.viewControllers {
                if vc is TabBarVc {
                    let VideoListVC = MainStoryboard.instantiateViewController(withIdentifier: "VideoListVC") as! VideoListVC
                    VideoListVC.chapterId = dict["chapter_id"] as? String ?? ""
                    VideoListVC.video_id = dict["video_id"] as? String ?? ""
                    VideoListVC.strSubTitle = dict["chapter"] as? String ?? ""
                    VideoListVC.questionsCount = dict["question_count"] as? Int ?? 0
                    VideoListVC.testCount = dict["test_count"] as? Int ?? 0
                    self.navigationC?.isNavigationBarHidden = true
                    self.navigationC?.pushViewController(VideoListVC, animated: true)
                    return;
                }
            }
            break

        case 3:

            break

        default: break

        }
    }else{
        let loginVC = SignupiPadStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
        SignupStoryboard = SignupiPadStoryboard
        self.navigationC = UINavigationController(rootViewController: loginVC)
    }

}

或者您可以直接打开视图控制器,例如 whatsapp 聊天等

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
    let userInfo = notification.request.content.userInfo
    let dictAps = userInfo["aps"] as! NSDictionary
    print(dictAps)
    let notification_type = dictAps["notification_type"] as? Int ?? 0
    if notification_type == 6{
        if isChatActive == false{
            completionHandler([.alert, .badge, .sound])
        }else{
            if USERDEFAULT.value(forKey:"isLogin") != nil{
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadChatMessages"), object: nil, userInfo: (dictAps as! [AnyHashable : Any]))
            }else{
                completionHandler([.alert, .badge, .sound])
            }
        }
    }else{
        completionHandler([.alert, .badge, .sound])
    }

}