Skip to Content

A couple of days ago on Twitter, Martin Lang asked if anyone had used the Apple Push Notification Service to push a message from SAP to an iOS device. The timing of this question was excellent, as a couple of weeks earler I had built a very basic Proof of Concept to push information about a users open Workitem count to their iOS device whenever a new Work Item arrived.

So, how do you do it? In the following Blog I’d like to run through the steps I took to connect all the pieces.

 

Step 1. You’ll need to register some stuff at developer.apple.com.

You’ll need to install your iOS Application on an actual physical device for the APNS to work. This means you’ll need to be a member of the Apple Developer Program so that you can request a Provisioning Profile for your device from the Apple Provisioning Portal.

So, assuming you are registered with the Apple Developer Program, you need to complete the following steps.

  • Generate a “Certificate Request” from your OSX Keychain and store the file locally.
  • From the Apple Developer Website, go to the Provisioning Portal and create an Application Id. The name you use is important and it’s needed later.
  • Go into the details of the Application Id you have created and select “Enable for Push Notifications”, and then select the “Configure” button next to the Development Push SSL Certificate option.
  • A Wizard will start up, and you will need to provide the Certificate Request you generated and downloaded earler. The Wizard will generate your Push SSL Certificate for you to download. You will need this certificate to talk with the APNS Server.
  • Create a Provisioning Profile for your iOS device using the Application Id you created.

The screenshot below shows an Application Id with Push Notification enabled.

image

 

Step 2. Build the iOS Client Application.

Open Xcode and create a new Window Based iOS application. Make sure you use the Application Id you created in the Provisioning Portal for the Product Name of your new applcation. The Project that Xcode creates for you should look like this (my application is called “pushnotificationdemo”). Note that this example is for a Universal application, but the PoC will work just as well for an iPad or iPhone specific project.

image

For the PoC, the XCode application will serve 2 purposes. The first is to give us a way to get the Device Token for our Device. When we use the APNS to push a message to a Device, the Device Token is the unique identifier used to make sure that it is only our device that receives the notification.

The second purpose of the PoC is to provide a client application to listen for Push Notifications. Those familiar with iOS devices will know that when an application receives a push notification a popup is displayed showing the message that was sent, and the “Badge” on the application icon is updated with the badge count sent with the notification.

The screenshot below shows all the code you’ll need to make the PoC work.

image

For those not familiar with iOS development, the didFinishLaunchingWithOptions method is called when an iOS application is started. This gives us a place to set up the application, determine what is displayed first, and then open the Application Window. In this case I have not used any views, as the PoC is only being used to test the APNS.

By calling registerForRemoteNotificationsTypes, we are telling iOS that this application wants to register for Push Notifications. This registration request is sent to the APNS at Apple. If this call is successful, the didRegisterForRemoteNotificationsWithDeviceToken method is called, and we can write the returned device token to the console.

To complete the client application, we need to assign the Provisioning Profile we created earlier. We do this by signing the code.

image

At this stage we can deploy the application to our iOS device. By executing the application through Xcode we can see the device token displayed in the Console. 

image

Once you have your device token you can move onto the next step.

 

Step 3. Talking with the APNS.

We now need to build our Notification Provider application that will generate the notifications that are sent to our iOS device. Our Provider will need to do 2 things.

  1. Open a secure socket to the APNS servers. This is what the Push SSL certificate generated in the Provisioning Portal will be used for.
  2. Create a message in the APNS format and send this via the opened socket. The message is composed of the device token and a JSON string representing the message details. The 2 components are converted to a binary format for transmission.

How I wish the WAS could open a TCP socket on an arbitrary port for me! Maybe its my BASIS skills failing me, but I can’t see how to do it…So my next choice is to open up NWDS and see how rusty my Java is 😉

I have built 2 Java classes to interact with the APNS. The first is an abstraction of the APNS service, and has one public method “sendNotification”. The code for this is shown below.

image

The class also has a private method used to open the secure socket connection to the APNS.

image

For clarity, the constants that I have used for the secure socket connection are:

image

The second class represents the actual APNS Notification. The class implements a toByteArray method which is used by the sendNotification method. This allows us to encapsulate the details of the Notification format within the Notification class, while providing a simple interface for the user to create the Notification. The details of how we create a Notification will be seen later in the blog. 

Below are extracts of the toByteArray method, and one of its private helper methods.

image

image

The method convertDeviceTokenToByteArray is an implementation of a HEX to Binary conversion routine. 

At this stage you will be able to to test sending notifications to your iOS device.

Please see the Apple Developer Library for a detailed discussion of the APNS Notification format.

 

Step 4. Connect SAP to the Provider Application. Did anyone say JCo?

So what’s the easiest way to make my Java APNS Provider and my WAS talk? Well in this case I believe it’s the SAP Java Connector (JCo).

Creating a JCo Server is fairly trivial. The code below is probably about as simple as it can get.

image

There are 2 important things to note in the code. The first is the factory call to getServer(SERVER), which maps to a properties file called SERVER.jcoServer. This provides details such as the Program Id and the SAP Gateway host. These details are needed when we create the RFC Connection in SM59. There is also a reference to a “Repository Destination”, which is needed for the new Connection Management model in JCo 3.0. This will require a second file to be placed on the server with the extension jcoDestination.

Examples of the 2 files are shown below.

image

The second point worth noting in the Server code is the function registration via the registerHandler method. We simply register the SAP function name against a class that implements the JCoServerFunctionHandler interface. For my PoC I have created a function module Y_PUSHWFCOUNT and the associated Java class PushWFCount. The implementation of this class is shown below.

image

This class ties the SAP function call to the APNS code we wrote earlier. The first part of the method just extracts the contents of the importing parameters. The next step is the creation of the Notification. Here you can see how a “Fluent Builder” allows us to express the intent of what we are doing, making our code more readable. The final step is to send the notification with our APNS functionality.

Not far to go now, were finally at the ABAP bit!

 

Step 5. Some ABAP at last!!!

It’s taken a while but we’re finally working with our beloved WAS. The first thing we need to do is create an RFC connection to our JCo server. Note that the Program Id must match the Program Id in our SERVER.jcoServer file.

image

Make sure you test the connection before going any further.

Next, we need to create an RFC enabled function module. In my PoC I have called the function module “Y_PUSHWFCOUNT”. You can see in the Importing Parameter definitions that the parameter names match those used in the PushWFCount class where the parameters are extracted.

image

 

Step 6. A Test.

Now that we have our function module defined and our RFC destination in place we can execute the function module in the test harness and watch what happens. Note the RFC target system is APNS, which is the RFC destination we set up earlier.

image

And then, as if by magic, I get the folowing on my iPad. Time for a very large Latte 🙂

image

You can see that the Badge Count for the application is also updated to 7.

 

To Finish.

I started this blog talking about pushing a notification to my iOS device whenever I received a new Workitem. Now I have my Y_PUSHWFCOUNT function I can integrate this into the WF runtime and do exactly this. 

Of course, looking back on this now, the RFC function module should have been a generic interface to the APNS Provider functionality, providing a level of abstraction that we can use in many places, rather than a specific WF Function.

There are many other questions here too, like how to manage the Device Tokens and match them with Users or Work Crews.

I see this PoC as more of a start down the road to discovering what type of functionality can be built utilising this capability.

Happy Building!

To report this post you need to login first.

9 Comments

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

  1. Gregory Misiorek
    Hi Al,

    so, no Java means no notifications? actually, i have read your first blog and enjoyed how you have challenged the “gateway”. but what i may have missed in this blog is like a simple list of what is required for your solution to work, eg:
    WAS
    JCo
    XCode,etc
    some SAP installations may not allow all the pieces, something probability of which increases with the number of components listed.

    (0) 
    1. Gregor Wolf
      Hi Alisdair, Hi Gregory,

      first a thank to Alisdair for this great writeup. In January I was approached by a SCN community member asking me how to setup a SSL connection. By the logs provided I’ve figured out that he tried actually to connect to APN. At the end we managed to get all the certificates correctly in place using STRUST but finally failed to connect using ICM as it’s not a HTTP(S) connection. Would be great to do RAW Sockets from ABAP :-). But perhaps Apple sometime also supports HTTPS.

      @Gregory: I think you’ve listed all the required components correctly. In addition to XCode you also need to sign up as an Apple Developer. The Java Part could perhaps be replaced
      http://code.google.com/p/apns-php/ which runs on PHP. Or you could try http://apnonrails.metabates.com/. That could perhaps run on the Blue-Ruby Project
      (https://cw.sdn.sap.com/cw/groups/blue-ruby) . That would then run again in the ABAP Stack ;-).

      Best regards
      Gregor

      (0) 
  2. John Moy
    Thanks for sharing this Al.  Showing your talents by coding in no less than 3 languages for this blog!   Great detail too.  I’ll be bookmarking this one.

    I presume you did ask Tony about direct connectivity via ICM?

    Cheers

    John

    (0) 
    1. Alisdair Templeton Post author
      Hi John.

      You know, every time I write something in Java I wonder why I ever got into ABAP…

      The trouble with the ICF is that although you can configure the port that it communicates on, it’s still using HTTP as it’s protocol. The APNS uses a native tcp socket for communication, so to make this work with the ICF we would need to not send the standard HTTP headers. I couldn’t see a way to do this…but would be happy to hear from anyone that has!

      Congratulations again on making the Wolfpack!

      AT

      (0) 
  3. Matthew Harding
    I’m just wondering how you would do this with a Super Generic Mobile Framework like the one I saw at DemoJam last year???
    Just kidding – Nice work!
    (0) 
    1. Alisdair Templeton Post author
      Hi Matt,

      Oh yeah, I remember that one 😉

      I think those guys were good enough to put their demo on the Code Exchange, so I should download it and give it a go. I think a framework like PhoneGap may be required…

      AT

      (0) 
  4. Joao Sousa
    The simple workaround I use is writing the notifications in a table inside SAP, and then running a PHP light script to read the table and send the notifications.

    Ok, it’s not real push, but the script is running locally and is very lightweigth so you can ping SAP every minute for new messages.

    (0) 

Leave a Reply