Swift read userInfo of remote notification

后端 未结 7 1608
庸人自扰
庸人自扰 2020-12-08 02:11

I implemented a function to open an AlertView when I receive a remote notification like this:

func application(application: UIApplication, didReceiveRemoteNo         


        
相关标签:
7条回答
  • 2020-12-08 02:54

    Method (Swift 4):

    func extractUserInfo(userInfo: [AnyHashable : Any]) -> (title: String, body: String) {
        var info = (title: "", body: "")
        guard let aps = userInfo["aps"] as? [String: Any] else { return info }
        guard let alert = aps["alert"] as? [String: Any] else { return info }
        let title = alert["title"] as? String ?? ""
        let body = alert["body"] as? String ?? ""
        info = (title: title, body: body)
        return info
    }
    

    Usage:

    let info = self.extractUserInfo(userInfo: userInfo)
    print(info.title)
    print(info.body)
    
    0 讨论(0)
  • 2020-12-08 02:55

    Alert should be showing while the app is in active state. So check the state is active or not.

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if application.applicationState == .active {
          if let aps = userInfo["aps"] as? NSDictionary {
            if let alertMessage = aps["alert"] as? String {
              let alert = UIAlertController(title: "Notification", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
              let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
              alert.addAction(action)
              self.window?.rootViewController?.present(alert, animated: true, completion: nil)
            }
          }
        }
        completionHandler(.newData)
      }
    

    From this if a user need message then he can get alert message.

    0 讨论(0)
  • 2020-12-08 02:56

    For me, when I send the message from Accengage, the following code works -

    private func extractMessage(fromPushNotificationUserInfo userInfo:[NSObject: AnyObject]) -> String? {
        var message: String?
        if let aps = userInfo["aps"] as? NSDictionary {
            if let alert = aps["alert"] as? NSDictionary {
                if let alertMessage = alert["body"] as? String {
                    message = alertMessage              
                }
            }
        }
        return message
    }
    

    The only difference from Craing Stanford's answer is the key I used to extract message from alert instance which is body which is different. See below for more clearification -

    if let alertMessage = alert["message"] as? NSString
    

    vs

    if let alertMessage = alert["body"] as? String
    
    0 讨论(0)
  • 2020-12-08 02:57

    This is my version for objC

    if (userInfo[@"aps"]){
        NSDictionary *aps = userInfo[@"aps"];
        if (aps[@"alert"]){
            NSObject *alert = aps[@"alert"];
            if ([alert isKindOfClass:[NSDictionary class]]){
                NSDictionary *alertDict = aps[@"alert"];
                if (alertDict[@"message"]){
                    NSString *message = alertDict[@"message"];
                }
            }
            else if (aps[@"alert"]){
                NSString *alert = aps[@"alert"];
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 03:03

    The root level item of the userInfo dictionary is "aps", not "alert".

    Try the following:

    if let aps = userInfo["aps"] as? NSDictionary {
        if let alert = aps["alert"] as? NSDictionary {
            if let message = alert["message"] as? NSString {
               //Do stuff
            }
        } else if let alert = aps["alert"] as? NSString {
            //Do stuff
        }
    }
    

    See Push Notification Documentation

    0 讨论(0)
  • 2020-12-08 03:04

    I use APNs Provider and json payload as below

    {
      "aps" : {
        "alert" : {
          "title" : "I am title",
          "body" : "message body."
        },
      "sound" : "default",
      "badge" : 1
      }
    }
    

    Due to the provider originates it as a JSON-defined dictionary that iOS converts to an NSDictionary object, without subscript like Dictionary, but can use value(forKey:)

    Reference from here

    This's my way for Swift 4

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        guard application.applicationState == .active else { return }
        guard let alertDict = ((userInfo["aps"] as? NSDictionary)?.value(forKey: "alert")) as? NSDictionary,
            let title = alertDict["title"] as? String,
            let body = alertDict["body"] as? String
            else { return }
        let alertController = UIAlertController(title: title, message: body, preferredStyle: .alert)
        let okAct = UIAlertAction(title: "Ok", style: .default, handler: nil)
        alertController.addAction(okAct)
        self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
        completionHandler(UIBackgroundFetchResult.noData)
    }
    
    0 讨论(0)
提交回复
热议问题