iOS | Push Notifications
Im receiving push notification with encrypted data. In docs I have found method
disablePushEncryption
but this method on NotificationsManager is not longer available. How do I show message text in push notification?
Also my app still keeping visible in badge total number of received push notifications. How do I remove them?
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
ServicesManager.sharedInstance().notificationsManager.handleNotification(withIdentifier: userInfo.description, withUserInfo: userInfo, withResponseInformation: nil)
NSLog("PUSH NOTIFICATION \(userInfo)")
completionHandler([.banner, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
ServicesManager.sharedInstance().notificationsManager.didReceiveNotification(userInfo: userInfo)
completionHandler()
NSLog("PUSH NOTIFICATION CLICK \(userInfo)")
}
/// Ask user for push notifications permissions
/// - Parameters:
/// - application: `UIApplication`
/// - notificationSettings: `UNNotificationSettings`
func application(_ application: UIApplication, didRegister notificationSettings: UNNotificationSettings) {
// Request for push token
UIApplication.shared.registerForRemoteNotifications()
}
/// User grant permissions for receiving push notifications
/// - Parameters:
/// - app: `UIApplication`
/// - deviceToken: `Data`
func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
ServicesManager.sharedInstance().notificationsManager.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
}
/// User refuse grant permission for receiving push notifications
/// - Parameters:
/// - app: `UIApplication`
/// - error: `Error`
func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
NSLog("User refuse to enable push notification")
}
}
Also which method should I use to let the Rainbow know that user interacted with notification?
I see two methods which seems to be same.
-handleNotificationWithIdentifier:withUserInfo:withResponseInformation:
Handle Notification @discussion You must invoke this method when the platform inform you that the user has interacted with the presented notification
-didReceiveNotificationWithUserInfo:
Did receive notification @discussion You must invoke this method when the platform inform you that the user has interacted with the presented notification.
-
Hello,
For push encryption, you need to use a Notification Service Extension to decrypt the push : https://developers.openrainbow.com/doc/sdk/ios/lts/guides/What_is_new
Also the "disablePushEncryption" is available in latest version 2.4.1 but is only a workaround.
For the badge number received in push, it's totally managed by the server especially when your app is in background. However, when you open your app, you can update it if you need.
For handling click on notifications, I think this is only managed on app side. There is a lot of tutorials for that, better than my explanations.
Nghia
-
But how server updating the badge number? I can overwrite badge number on app start, but my problem is that right now is still showing number 11 and on each receive push notification this number going up.
Which method do I have to call to mark all push notification on server as read by the user to not pushing them into app?
I called didReceivedNotification when push is received but app still showing same or increment number in badge.
-
I have create UNNotificationServiceExtension for decoding encrypted messages. But calling method
ServicesManager.sharedInstance().notificationManager.decryptNotificationContent(userInfo: userInfo)
return exact same userInfo as I pass. Nothing decrypted. What am I doing wrong?
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
guard let aps = bestAttemptContent.userInfo["aps"] as? [String:Any] else { return }
// TRY TO DECRYPT
if let _ = aps["crypt"] as? String {
let decryptedUserInfo = ServicesManager.sharedInstance().notificationsManager.decryptNotificationContent(userInfo: bestAttemptContent.userInfo)
bestAttemptContent.body = "Test"
}
// Modify the notification content here...
//bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}I put breakpoint on decryptedUserInfo but as I said above, this return same userInfo as was passed.
-
Ive tried but now I have problem that im not receiving push notifications at all. I did not made any changes but push notification does not arrive when app is terminated.
I ve tried certificates via
https://www.pushtry.com
if I did not make something wrong because I did some cleaning . But from that website push notification coming to the device.
This is full log
2022-07-11 16:28:31.038735+0200 DholRainbow[36235:2832946] [NotificationsManager:760] [PUSH] registerForRemoteNotifications via Apple Push Notification service
2022-07-11 16:28:31.628559+0200 DholRainbow[36235:2832946] [NotificationsManager:498] [Push-VoIP] didUpdatePushCredentials via Apple Push Notification service {length = 32, bytes = 0xcb49fc86 bd8cbe9a b9caf05e a3b80cd5 ... db8e9fde 8f01f2ce } for Type PKPushTypeVoIP
2022-07-11 16:28:31.628620+0200 DholRainbow[36235:2832946] [XMPPPush:146] [PUSHKIT] didUpdatePushKitCredentials {length = 32, bytes = 0xcb49fc86 bd8cbe9a b9caf05e a3b80cd5 ... db8e9fde 8f01f2ce } (Base64 Token y0n8hr2Mvpq5yvBeo7gM1ePGd45u3jae246f3o8B8s4=)
2022-07-11 16:28:31.638839+0200 DholRainbow[36235:2832946] [XMPPPush:116] [PUSH] setPushToken '{length = 32, bytes = 0xd1f18b82 937120f4 05ef96fa 80285c72 ... 8a66bbd8 5a2a2469 }' (Base64 Token '0fGLgpNxIPQF75b6gChccjwgNRuTO37Vima72FoqJGk=')
2022-07-11 16:28:32.379470+0200 DholRainbow[36235:2833146] [XMPPPush:408] [PUSH] We are authenticated so enable push
2022-07-11 16:28:32.387102+0200 DholRainbow[36235:2833146] [XMPPPush:332] [PUSH] Using 'register-push-apns-v2-sandbox' to register push APNS
2022-07-11 16:28:32.389861+0200 DholRainbow[36235:2833146] [XMPPPush:339] [PUSH] Sending register push IQ <iq type="set" to="sandbox-all-in-one-rbx-prod-1.rainbow.sbg" id="E5A579AC-5882-421B-86AA-D76AF8053893"><command xmlns="http://jabber.org/protocol/commands" node="register-push-apns-v2-sandbox" action="execute"><x xmlns="jabber:x:data" type="submit"><field var="app-id"><value>68d336f0792b11eca0cfeb3ff98cd96a</value></field><field var="token"><value>0fGLgpNxIPQF75b6gChccjwgNRuTO37Vima72FoqJGk=</value></field><field var="device-name"><value>iPhone</value></field><field var="device-id"><value>mobile_ios_sdk_1D500C88-DA2F-4C02-A36E-BC11AC9775FF</value></field><field var="ua_pub"><value>BOa1WXmr8tSHvSDhgi3KYybdXwTrEKEuh1GdyFpkpl72VeEGKdSrqTFtxRvWMA17l4ZQ4nLWKgA56K8gZrrC4rE=</value></field><field var="auth_secret"><value>ErnQSAqF7/mmlJZ89DEUrA==</value></field><field var="os-version"><value>15</value></field><field var="xcode-version"><value>13.3.1</value></field><field var="token-voip"><value>y0n8hr2Mvpq5yvBeo7gM1ePGd45u3jae246f3o8B8s4=</value></field></x></command></iq>
2022-07-11 16:28:32.420829+0200 DholRainbow[36235:2833131] [XMPPStreamWebSockets:1248] [WebSocket] SEND [980] : <iq type="set" to="sandbox-all-in-one-rbx-prod-1.rainbow.sbg" id="E5A579AC-5882-421B-86AA-D76AF8053893"><command xmlns="http://jabber.org/protocol/commands" node="register-push-apns-v2-sandbox" action="execute"><x xmlns="jabber:x:data" type="submit"><field var="app-id"><value>68d336f0792b11eca0cfeb3ff98cd96a</value></field><field var="token"><value>0fGLgpNxIPQF75b6gChccjwgNRuTO37Vima72FoqJGk=</value></field><field var="device-name"><value>iPhone</value></field><field var="device-id"><value>mobile_ios_sdk_1D500C88-DA2F-4C02-A36E-BC11AC9775FF</value></field><field var="ua_pub"><value>BOa1WXmr8tSHvSDhgi3KYybdXwTrEKEuh1GdyFpkpl72VeEGKdSrqTFtxRvWMA17l4ZQ4nLWKgA56K8gZrrC4rE=</value></field><field var="auth_secret"><value>ErnQSAqF7/mmlJZ89DEUrA==</value></field><field var="os-version"><value>15</value></field><field var="xcode-version"><value>13.3.1</value></field><field var="token-voip"><value>y0n8hr2Mvpq2022-07-11 16:28:32.420866+0200 DholRainbow[36235:2833137] [XMPPStreamManagementDiskStorage:113] loadInfosFromCache : {
22-07-11T14:28:32.447595Z" default:lang="en" node="register-push-apns-v2-sandbox"><x xmlns="jabber:x:data" type="result"><field var="jid" type="text-single"><value>pubsub.sandbox-all-in-one-rbx-prod-1.rainbow.sbg</value></field><field var="node" type="text-single"><value>8123276038029386246</value></field><field var="secret" type="text-single"><value>10075685502931284703</value></field></x></command></iq>
2022-07-11 16:28:32.511160+0200 DholRainbow[36235:2833145] [XMPPPush:427] [PUSH] did receive register push IQ response <iq xmlns="jabber:client" lang="en" to="b5842c98caf046b7a6f8a57a723b38f7@sandbox-all-in-one-rbx-prod-1.rainbow.sbg/mobile_ios_sdk_1D500C88-DA2F-4C02-A36E-BC11AC9775FF" from="sandbox-all-in-one-rbx-prod-1.rainbow.sbg" type="result" id="E5A579AC-5882-421B-86AA-D76AF8053893"><command xmlns="http://jabber.org/protocol/commands" status="completed" sessionid="2022-07-11T14:28:32.447595Z" default:lang="en" node="register-push-apns-v2-sandbox"><x xmlns="jabber:x:data" type="result"><field var="jid" type="text-single"><value>pubsub.sandbox-all-in-one-rbx-prod-1.rainbow.sbg</value></field><field var="node" type="text-single"><value>8123276038029386246</value></field><field var="secret" type="text-single"><value>10075685502931284703</value></field></x></command></iq>
2022-07-11 16:28:32.514992+0200 DholRainbow[36235:2833145] [XMPPPush:360] PUSH CONFIGURATION Push Configuration 0x280d5f3f0 : <Device Token (Base64 encoded) 0fGLgpNxIPQF75b6gChccjwgNRuTO37Vima72FoqJGk= VoIP Token (Base64 encoded) y0n8hr2Mvpq5yvBeo7gM1ePGd45u3jae246f3o8B8s4= nodeID 8123276038029386246 secret 10075685502931284703>
2022-07-11 16:28:32.519134+0200 DholRainbow[36235:2833145] [XMPPPush:389] [PUSH] Sending enable push IQ <iq type="set" id="669E2778-18E2-411C-BC16-6E646E499003"><enable xmlns="urn:xmpp:push:0" node="8123276038029386246" jid="pubsub.sandbox-all-in-one-rbx-prod-1.rainbow.sbg"><x xmlns="jabber:x:data" type="submit"><field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field><field var="secret"><value>10075685502931284703</value></field></x></enable></iq>
2022-07-11 16:28:32.562647+0200 DholRainbow[36235:2833172] [XMPPStreamWebSockets:1248] [WebSocket] SEND [386] : <iq type="set" id="669E2778-18E2-411C-BC16-6E646E499003"><enable xmlns="urn:xmpp:push:0" node="8123276038029386246" jid="pubsub.sandbox-all-in-one-rbx-prod-1.rainbow.sbg"><x xmlns="jabber:x:data" type="submit"><field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field><field var="secret"><value>10075685502931284703</value></field></x></enable></iq>
2022-07-11 16:28:32.629540+0200 DholRainbow[36235:2833184] [XMPPPush:496] [PUSH] We receive a response to our enable Push IQ but we don't treat it specially <iq xmlns="jabber:client" lang="en" to="b5842c98caf046b7a6f8a57a723b38f7@sandbox-all-in-one-rbx-prod-1.rainbow.sbg/mobile_ios_sdk_1D500C88-DA2F-4C02-A36E-BC11AC9775FF" from="b5842c98caf046b7a6f8a57a723b38f7@sandbox-all-in-one-rbx-prod-1.rainbow.sbg" type="result" id="669E2778-18E2-411C-BC16-6E646E499003"></iq>
2022-07-11 16:28:32.775624+0200 DholRainbow[36235:2833134] [MyUser:1934] PUSH_WITH_ACK detected : {
featureName = "New push mechanism with acknowledgment";
featureUniqueRef = "PUSH_WITH_ACK"; -
I see only this in the log
2022-07-18 13:24:03.264414+0200 DholRainbow[924:132418] [EncryptionManager:54] saveKeysData : save keys locally.
title = "Message encrypted";
title = "Message encrypted";
2022-07-18 13:25:09.129300+0200 DholRainbow[924:133047] [EncryptionManager:54] saveKeysData : save keys locally. -
Hi,
Here is how I managed to decrypt a remote notification with the extension service.- In your two targets (Main app and extension) add the "keychain sharing" capability with the same group name
- In the entitlements files (App and extension) check also that the group is the same
- Check the provisioning profile of the App and the extension, you should see the keychain sharing capability
- In apple developer website check that the app and extension have the same "App ID Prefix" (it can be different from the Team ID)
- If you have some trouble with signing and provisioning profile, please uncheck the following case in Xcode and manage everything manually
- After all these steps, remove your app from the iDevice, Clean your project and try to decrypt the content of the push notification with the following piece of code
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
if let aps = bestAttemptContent.userInfo["aps"] as? NSDictionary {
if let crypt = aps["crypt"] as? NSString {
let decryptedUserInfo = ServicesManager.sharedInstance().notificationsManager.decryptNotificationContent(userInfo: request.content.userInfo)
//Set default values from decrypted userInfo
bestAttemptContent.userInfo = decryptedUserInfo
if let decryptedAps = decryptedUserInfo["aps"] as? NSDictionary {
if let alert = decryptedAps["alert"] as? NSDictionary {
if let title = alert["title"] as? NSString {
bestAttemptContent.title = title as String
}
if let body = alert["body"] as? NSString {
bestAttemptContent.body = body as String
}
}
if let badge = decryptedAps["badge"] as? NSNumber {
bestAttemptContent.badge = badge
}
}
}
} else {
print("Push is not encrypted")
}
contentHandler(bestAttemptContent)
}
}
Please sign in to leave a comment.
Comments
11 comments