Swift read userInfo of remote notification

2019-01-22 01:58发布

问题:

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

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){
        var notifiAlert = UIAlertView()
        var NotificationMessage : AnyObject? =  userInfo["alert"]
        notifiAlert.title = "TITLE"
        notifiAlert.message = NotificationMessage as? String
        notifiAlert.addButtonWithTitle("OK")
        notifiAlert.show()
}

But NotificationMessage is always nil.

My json payload looks like this:

{"aps":{"alert":"Testmessage","badge":"1"}}

I am using Xcode 6, Swift and I am developing for iOS8. I searched hours now, but didn't find any useful information. The Notifications works perfectly.. and if I click it, the alertview opens. My problem is, that I am not able to get the data out of userInfo.

回答1:

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



回答2:

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


回答3:

Method(swift4):

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)


回答4:

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.