Over the past few weeks, i’ve been working on creating “demo” apps for SimplePush integration into third party message transport systems. If i’ve lost you in the previous sentence’s word salad, feel free to bail on this post, because it’s going to get a wee bit cranky, and a whole lot geeky. Actually, strike that, reverse it.
Wherein i talk about why i walked into the tarpit
Right, so let’s start from the beginning. Mozilla is rolling out a messaging system for programmers. There’s a lot of these sort of things out there, but mostly they’re like email was back in the bad ol’ days of Prodigy, AOL and Compuserve. Folks who used those systems couldn’t send email to folks who were on other systems, or at least, couldn’t do so easily. Then came some discussion, standards meetings, and the Simple Mail Transport Protocol (SMTP) was introduced. Now, various folks could send mail to other various folks, and after copious arm twisting, customer demands, and folks leaving to use The Internet (because that didn’t have weird restrictions like the older platforms did), the companies caved and converted to SMTP. Much joy was to be had. Well, for a little while at least.
Fast forward a few decades and we’re back in the same spot again, only this time, it’s with how servers can send messages to your devices. Turns out, that’s kinda tricky. Your laptop, phone, tablet, watch, belt buckle, shoelaces, and fridge can pretty easily connect up to sites like Facebook, Google, and RedTube (your belt, sadly, is REALLY into bondage for some reason). That’s because those sites pay money to be at well known locations on the internet. You, however, don’t. You move around. One minute you’re at home, then 30 minutes later you’re at work, or headed down the freeway. Turns out that you moving around so much makes it hard to get something to you. (Imagine that your cellphone number changed between locations, and a few times while you’re between locations. That’d make it a bit hard for folks to get in touch with you.) Turns out exactly that happens with your various gadgets. That means that if you wanted to get stuff like chat messages, or surf reports, or a lot of other things, that could lead to all sorts of problems.
Turns out there are a bunch of ways that folks have tried to solve this problem, and have been trying to solve it for a while. Apple, & Google are the big players in this area (much like Prodigy, AOL and CompuServe were with email in the very early days of the internet). Sadly, none of these play nice together. You can’t use the same system to talk to Google that you do for Apple. Heck, you can’t even send the same sort of data to Google that you can to Apple.
Thus, very smart folk have sat down and created a standard for all of this. This standard is still in the works, but there’s a prototype that i’ve been working with for a while. That’s SimplePush, and much like email, it tries to make things easier for sites you want to hear from to send you things you’re actually interested in getting. Now, because those big systems are big systems, and because those big systems are VERY TIGHTLY INTEGRATED into devices, it makes sense that we try to use those notification systems to carry some of the data we want to send.
For some systems, this can be interesting.
And then there’s Apple.
In which i note that i’m not a fan…
i’m not a fan of Apple. i’ve a long, and somewhat checkered history with the company, and while i appreciate that they have an excellent eye for product design that has lead to a good deal of improvement in tech, i’ll note that Disney has had an equally large impression on amusement park theme rides, but i’m rather happy with my car not following a rail and limited to 15mph.
Fortunately, i’ve had little need to deal with Apple products. i get my music from Amazon, watch movies on Netflix, generally work on Unix systems (i tend to run Windows as the UI client, but most of the apps i run there are Open Source.) i have no beef with other folks using Apple products and, frankly, the office here is pretty much filled with Apple laptop chargers because of the enormous number of Macs in the building.
Suffice to say that i’m a bit biased against the legacy of Steve, but still reasonably polite to the odd Apple recruiter that called.
The Procession of Ducks
In which we learn it is better to be eaten whole by alligators, than nibbled to death by ducks
Right, so first i needed to build a version of SimplePush that used Google Cloud Messaging as it’s carrier. i grabbed a copy of Android Studio, fired it up, and in about 6 days, used Java to write a simple demo app that let me connect to the server, and fire messages that were then echoed back to the app over GCM. i’m not going to claim that it’s a masterpiece of elegant code or anything, but it works well enough to test out if things on the server are working.
About the only really annoying thing is that the key bindings in Android Studio can’t be mapped to Vim, so i would occasionally write :w! in the code. i knew Java from a previous job, and it’s bloody java so it’s not like it’s hard to find things. If you like, you can play with the demo using the built in emulator or “side load” it to any device you’d like.
That done, i turned my attention to Apple Push Notification System (APNS). And there in lies my tale of woe.
Apparently, to build iOS apps of any sort, i need to get xCode (an compiler environment for Macs), an iOS device, and a $99 Apple iOS developmental license. i was able to borrow a mac from work, i had my wife’s old iPad2 as the device, but had to pony up the $99+tax fee out of pocket. If i were to go the cheapest possible route, i’d have to pay $500 for a mac mini + $250 for an ipad mini + the $100 iOS development license. Why do i need a real device? Because the APNS requires a real device. It doesn’t work in an emulator. So, close to a grand out of pocket vs what i would have had to spend for GCM, which was $0.
Receipts filed for next years tax season, i decided to dig in. And that’s when i encountered ObjectiveC.
[[intent alloc] withSarcasmAndSlightMalice: @Seriously];?
Granted, i could have used Swift, but in either case, this is a language specific to writing apps for a specific platform. That’s a bit like having to learn Esperanto to order a lunch. i won’t get into the oddities of ObjectiveC (and there are a lot of them), but i’ll note that you really do need to use xCode to write the app. This is because there are whole portions of the app that can only really be built by dragging connectors around like you’re running a 1920’s era switchboard.
Then there’s the certificates. God, the certificates. i get TLS. It’s wonderful for security because it’s using really large bits of math in order to prove you are you and i am i, and you get it for free with browsers. Granted, for this, i need a certificate saying who i am. i then need another certificate that is signed against the first certificate to indicate the app is my app (ok, that seems fair). i then need to export the certificate parts, convert them to a different format, so i can turn them into another format and store them on my server for the connection back to the APNS server which (obviously) needs to have the certificate it knows about me.
This is why OAuth is popular.
Oh, and in addition, i’ll need to get the long, complicated device id off of the iOS device using a completely program that tries to sell you Kanye West and Pitbull songs so that it can be one of the 1000 devices you’ve specifically blessed to run this app outside of the closely guarded and completely arbitrarily governed sanctum they’ve established. Because, obviously, why would anyone ever want to build testing or demo apps?
Anyway, back to the demo app. Once you’ve got the crux of things (hopefully) working, you then have to try sending the actual notification. This is done using a binary format. Well, actually, one of two. There’s the oldest format which consists of a “0” + the length of a token + the token + the length of the message + the message in JSON format. The message JSON needs to be constructed according to a reasonably simple structure, and after you feed the beast, you get a response back indicating if the message was accepted. Most examples will refer to this format.
Then there’s the new format, which has a 2 + the length of all the items combined + the items [ 1 + length of the token + token, 2 + length of the message + the message, 3 + length of an id + the id, 4 + length of the expiration time + expiration time, 5 + length of the priority flag + priority flag]. This information is bundled up and fed to the beast and you get a response back indicating if the message was rejected. You get nothing back if it was accepted. Mind you, it could take a second or two to process the data, so you ought to hang around a bit waiting, just in case. Oh, and after the third message or so, the server will drop your connection, so you’ll have to reconnect. Golly, and because i nearly forgot, you’ll also want to hang onto messages you’ve sent recently because there’s no ACK and you’ll need to resend them later if they’re requested. Because i’m a nice guy, here’s a PHP script built off the most common example that uses either v0 or v2 APNS.
Oh, and also? Even if the server accepts the message and says there’s no problem. There may be a problem and the service will just silently eat the message. So, if you do something silly and screw up the length of a field, or don’t specify the expiration with just enough buffer, or maybe have a typo in the JSON data, the message is helpfully shot into the void never to be heard from again. This makes debugging a bit of a challenge, but hey! It’s apple! It just works! Unless it doesn’t, in which case it’s your fault and you should fix it, you moron.
(Honestly, it would be lovely to have a service set up that would actually verify the data you’re sending in to it and see if it’s correct. i should write one.)
In which the hero walks to the sunset behind La Brea
Much swearing and twiddling later, it is possible to use APNS to send data to apps. i’m still missing a few additional things, and will have to create them before this goes fully live, but it’s good enough for early prototyping.
So, in theory, i’m over the worst of it. i should be happy, right?
Well, no. You see, having built this, i recognize that this is more than a one or two week process. i’m going to need to have a stable mac environment to work in for a while. That means i’m going to have to swap the loaner macbook for a mini. i’m also going to have to get a mini for my home because there will be days i’ll want to work from home, and i’ve discovered that remote desktop services on macs (or at least on the loaner) is… problematic. Fortunately, i’ll be able to toss the little crapbox into the garage where it can spin it’s fans up and not keep the rest of the house awake. It also means that i’ll be hanging onto the wife’s old iPad for a while, mostly for the same reasons (hopefully, i won’t have to get a second one of those).
Apple, the craft glitter of computing.
Once that i am actually DONE with this crap, i might see if i can put Linux on the mini and use it as a NAS or something. Having hot plugged a USB 3.0 NTFS drive into the mac and not seeing it show up does not bode well, but that could well be a FUSE solvable problem.
All i can say is that this experience has not endeared me to apple at all. (Seriously? Damn near every platform out there has used Ctrl as the principal modifier key, but apple decides to use it’s own, and has the key sit right next to the spacebar? No wonder they want you to use the mouse for everything.) Frankly, sometimes it seems that Apple exists just to ebb joy out of my life.
But, people love them, and are happily effervescent about the Emperor’s wardrobe choices. Even if he’s standing on his thrown, gyrating his hips, and making helicopter noises.