Top

iOS | Push Notifications

Comments

11 comments

  • Le-Trong-Nghia HUYNH

    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

    0
    Comment actions Permalink
  • Patrik Spisak

    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.

     

    0
    Comment actions Permalink
  • Patrik Spisak

    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. 

    0
    Comment actions Permalink
  • Le-Trong-Nghia HUYNH

    Hello,

    Do you have logs for the decrypt part (from the SDK) ?

    Thanks

    0
    Comment actions Permalink
  • Patrik Spisak

    I dont have anything in logs about decryption. 

    0
    Comment actions Permalink
  • Le-Trong-Nghia HUYNH

    Hello Patrik,

    This is weird.. could you try to enable the capability "Keychain Sharing", if not done yet of course?

    In Xcode, on your target app :

    • Tab "Signing & Capabilities"
    • Click on the "+" button on bottom left
    • Search and select "Keychain Sharing"

    Thanks

    0
    Comment actions Permalink
  • Patrik Spisak

    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";

     

    0
    Comment actions Permalink
  • Rick LUPPINO

    I am having the same issue where the "decryptNotificationContent" function of the notificationManager is not decrypting the payload and is returning the exact same content as before decryption. Is this working for you and if so, what was the resolution?

    0
    Comment actions Permalink
  • Rick LUPPINO

    I just noticed this error message in the console:

    [EncryptionManager:94] decryptDataString: failed to decrypt received data!

    0
    Comment actions Permalink
  • Patrik Spisak

    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.
    0
    Comment actions Permalink
  • Joseph IACOPETTA

    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)

              }

          }

    0
    Comment actions Permalink

Please sign in to leave a comment.

Still can't find what you need?

  • Contact Us

    Do you have any question about Rainbow? Leave us a message to get more information.

    Contact
  • Ask the Community

    Do you need help? Ask your questions to the Community and get answers from other Rainbow users.

    Post message