Tuesday, June 23, 2009

Sending push notification locally.

So far I haven't found a reliable push notification app yet to test GriP Push Notification (QuickPigeon is the most reliable one I've ever tried, but it held up 2 trial mails quite a long time).

So what about faking push notifications? After a push notification is just a TCP packet. The first thing I do is to set a breakpoint on the most suspicious method -- -[SBRemoteNotificationServer connection:didReceiveMessageForTopic:userInfo:] (0x9ffa5). And indeed, when a push notification comes, the break point is hit (multiple times).

I used the breakpoint command
call (void)CFShow($r2)
call (void)CFShow($r3)
call (void)CFShow(*$sp)
c

to record the arguments. And not surprisingly, the userInfo is an NSDictionary of the payload, like
{
aps = {
sound = "hello.aif";
alert = "Hello world!";
};
};

The Apple's documentation on this is more in detail. The "topic" parameter is the bundle ID of the app to receive the notification, and connection is an APSConnection object.

Given these results, we can craft our notification packet with a Mobile Substrate extension.

Right now, you can download FakePushNotification.zip and test it out. To install:
  1. Put the .dylib and the .plist to /Library/MobileSubstrate/DynamicLibraries
  2. Put the executable (FakePushNotification) to /usr/bin and chmod a+x it.
  3. Respring
  4. In command line, type e.g.:
    FakePushNotification com.yourcompany.pushEnabledApp -
    aps={
    alert={
    body = "Hello world!";
    action-loc-key = "Welcome!";
    };
    };
    ^D

    The "payload" must be in plist format, not JSON format.

Note: the program is written to demonstrate how it can be done. It is not bug free. In particular, sending a string that cannot be interpreted as a plist will cause your device crash and go into safe mode. Use with caution.

2 comments:

  1. Could this be implemented as a Growl-plugin (http://growl.info/)? That way any Mac app can send notifications to your iPhone... This would be cool.

    ReplyDelete
  2. I've setup a test harness for sending push notifications, so that I could automatically test my toolkit's push notification handling code. My harness runs on Heroku's infrastructure, and it easily fits into the free tier. If you're still looking for a push notification sending service, you could bring up your own instance, change the code, etc, it's all open source.

    My test harness: http://github.com/costan/zn_testbed/ (you probably want to read app/controllers/imobile_support_controller.rb)
    Heroku's free tier: http://heroku.com/pricing#blossom-1
    My Ruby gem for sending push notifications: http://github.com/costan/imobile
    My toolkit code handling push notifications on the iPhone: http://github.com/costan/zergsupport/

    I hope this helps you or your readers.

    ReplyDelete