I have recently been working on sending Push Notifications for an iPhone app. The Ray Wenderlich web site has a (dated but still) great post to get you started with this and includes some PHP code for transmitting the messages to the Apple Push Notification Server (APNS). I won’t rehash what Ali Hafizji went over in his post, rather just suggest you have a read yourself.
There are free and “nearly free” services that offer customers a service that communicates with APNS, but they just leave you communicating with their servers, rather than directly with Apple’s. At the risk of sounding like “not invented here syndrome” I wrote my own application.
Apple document the comms format used. It’s a binary message format. “Back in the day” I did more than my fair share of binary comms . Like a lot of my peers I had my share of writing Point of sales software. Most peripherals in those days used differing binary formats over RS232 to communicate. Apple’s format differs from how I remember binary protocols from working, so I wanted to share some potential pitfalls that I noted. (One of which I fell in, others I skilfully / luckily? avoided)
Numbers are stored big-endian.
If you are writing your application on a Windows machine, then your numbers will be stored little-endian. In my case, I was using C#. The BitConverter class provides methods to get the byte array representing the number, as well as a property that you can check to see if you need to reverse the array. I guess with Mono, there’s a chance that your C# code will end up running on an O/S that is big-endian – so it probably pays to check first, before reversing the byte array!
The frame data is not simply a in-memory version of the third table
This is the trap I fell in – and in retrospect it was a silly mistake caused by misinterpreting the sentence:
The frame data is made up of a series of items. Each item is made up of the following, in order.
Each item contains an item identifier, an item data length field, and the item data itself. Unlike previous binary comms that I have done, this means that length fields appear throughout a transmission. This is not exactly necessary, as there is only one variable length field. While I consider it “not exactly necessary” it does lend itself to forward compatibility that would otherwise not be possible.
The APNS servers only respond with errors – sometimes
When I was struggling with malformed frame data I would often not get an error message response from the APNS. I don’t know why this would be the case. In my experience, if your iDevice does not receive your notification within thirty seconds, you have probably done something wrong! My experience was most were received within three or four seconds…
Not every item-type needs to be in your frame data
Out of interest, I started experimenting with leaving out frame-data items. It appears safe to leave out the “expiration-date” if you wish. I would guess that leaving it out, is the same as specifying zero. That is, if the message cannot be delivered straight away, the APNS will not attempt any delayed delivery.
You do not have to reinvent the wheel!
Late in the piece, I came across the PushSharp open source library. Chances are, I will switch over the code I wrote to use this project instead. It supports all major mobile platforms, not just Apple.
Still, I wanted to rattle off what I learnt in building this app, in the hope that it may help someone avoid a gotcha!
Good luck and happy coding!