简体   繁体   English

当用户点击 iOS Swift 中的通知时,如何加载 viewController?

[英]How to load viewController when user tap on notification in iOS Swift?

I have done push notification using FCM on the app side.我已经在应用程序端使用 FCM 完成了推送通知。 When the user taps on the notification it navigates to specific viewController from the app side to custom SDK.当用户点击通知时,它会从应用程序端导航到特定的 viewController 到自定义 SDK。 I have tried many ways but viewController is not showing but all functionalities are loaded successfully.我尝试了很多方法,但 viewController 没有显示,但所有功能都已成功加载。

1. First attempt: [Notification tap is detected and passed data from the app side to framework. 1.第一次尝试: [Notification tap is detected 并将数据从应用端传递到框架。 Loaded particular viewController functionalities but viewController are not showing.]加载了特定的 viewController 功能,但 viewController 没有显示。]

When user tap notification from the app side, it will send data to the framework to show a particular viewController.当用户从应用端点击通知时,它将向框架发送数据以显示特定的 viewController。

here is the code for the app side:这是应用程序端的代码:

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

Here is the code from the framework side:这是框架方面的代码:

  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. Second attempt: [Notification detected in the app side and passed value to viewController.第二次尝试:[在应用程序端检测到通知并将值传递给 viewController。 And, Inside viewController framework method is called to load framework viewController but all functionality is loaded successfully but the view is not loaded]并且,调用内部 viewController 框架方法来加载框架 viewController 但所有功能都已成功加载但未加载视图]

Here is the code from the app side:这是应用程序端的代码:

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

Here is the code viewController from the app side, it will load the framework viewController method.这是来自应用程序端的代码 viewController,它将加载框架 viewController 方法。

Attempt 1:尝试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)
   }

Attempt: 2尝试: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)



    }

Any help much appreciated pls...任何帮助非常感谢请...

I have such task currently maybe it is a little bit simpler but this is my code:我目前有这样的任务,也许它有点简单,但这是我的代码:

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

In my case, it works fine because I have UINavigationController as a root of my app, and I manage my navigation through it.就我而言,它运行良好,因为我将 UINavigationController 作为我的应用程序的根目录,并且我通过它管理我的导航。 This is important to be sure what you have on your stack of views right now and how to clear it.这对于确定您现在在视图堆栈中拥有什么以及如何清除它很重要。

Also, you can see that I use this line for instantiating my new ViewController此外,您可以看到我使用这一行来实例化我的新 ViewController

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

But this is not important, just be sure that your ViewController is correctly initiated.但这并不重要,只要确保您的 ViewController 正确启动即可。

Good luck.祝你好运。

I used the top view controller to present the desired view.我使用顶视图 controller 来呈现所需的视图。

To fetch top view controller:要获取俯视图 controller:

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

            topController = presentedViewController
        }
        return topController
    }
    return (UIApplication.shared.keyWindow?.rootViewController)!
}

Then on receiving notification:然后在收到通知时:

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

Let me know if it works for you.请让我知道这对你有没有用。

Use NotificationCenter create a custom NSNotification.Name and subscribe your viewcontroller to the created notification name using使用NotificationCenter创建一个自定义NSNotification.Name并使用您的视图控制器订阅创建的通知名称

NotificationCenter.default.addObserver(self, selector: #selector(openView), name: <<custom notification name>>, object: nil)

after that using the selector function you can pass all the parameters to the view controller之后使用选择器 function 您可以将所有参数传递给视图 controller

@objc func openView(notification: Notification){}

and in didFinishLaunchingWithOptions post to the above custom notification using this并在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]?)
                }
            }

if you have multiple viewcontrollers that needs to be open you can create a base view controller class and put above code in the base class and extend the viewcontrollers by the base class if you have multiple viewcontrollers that needs to be open you can create a base view controller class and put above code in the base class and extend the viewcontrollers by the base class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 收到通知时点击打开本地通知 - iOS - Swift - Open Local Notification on tap when Notification received - iOS - Swift 当用户点击推送通知时,关闭当前ViewController并打开新ViewController的最佳方法是什么 - When user tap push notification, what is the best way to close current viewcontroller and open new viewcontroller 当应用程序终止时处理点击本地通知 - iOS - Swift - Handle tap on local notification when app is terminated - iOS - Swift 为什么当我点击推送通知并快速移动ViewController时状态栏消失 - Why status bar disappear when I tap push notification and move ViewController in swift 当用户点击通知IOS7时,导航到特定的视图控制器 - Navigate to particular view controller when user tap the notification IOS7 用户快速点击Firebase通知后如何显示警报? - How to show alert after user tap firebase notification in swift? 在iOS Swift中点击“下一步”按钮时,如何在表格视图中加载数据数组? - How to load array of data in table view when tap on Next button in iOS Swift? 在推送通知Swift 2 AppDelegate上加载特定的viewController - Load a specific viewController on push notification Swift 2 AppDelegate 如何在用户点按推送通知时禁用打开应用 - How to disable opening app when user tap push notification 当我们在 swift 中使用 MKMapView 点击 mapView 时,如何移动到第二个 Viewcontroller? - How to Move to 2nd Viewcontroller when we tap on mapView using MKMapView in swift?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM