I am attempting to grasp actionable notifications (Notifications with textual content and button(s) – thus permitting person to work together with the notification with greater than only a faucet). I am following this documentation.
First, requesting person permission,
// Log() is my customized logging wrapper.
// Referred to as from software(_:willFinishLaunchingWithOptions:).
func RequestUserPermission() {
AppDelegate.sUserNotificationCenter.requestAuthorization(choices: [.alert, .sound, .badge]) { (pGranted: Bool, pError: Error?) in
Log("Completion handler of requestAuthorization(choices:completionHandler:) invoked!")
if(pGranted) {
Log("Permission granted!")
} else {
Log("Permission denied!")
guard let error = pError else {
Log("nil worth in pError!")
return;
}
Log(String(format: "error = %@", error.localizedDescription))
}
}
}
Then, registering for distant notification and to acquire a tool token,
// static let sApp: UIApplication = UIApplication.shared
// static let sUserNotificationCenter: UNUserNotificationCenter = UNUserNotificationCenter.present()
// Referred to as from software(_:willFinishLaunchingWithOptions:).
func RegisterForRemoteNotifications() {
AppDelegate.sApp.registerForRemoteNotifications()
// Set the app delegate to be notified.
AppDelegate.sUserNotificationCenter.delegate = self
}
func software(_ software: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
Log(String(format: "error.localizedDescription = %@", error.localizedDescription))
}
func software(_ software: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken pDeviceToken: Information) {
// Print the gadget token as a string.
Log("pDeviceToken = " + pDeviceToken.hexEncodedString())
}
extension Information {
func hexEncodedString() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
Then, the notification classes supported by the app must be registered. I am solely taking a look at one assembly notification with 3 buttons.
// static let sAcceptActionID: String = "ACCEPT_ACTION"
// static let sTentativeActionID: String = "TENTATIVE_ACTION"
// static let sDeclineActionID: String = "DECLINE_ACTION"
// static let sMeetingInviteID: String = "MEETING_INVITE"
func RegisterNotificationCategories() {
// Specify the actions (buttons) to a notification
let meeting_accept: UNNotificationAction = UNNotificationAction(identifier: AppDelegate.sAcceptActionID, title: "ACTION")
let meeting_tentative: UNNotificationAction = UNNotificationAction(identifier: AppDelegate.sTentativeActionID, title: "TENTATIVE")
let meeting_decline: UNNotificationAction = UNNotificationAction(identifier: AppDelegate.sDeclineActionID, title: "DECLINE")
// Create the notification class object
let meeting_invite: UNNotificationCategory = UNNotificationCategory(identifier: AppDelegate.sMeetingInviteID, actions: [meeting_accept, meeting_tentative, meeting_decline], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: "Preview")
// Register the notification class
AppDelegate.sUserNotificationCenter.setNotificationCategories([meeting_invite])
}
Subsequent, to deal with the notification by implementing the userNotificationCenter(_:didReceive:withCompletionHandler:) delegate technique.
func userNotificationCenter(_ middle: UNUserNotificationCenter, didReceive pResponse: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let user_info: [AnyHashable : Any] = pResponse.notification.request.content material.userInfo
Log(String(format: "user_info = %@", String(describing: user_info)))
completionHandler()
}
This technique shall be invoked after person has tapped a button within the notification. App is positioned in background state to course of person’s motion.
Lastly, to ship the distant notification, I am doing it the command line manner (Token based mostly method). Nevertheless it by no means works. The take a look at notification, which makes use of the next command works
curl -v –header “apns-topic: $TOPIC” –header “apns-push-type: alert” –header “authorization: bearer $AUTHENTICATION_TOKEN” –data ‘{“aps”:{“alert”:”take a look at”}}’ –http2 https://${APNS_HOST_NAME}/3/gadget/${DEVICE_TOKEN}
However the modified one for exhibiting an actionable notification does not work. There is no notification (regardless that I did obtain the pattern take a look at notification). That is my JSON payload,
{
"aps" : {
"class" : "MEETING_INVITE"
"alert" : {
"title" : "Assembly Invite"
"physique" : "Weekly Drag"
},
},
"MEETING_ORGANIZER" : "El Diablo",
}
The modified curl command (The above JSON payload is given to the info header of the POST request as a single string) is,
curl -v –header “apns-topic: $TOPIC” –header “apns-push-type: alert” –header “authorization: bearer $AUTHENTICATION_TOKEN” –data ‘{“aps” : {“class” : “MEETING_INVITE””alert” : {“title” : “Assembly Invite””physique” : “Weekly Drag”},},”MEETING_ORGANIZER” : “El Diablo”}’ –http2 https://${APNS_HOST_NAME}/3/gadget/${DEVICE_TOKEN}
I do get HTTP 200 within the terminal after the command (which means it reached APNS), however no notification in my cellphone.
% curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: alert" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps" : {"class" : "MEETING_INVITE""alert" : {"title" : "Assembly Invite""physique" : "Weekly Drag"},},"MEETING_ORGANIZER" : "El Diablo"}' --http2 https://${APNS_HOST_NAME}/3/gadget/${DEVICE_TOKEN}
....
....
* We're utterly uploaded and superb
* Connection state modified (MAX_CONCURRENT_STREAMS == 1)!
* Connection state modified (MAX_CONCURRENT_STREAMS == 1000)!
< HTTP/2 200
< apns-id: EB0400F7-3CC1-64EF-5DD6-F8158E44BC1D
<
* Connection #0 to host api.sandbox.push.apple.com left intact
I’ve verified that the gadget token is appropriate and the class key in aps dictionary has the suitable worth i.e MEETING_INVITE…. as registered in code.
What am I lacking?