Swift IOS:从通知打开应用程序时,调用UIviewController的特定功能

时间:2019-02-26 12:00:06

标签: ios swift push-notification apple-push-notifications nsnotificationcenter

我想使用通知上的点击打开应用程序时调用ViewController函数。 (onDidReceiveNotification是第一个视图控制器,根视图控制器)

当应用程序打开或在后台运行时,它工作正常,但是当应用程序未打开或在后台(不在内存中)并点击以打开应用程序时,onDidReceiveNotification函数未调用,< / p>

使用点击通知打开应用程序时,应该怎么调用class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. NotificationCenter.default.removeObserver(self, name: .didReceiveAlert, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ViewController.onDidReceiveNotification(_:)), name: .didReceiveAlert, object: nil) } @objc func onDidReceiveNotification(_ notification:Notification) { print("Received Notification") } } 函数

ViewController.swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {            
    NotificationCenter.default.post(name: .didReceiveAlert, object: nil)       
}

AppDelegate.swift

ruby '~> 2.5.0'

5 个答案:

答案 0 :(得分:1)

当应用程序当时处于打开状态或在后台运行时称为NotificationCenter.defalut.post,并且当应用程序终止/关闭并在那时使用通知打开时,获取实例并按菜单调用onDidReceiveAlert函数,请参见以下代码

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    if application.applicationState == .background || application.applicationState == .active {
        NotificationCenter.default.post(name: .didReceiveAlert, object: nil)
    }else {
        let nav = window?.rootViewController as! UINavigationController
        let mainVC = nav.viewControllers.first as! ViewController
        mainVC.onDidReceiveAlert(nil)
    }
}

或者只需从ViewController堆栈中获取UINavigationController实例,然后直接调用ViewController的功能(不需要通知通知程序)

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    let nav = window?.rootViewController as! UINavigationController
    let mainVC = nav.viewControllers.first as! ViewController
    mainVC.onDidReceiveAlert(nil)       
}

使用可选参数创建函数,请使用以下代码。

@objc func onDidReceiveAlert(_ notification:Notification? = nil) {
    print("Received Notification")
}

答案 1 :(得分:0)

尝试以下代码

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any] {
         //call your notification method from here
         NotificationCenter.default.post(name: .didReceiveAlert, object: nil)  
    }
}

希望您在任何情况下都只需要拨打didReceiveAlert通知

答案 2 :(得分:0)

在AppDelegate中,检查是否在didReceiveRemoteNotification中获得了有效负载。从那里您可以编写代码以推送到特定页面。

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    // Print full message.
    print(userInfo)
    pushToPage(data: userInfo)
}

func pushToPage(data:[AnyHashable : Any]){
    print("Push notification received: \(data)")
    if let aps = data["aps"] as? NSDictionary {
        print(aps)
    }
}

答案 3 :(得分:0)

当应用处于非活动状态并且用户点击通知时。在这种情况下,只有一个选项可以管理通知。

尝试

在全局类中创建一个变量,以便您可以从任何地方访问它。

Ex AppDelegate

中创建变量
'\s'

在那之后检查var isNotificationTap : Bool = false ,如果launchOptions可用,则设置标志

launchOptions

然后只需在ViewController中检查一个标志即可。

if launchOptions != nil {
    if let userInfo = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? [String : AnyObject] {
        if let dic = userInfo["body"] as? [String : AnyObject] {
            if let pushType = dic["push_type"] as? String {
                //Set Flag or any key in global file to identify that you tap on notification
                self.isNotifcaionTap = true
            }
        }
    }
}

答案 4 :(得分:-1)

您可以通过使用控制器实例而不是notificationObserver来克服这种情况。

if let rootController = UIApplication.shared.keyWindow?.rootViewController{
        let controllerInstance = rootController.navigationController?.viewControllers[yourControllerIndex] as? ViewController
        controllerInstance.onDidReceiveNotification()
 }