How to get data from push notification response Swift 3/iOS
Make sure you turned 'ON' Background Modes in Project 'capabilities' and checked 'Remote Notifications'. Add following method in AppDelegate class. This method will call at the time of presenting notification.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print(notification.request.content.userInfo)
completionHandler([ .alert,.badge, .sound])
}
I think this is a safer way to do the way Joseph found.
guard
let aps = data[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
I would eager you to try to find a way to avoid using force unwrapping. When you do to the following:
let alert = aps["alert"]! as! NSDictionary
let body = alert["body"] as! String
let title = alert["title"] as! String
the application will crash, when any of the above values are missing.
Instead, first lets introduce a notification model.
class MTNotification {
let alert: [String: AnyHashable]
var title: String?
var body: String?
init(alert: [String: AnyHashable]) {
self.alert = alert
}
}
Use something to track the errors what could occur while handling the raw notification data. The better if you make it conform to the Error
protocol.
enum MTError: Error {
// Observe your transformation and extend error cases
case missingProperty(id: String)
}
Use a helper class not to pollute the app delegate, where you can handle the transformation of the data to notifications.
class MTNotificationBuilder {
/// Build a notification from raw data
///
/// - Parameter data: Classic notification payload, received from app delegate
/// - Returns: customized MTNotification
/// - Throws: error while building a valid MTNotification object
static func build(from data: [AnyHashable : Any]) throws -> MTNotification {
guard let aps = data["aps"] as? [String: AnyHashable] else {
// Do some error handlig
throw MTError.missingProperty(id: "aps")
}
guard let alert = aps["alert"] as? [String: AnyHashable] else {
// Do some error handlig
throw MTError.missingProperty(id: "aps")
}
let notification = MTNotification(alert: alert)
// Assign values read as optionals from alert dictionary
notification.title = alert["title"] as? String
notification.body = alert["body"] as? String
return notification
}
}
And all you need to do at the end is to call the builder function and see the result. You can be strict and introduce errors for any of the cases, also using will help maintainability later.
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
do {
let notification = try MTNotificationBuilder.build(from: data)
print(notification.alert)
} catch let error {
print(error)
}
}