Skip to Content

In this series of blog entries we will describe the development of a mobile chat app using SAP NetWeaver Cloud as a backend. The last time we explained data storage on the mobile device and on NW Cloud. Now we want to explain how we enabled push notifications for our app.

Why we need Push Notifications

When a user sends a message the recipient needs to be informed about the new message. But of course the receiving user has not opened out Twaddle app the whole time. That’s the point push notifications come in: The device informs the recipient via a popup that a new message is available for him. The second reason why we need push notifications is that our app shouldn’t ask the server the whole time for new messages as this would mean a large waste of bandwidth and battery. So that’s why also when the Twaddle app is opened by the user it receives new messages via a push notification and doesn’t have to perform a GET-request against our web service.

The landscape behind push notifications

Push notifications are sent to the device via a server. This server is hosted by Apple and is called “Apple Push Notification Service” – APNS. So whenever you want to send a push notification to an apple device you have to connect to the APNS and ask it for sending a push notification to a certain device. Our system that connects to the APNS is NW Cloud. When a user sends a new message to our web service NW Cloud saves this message and sends a push notification to the recipient and therefore connects to the APNS. NW Cloud has to provide the APNS the device receiving the push notification. Therefore every device that uses our app is identified by a device token – iOS provides this information to our app. That’s why our task is that also NW Cloud knows this device token for every user. As a summary: When Alice sends a new message to Bob, NW Cloud checks the device token of Bob in its data base, connects to APNS and provides it the device token of Bob and the message content, and APNS delivers the push notification to Bob’s device.

Folie1.PNG

Apple Push Notification Certificates

There are several certificates needed to enable Push Notifications for your app, so we want to give a short overview of that.

  • First of all you have to create a Certificate Signing Request with the Keychain Access.
  • Next step: Creating an AppID and check the Enable for Apple Push Notification service box. After that, you have to configure the Push SSL Certificate – upload the Certificate Signing Request.
  • Now you can download and install your SSL Certificate.
  • Last step: After creating a Provisioning Profile for your App you can download it and add it to Xcode.

We found a really helpful step-by-step description, which could also be useful for you.

Our workaround for enabling NW Cloud to send push notifications

Unfortunately it’s not that simple. You have to establish a secure connection to the APNS via port 2195 – that’s the issue. Currently NW Cloud seems to be able to connect other servers only via port 80 and 443 for http(s)-traffic. How to solve this issue? Our idea was to use a proxy server: NW Cloud sends the push notification not directly to the APNS but to the proxy forwarding the notification. That’s why we created a simple PHP-Web service running on a colleague’s machine (Thank you John!) that connects to the APNS without difficulties. NW Cloud accesses this php script and passes device token and message to it. The php-script then connects to the APNS that delivers the message. Of course this solution makes the whole system more complex but we’re happy to see it working

Folie2.PNG

Some backend coding

For developing the php script connecting to the APNS we used this tutorial. We changed the script that it reads device token and payload from passed post-parameters. To access our proxy server running our php-script we use the following code:

// cut message if too long

if(text.length()>200)

       text = text.substring(0, 200);

// define php-script as proxy

URL url = new URL(http://XXXXXXXXXX/sendpush.php);

URLConnection connection = url.openConnection();    

// simple payload: The alert box contains the message, and the Twaddle app shows a

// bubble with a 1 in it to notifiy the user

String payload = “{\”aps\”:{\”alert\”:\””+ text + “\”,\”badge\” : 1}}”;

// convert payload and devicetoken to UTF8 for the php-script

String data = URLEncoder.encode(“payload”, “UTF-8”) + “=” + URLEncoder.encode(payload, “UTF-8”);

data += “&” + URLEncoder.encode(“devicetoken”, “UTF-8”) + “=” + URLEncoder.encode(devicetoken, “UTF-8”);

if(payload.length()>256)

    throw new TwaddleException(“Push-Notification not sent because payload exceeds maximum size”);

// send data to php-script

connection.setDoOutput(true);

OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());

wr.write(data);

wr.flush();

// read response from php-script

BufferedReader in = new BufferedReader(

new InputStreamReader(connection.getInputStream()));

String line;

while ((line = in.readLine()) != null)

                 result += line;


Receiving Notifications on the Application

After creating all the certificates you have to make sure that your App is “listening” for notifications. This is really simple. You just have to insert the following lines to the didFinishLaunchingWithOptions in your AppDelegate:

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:

(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

To send Notifications to a special device, you have to know the device token. You can easily get this with the help of the method didRegisterForRemoteNotificationsWithDeviceToken.

– (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken

{

    NSString* newToken = [deviceToken description];

}

Handle received Notifications

When your device receives a notification and the app is in the foreground at the moment, the method didReceiveRemoteNotification is called. So that’s the place where we handle those notifications. After receiving a notification, we post our own notification in the NSNotificationCenter and named it “pushReceived”.

– (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo{

    application.applicationIconBadgeNumber = 0;

    NSLog(@”Received notification: %@”, userInfo);

    // Post a notification

    [[NSNotificationCenter defaultCenter] postNotificationName:@”pushReceived” object:nil];

}

Every ViewController, which should react after receiving a notification, has an observer. So when the notification “pushReceived” is sent to the NSNotificationCenter the observer calls the declared method. In this code example the data will be refreshed. 

// Observer that will respond to pushReceived

[[NSNotificationCenter defaultCenter] addObserver:self

   selector:@selector(refreshData:)

   name:@”pushReceived” object:nil];

In our use case there is nothing special to do when the device receives a notification and the app is in the background. When you launch the app, all the data will be refreshed either the device received a notification before or not.

We hope our explanation about APNS on NW Cloud was useful for you. In the next blog post we will describe how the authentication for our app works . We always appreciate your feedback so please feel free to suggest any ideas of improvement.

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. Matthias Steiner

    Well, what can I say… I’ve been supporting your journey for a long time and along the way I’ve become a big fan of your work! This one is yet another outstanding blog: both from a content and presentation perspective! Your excitement really shines through…

    Concerning the topic you raised – thanks for the push! 😉

    We hear you… the fact that – as of today – the open ports are rather restricted (primarily for security reasons) is something that we sure got on our radar. Of course I cannot make any promises here and now, but what I can say is that we have been talking about this aspect internally already and the value of being able to support push notifications (and other functionalities which require different ports) is indisputable.

    Please keep in mind that you’re really among the early adopters of the platform, but it’s through feedback like yours that one really can influence the road forward!

    Keep pushing!

    (0) 
      1. Ethan Jewett

        I believe this is correct. Push notifications seem to work for me in Germany, though I have a US apple account, so who knows.

        Cheers,

        Ethan

        (0) 
  2. Vivek Srinivasan

    Hi,

    Thanks a lot for the push..I tried for my scenario where the notification is triggered from  gateway backend.

    And i am able to get the notification in the iphone device with the following aps

        aps =     {

     

            alert = “Price change”;

     

            badge = 1;

     

        };

     

        data = “”;

    And i am getting a notification xml from the gateway which i dont know how to fetch via apns.

    How would we add that to the json payload data stored in notification xml  or only we can show the alert and badge number…

    Kindly help me here with your suggestion

    (0) 

Leave a Reply