Как загрузить viewController, когда пользователь нажимает на уведомление в iOS Swift? - PullRequest
0 голосов
/ 06 апреля 2020

Я сделал уведомление pu sh, используя FCM на стороне приложения. Когда пользователь нажимает на уведомление, он переходит к указанному c 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)




}
Вторая попытка: [Обнаружено уведомление на стороне приложения и передано значение в 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 ?? "")

     }

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


  }

Вот код 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)



    }

Любая помощь высоко ценится пожалуйста ...

Ответы [ 3 ]

0 голосов
/ 09 апреля 2020

Я использовал контроллер вида сверху, чтобы представить желаемый вид.

Чтобы получить контроллер вида сверху:

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

Дайте мне знать, работает ли он для вас.

0 голосов
/ 14 апреля 2020

Используйте NotificationCenter, создайте пользовательский NSNotification.Name и подпишите ваш viewcontroller на имя созданного уведомления, используя

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

, после этого с помощью функции селектора вы можете передать все параметры в контроллер представления * 1006. *

@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]?)
                }
            }

, если у вас есть несколько viewcontrollers, которые должны быть открыты, вы можете создать базовый класс контроллера представления и поместить выше код в базовом классе и расширение контроллеров представления базовым классом

0 голосов
/ 09 апреля 2020

У меня есть такая задача в настоящее время, может быть, она немного проще, но это мой код:

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 как root моего приложения, и я управляю навигацией по нему. Это важно, чтобы быть уверенным в том, что у вас есть в вашем стеке просмотров сейчас и как его очистить.

Кроме того, вы можете видеть, что я использую эту строку для создания экземпляра моего нового ViewController

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

Но это не важно, просто убедитесь, что ваш ViewController запущен правильно.

Удачи.

...