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.
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.
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.
There are several certificates needed to enable Push Notifications for your app, so we want to give a short overview of that.
We found a really helpful step-by-step description, which could also be useful for you.
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
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; |
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]; } |
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
37 | |
19 | |
13 | |
12 | |
11 | |
10 | |
10 | |
9 | |
8 | |
8 |