推送通知-使用SceneDelegate在通知点击时推送ViewController

时间:2020-01-10 04:40:35

标签: ios swift

在iOS 13之前,AppDelegate中定义了导航控制器和根视图。但是,在iOS 13中,Apple引入了SceneDelegate,它接管了这些视图功能的处理。但是,AppDelegate仍然处理诸如本地通知处理之类的事情。 See this answer for some code that outlines these changes for root views.

如果我希望在用户点击本地通知时推送视图,我将在AppDelegate中执行以下操作:

extension AppDelegate: UNUserNotificationCenterDelegate {

    var navigationController: UINavigationController?

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

        if response.actionIdentifier == UNNotificationDefaultActionIdentifier { //User taps notification
             let vc = MyViewController()
             self.navigationController?.pushViewController(vc, animated: true)
        }
    }
}

但是,由于我的项目的根导航控制器现在可以从iOS 13开始在SceneDelegate中定义,因此我似乎无法弄清楚如何在由SceneDelegate而不是AppDelegate管理的导航控制器中推送视图。

2 个答案:

答案 0 :(得分:1)

SceneDelegate可以通过以下方式处理通知响应:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
  func scene(
    _ scene: UIScene,
    willConnectTo session: UISceneSession,
    options connectionOptions: UIScene.ConnectionOptions
  ) {
    if let windowScene = scene as? UIWindowScene {
      let window = UIWindow(windowScene: windowScene)
      // rootViewController set up code
      // say,
      // let mainController = ViewController()
      // let navigationController = UINavigationController(rootViewController: mainController)
      // window.rootViewController = navigationController

      // This is UNNotificationResponse
      if let notificationResponse = connectionOptions.notificationResponse {
        window.makeKeyAndVisible()
        // do the pushing on your navigation controller
        // navigationController.push()
        return
      }

      window.makeKeyAndVisible()
    }
  }
}

答案 1 :(得分:1)

如果您的应用支持多个窗口或单个窗口,您可以使用 targetScene 上的 UNNotificationResponse 属性来确定通知将启动哪个场景(窗口)。

示例:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    guard let windowSceneDelegate = response.targetScene?.delegate as? UIWindowSceneDelegate,
          let window = windowSceneDelegate.window,
          let rootViewController = window.rootViewController as? UINavigationController else {
        completionHandler()
        return
    }
    let notificationViewController = UIViewController()
    rootViewController.pushViewController(notificationViewController, animated: true)
    completionHandler()
}