【问题标题】:How to load viewController when user tap on notification in iOS Swift?当用户在 iOS Swift 中点击通知时如何加载 viewController?
【发布时间】:2020-07-18 10:14:26
【问题描述】:

我已经在应用端使用 FCM 完成了推送通知。当用户点击通知时,它会从应用程序端导航到特定的 viewController 到自定义 SDK。我尝试了很多方法,但 viewController 没有显示,但所有功能都成功加载。

1.第一次尝试: [检测到通知点击并将数据从应用端传递到框架。加载了特定的 viewController 功能,但 viewController 没有显示。]

当用户从应用端点击通知时,它会将数据发送到框架以显示特定的 viewController。

这是应用端的代码:

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

    
    
    
    if(application.applicationState == .active){
      print("user tapped the notification bar when the app is in foreground")
    let userInfo = response.notification.request.content.userInfo
    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
    }

    // Print full message.
    print("didReceive notification tapped",userInfo)

        TaskName = userInfo[taskName] as? String ?? ""
        print("TaskName::::", TaskName ?? "")
        ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
        print("ProcessInstanceId::::", ProcessInstanceId ?? "")
        processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
        print("processDefinitionName::::", processDefinitionName ?? "")
        TaskID = userInfo[taskId] as? String ?? ""
        print("taskID::::", TaskID ?? "")
        FormKey = userInfo[formKey] as? String ?? ""
        print("FormKey::::", FormKey ?? "")
        Types = userInfo[type] as? String ?? ""
        print("Type::::", Types ?? "")
        Title = userInfo[title] as? String ?? ""
        print("Title::::", Title ?? "")
        Body = userInfo[body] as? String ?? ""
        print("Body::::", Body ?? "")
        CreatedDate = userInfo[created] as? String ?? ""
        print("created:::", CreatedDate ?? "")




        AFlowBuilder(self).callFormView(taskName: TaskName ?? "", processInstanceID: ProcessInstanceId ?? "", ProcessDefinitionName: processDefinitionName ?? "", taskId: TaskID ?? "", formKey: FormKey ?? "", title: Title ?? "", type: Types ?? "", body: Body ?? "", created: CreatedDate ?? "", formStatus: false)


    }
    completionHandler()
    
    
  }

这是框架方面的代码:

  private var taskViewNew: UIViewController?

    public func callFormView(taskName: String, processInstanceID: String, ProcessDefinitionName: String, taskId: String, formKey: String, title: String, type: String, body: String, created: String, formStatus: Bool){
    

    
    let newNotification = makeSaveNotification(taskName: taskName, processInstanceID: processInstanceID, ProcessDefinitionName: ProcessDefinitionName, taskId: taskId, formKey: formKey, title: title, type: type, body: body, created: created, formStatus: formStatus)
    
    let realm = try! Realm()
    //        let realmData = realm.objects(NotificationRealmModel.self).filter("name = \(userNameRealm ?? "")").first!

            try! realm.write {
                realm.add(newNotification)
                print("ream notification saved path url:: call form view", realm.configuration.fileURL ?? "")



}

                    let controller = CreateCardViewController()
    
                    let str = formKey
                    let result = String(str.dropFirst(7))
                    print(result)
                    let s = String(result.dropLast(10))
                    print("newFormKey call form view", s )
                    let v = convap(text: s)
                    controller.processInstanceId = processInstanceID
                    controller.cardName = ""
                    controller.TaskIdValue = taskId
                    controller.formKey = v
                    controller.tabName = "NotificationTapped"
                    controller.fullFormKey = formKey
                    
                
                    self.taskViewNew?.addChild(controller)
                    self.taskViewNew?.view.addSubview(controller.view)
                    controller.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

  //                        controller.didMove(toParent: taskViewNew)
                    taskViewNew?.present(controller, animated: true, completion: nil)

                    
                    

}
  1. 第二次尝试:[在应用端检测到通知并将值传递给 viewController。并且,调用Inside viewController框架方法加载框架viewController但所有功能加载成功但视图未加载]

这是应用端的代码:

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

    
    
    
    if(application.applicationState == .active){
      print("user tapped the notification bar when the app is in foreground")
    let userInfo = response.notification.request.content.userInfo
    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
    }

    // Print full message.
    print("didReceive notification tapped",userInfo)

        TaskName = userInfo[taskName] as? String ?? ""
        print("TaskName::::", TaskName ?? "")
        ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
        print("ProcessInstanceId::::", ProcessInstanceId ?? "")
        processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
        print("processDefinitionName::::", processDefinitionName ?? "")
        TaskID = userInfo[taskId] as? String ?? ""
        print("taskID::::", TaskID ?? "")
        FormKey = userInfo[formKey] as? String ?? ""
        print("FormKey::::", FormKey ?? "")
        Types = userInfo[type] as? String ?? ""
        print("Type::::", Types ?? "")
        Title = userInfo[title] as? String ?? ""
        print("Title::::", Title ?? "")
        Body = userInfo[body] as? String ?? ""
        print("Body::::", Body ?? "")
        CreatedDate = userInfo[created] as? String ?? ""
        print("created:::", CreatedDate ?? "")

     }

          window = UIWindow(frame: UIScreen.main.bounds)
             let homeViewController = ViewController()
             homeViewController.Body = Body
             homeViewController.CreatedDate = CreatedDate
             homeViewController.FormKey = FormKey
             homeViewController.processDefinitionName = processDefinitionName
             homeViewController.ProcessInstanceId = ProcessInstanceId
             homeViewController.TaskID = TaskID
             homeViewController.Title = Title
             homeViewController.Types = Types
             homeViewController.view.backgroundColor = UIColor.red
             window!.rootViewController = homeViewController
             window!.makeKeyAndVisible()


      completionHandler()
    
    
  }

这里是app端的viewController代码,它会加载框架viewController方法。

尝试 1:

    override func viewDidAppear(_ animated: Bool) {
    
    let controller = CreateCardViewController()
        let str = FormKey
        let result = String(str?.dropFirst(7) ?? "")
        print(result)
        let s = String(result.dropLast(10))
        print("newFormKey call form view", s )
        let v = convap(text: s)
        controller.processInstanceId = ProcessInstanceId
        controller.cardName = ""
        controller.TaskIdValue = TaskID
        controller.formKey = v
        controller.tabName = "NotificationTapped"
        print(controller.tabName)
        controller.fullFormKey = FormKey
    add(asChildViewController: controller)
    
        
    }


      private func add(asChildViewController viewController: UIViewController) {
    // Add Child View Controller
    addChild(viewController)

    // Add Child View as Subview
    view.addSubview(viewController.view)

    // Configure Child View
    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Notify Child View Controller
    viewController.didMove(toParent: self)
   }

尝试次数:2

      override func viewDidAppear(_ animated: Bool) {

                print("Presenting next...")
     
    
    let controller = CreateCardViewController()


            let str = FormKey
            let result = String(str?.dropFirst(7) ?? "")
            print(result)
            let s = String(result.dropLast(10))
            print("newFormKey call form view", s )
            let v = convap(text: s)
            controller.processInstanceId = ProcessInstanceId
            controller.cardName = ""
            controller.TaskIdValue = TaskID
            controller.formKey = v
            controller.tabName = "NotificationTapped"
            print(controller.tabName)
            controller.fullFormKey = FormKey

         present(controller, animated: true, completion: nil)



    }

任何帮助都非常感谢...

【问题讨论】:

    标签: ios swift uiviewcontroller firebase-cloud-messaging appdelegate


    【解决方案1】:

    使用 NotificationCenter 创建自定义 NSNotification.Name 并使用

    为您的视图控制器订阅创建的通知名称
    NotificationCenter.default.addObserver(self, selector: #selector(openView), name: <<custom notification name>>, object: nil)
    

    之后使用选择器函数可以将所有参数传递给视图控制器

    @objc func openView(notification: Notification){}
    

    并在didFinishLaunchingWithOptions 中使用这个发布到上述自定义通知

    let userInfo = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification]
                if (userInfo != nil){
    
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
                            NotificationCenter.default.post(name: <<custom notification name>>, object: nil, userInfo: userInfo as! [AnyHashable : Any]?)
                    }
                }
    

    如果您有多个需要打开的视图控制器,您可以创建一个基本视图控制器类并将上述代码放在基类中并通过基类扩展视图控制器

    【讨论】:

      【解决方案2】:

      我使用顶视图控制器来呈现所需的视图。

      获取顶视图控制器:

      func topController() -> UIViewController  {
          if var topController = UIApplication.shared.keyWindow?.rootViewController {
              while let presentedViewController = topController.presentedViewController {
      
                  topController = presentedViewController
              }
              return topController
          }
          return (UIApplication.shared.keyWindow?.rootViewController)!
      }
      

      然后在收到通知时:

      func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
          print(userInfo)
          guard Utility.shared.userInfo != nil else { return }
      
          let vc : EventDetailVC = EVENTSSTORYBOARD.viewController(id: "EventDetailVC") as! EventDetailVC
          vc.eventID = event_id
          vc.eventType = EventType.Invite
          let nav = UINavigationController(rootViewController: vc)
          nav.modalPresentationStyle = .fullScreen
          self.topController().present(nav, animated: true, completion: nil)
      }
      

      让我知道它是否适合您。

      【讨论】:

        【解决方案3】:

        我目前有这样的任务,也许它有点简单,但这是我的代码:

        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            if let navigationController =  window?.rootViewController as? UINavigationController {
                navigationController.popToRootViewController(animated: false)
                if let someViewController = navigationController.storyboard?.instantiateViewController(withIdentifier: "SomeViewController") as? SomeViewController {
                    navigationController.pushViewController(someViewController, animated: true)
                }
            }
        }
        

        就我而言,它运行良好,因为我将 UINavigationController 作为我的应用程序的根,并且我通过它管理我的导航。这对于确定您现在在视图堆栈中拥有什么以及如何清除它很重要。

        另外,你可以看到我使用这一行来实例化我的新 ViewController

        if let someViewController = navigationController.storyboard?.instantiateViewController(withIdentifier: "SomeViewController") as? SomeViewController
        

        但这并不重要,只要确保您的 ViewController 正确启动即可。

        祝你好运。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-12-24
          • 2016-02-15
          • 2020-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多