I made a prototype of earthquake early warning system in one week. The scenario goes as follows: We use a Friendly ARM SBC (Single-Board Computer) as an earthquake signal collector and processor. If the signal was identified as serious earthquake, it would send a message to our server. Then our server will authenticate the message and use Apple Push Notification Service (APNS) to notify some iPhone registered for the notifications.
The demo video:
Apple Push Notification Service (APNS)
There are two ways to show up a notification even if app wasn’t active. One is local notification and the other is server-pushed notification.
Local notification are scheduled by an iOS application. It’s iOS only.
Push notification are sent by a remote server to Apple Push Notification service, which pushes the notification to devices on which the application is installed.
There are a lot of limitation in alert message. So one must use it wisely. The maximum size allowed for a notification payload is 256 bytes. APNS refuses any notification that exceeds this limit. The notification is encoded in a JSON string, the properties go as follows:
- alert If this property is included, iOS display a standard alert. This
property can be a string or a dictionary. If it was a dictionary, below are
the properties of alert.
- body The text of the alert message
- action-loc-key Display an alert with two buttons. The right buttons’s title would be this key.
- loc-key A key to an alert-message string in a
Localizable.strings
file for the current localization. - loc-args Variable string to appear in place of format specifiers in loc-key.
- launch-image The file name of an image in application bundle, which will be shown on the display message.
- badge The number to display as the badge of the application icon.
- sound The name of the sound in the application bundle. Set the property to default then the default sound is played.
To develop and deploy the provider side of a client/server application, you must get SSL certificatates from Apple Dev Center. Apple has a guide for this.
After setting up provisioning on Dev Center, you can get the certificate and key
in .pem
format, with following commands.
openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
Remember to setup your bundle identifier and code sign as same as your provisioning profile uploaded to apple.
Sometimes you might bump into bugs that your code sign wouldn’t work when you renew your bundle identifier. If so, just restart XCode.
Server CGI script
I use Perl to be cgi server. There are already a lot of APNS plugins that you can find in most popular languages. So just pick what is comfortable to you for implementing server side application.
My script that handles APNS looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
The device token is generated by your app. You will first register when your app
launch, then get the token from method - (void)application:(UIApplication
*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData
*)deviceToken
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
ARM board
I use Friendly ARM 6410 for prototyping.
Here are some configuration details:
booting
In minicom
remote shell:
> boot-args:
> root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200
The boot args is quite important else you won’t get the shell from the device or you may not boot it successfully. It took me a while to find the correct boot args.
cross compile
If some desired library are not included in the board, you can cross compile it from source. However, the configuration is a bit complex then normal compilation:
$ ./configure --host=arm-linux-gnu --target=arm-linux CC=arm-linux-gcc \
$ AR=arm-linux-ar LD=arm-linux-ld RANLIB=arm-linux-ranlib \
$ --prefix=/opt/curl --without-ssl
The cross compiled library can be uploaded to ARM board via ftp:
$ ncftp -u user -p passwd $IP
> put curl.tar.gz
You can find the $IP
in minicom remote shell by ifconfig
.