2 Dec 2009 ... Introduction to Apple Push. Notification Service (APNS). Mark Aufflick mark@
aufflick.com. December 3, 2009 notification notification. APNS.
Introduction to Apple Push Notification Service (APNS) Mark Aufflick
[email protected] December 3, 2009
Provider
Mark Aufflick
notification
APNS
notification
notification
Client App
December 3, 2009
Slide 1/20
Push Notifications What are they for? Infrequent sms-style user alerts
Setting your app’s numerical badge
What are they not for? delivering required application data 256 byte (yes, byte) maximum payload delivery not guaranteed only last message delivered Mark Aufflick
December 3, 2009
Slide 2/20
App/Device Registration
Provider
Device
APNS
Connect (Token, ...) Generate token package Generate device ID from device certificate Encrypt token with token key Token Token
Mark Aufflick
December 3, 2009
Slide 3/20
Notification Transmission
Provider
APNS
Device
Connect (Token, ...) Decrypt token and validate with device certificate Response (OK)
Token, Payload
Decrypt token with token key Payload
Mark Aufflick
December 3, 2009
Slide 4/20
The Notification This is a binary format so needs some care Apple docs are unclear on JSON encoding A little trial and error is required 256 byte limit is on payload only Device tokens are currently always 32 byte, but you shouldn’t hard code that Only Command 0 currently used Alert body can be internationalised Sound string refers to soundfile in your App bundle (or ‘default’) Command
Token length
0 Bytes:
Mark Aufflick
1
0
32 2
(big endian)
Payload length
deviceToken (binary) 32
0
34 2
(big endian)
{"aps":{"alert":"You have mail!"}} 34
December 3, 2009
Slide 5/20
Notification Payload
alert alert
alert
badge
sound default
Mark Aufflick
December 3, 2009
Slide 6/20
Notification Payload (Complex alert) body action-loc-key
null
null
loc-key
Localizable.strings %@ loc-args
% $@
loc-args loc-key
Mark Aufflick
December 3, 2009
Slide 7/20
Feedback If a user removes your app, their device will reject your notifications APNS will notice this and let you know via the Feedback service Token length
time_t n Bytes:
n
n 4
(big endian)
n
0
32 2
(big endian)
deviceToken (binary) 32
APNS monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices. You have been warned :) Mark Aufflick
December 3, 2009
Slide 8/20
Getting Ready You will need the following for each app: App/Bundle ID Push Certificate Push Private Key Provisioning Profile
Actually, you need two sets: Development Production
The wizard in the Developer Portal does a good job of walking you through the process online and in Keychain Access.app Mark Aufflick
December 3, 2009
Slide 9/20
Registering Application/Device Each App/Device needs to register Simple as the following in your applicationDidFinishLaunching: method: [ application r e g i s t e r F o r R e m o t e N o t i f i c a t i o n T y p e s : ( UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | U I R e m o t e N o t i f i c a t i o n T y p e B a d g e ) ];
That’s when you see the alert asking for push permission
Mark Aufflick
December 3, 2009
Slide 10/20
Uploading The Token Remember the interaction diagram? APNS will return the token to the phone But you need it at your server end Or there could be an error (eg. in simulator) - ( void ) application :( UIApplication *) application d i d R e g i s t e r F o r R e m o t e N o t i f i c a t i o n s W i t h D e v i c e T o k e n :( NSData *) deviceToken { pushToken = [ deviceToken retain ]; [ self p e r f o r m S e l e c t o r I n B a c k g r o u n d : @selector ( uploadToken ) withObject : pushToken ]; } - ( void ) application :( UIApplication *) application d i d F a i l T o R e g i s t e r F o r R e m o t e N o t i f i c a t i o n s W i t h E r r o r :( NSError *) error { NSLog ( @ " Error in registration. Error : %@ " , error ) ; } Mark Aufflick
December 3, 2009
Slide 11/20
Uploading The Token Continued - ( void ) uploadToken { N S A u t o r e l e a s e P o o l * threadPool = [[ N S A u t o r e l e a s e P o o l alloc ] init ]; // There ’s probably an easier way... N SM ut ab l eS tr in g * tokenHex = [[ pushToken description ] mutableCopy ]; [ tokenHex r e p l a c e O c c u r r e n c e s O f S t r i n g : @ " " withString : @ " " options :0 range : NSMakeRange (0 , [ tokenHex length ]) ]; [ tokenHex r e p l a c e O c c u r r e n c e s O f S t r i n g : @ " " withString : @ " " options :0 range : NSMakeRange (0 , [ tokenHex length ]) ]; NSString * su bm it U RL St ri n g = [ NSString s t r i n g W i t h Fo r m a t : YOURAPP _ TOKEN _ UPLOAD _ URL " ? tokenHex = %@ " , tokenHex ]; NSURL * submitURL = [ NSURL URLWithString : su b mi tU RL S tr in g ]; NSString * res = [ NSString s t r i n g W i t h C o n t e n t s O f U R L : submitURL ]; [ threadPool release ]; } Mark Aufflick
December 3, 2009
Slide 12/20
Receiving Notifications If your app is not running and the user taps View on the alert - ( BOOL ) application :( UIApplication *) application d i d F i n i s h L a u n c h i n g W i t h O p t i o n s :( NSDictionary *) launchOptions { NSLog ( @ " options : %@ " , launchOptions ) ; [ self a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : application ]; } Wed Dec 2 23:21:27 unknown PushTest [2268] < Warning >: options : { UIApplicationLaunchOptionsRemoteNotificationKey = { aps = { alert = " 02 - send.t second " ; badge = 1; sound = default ; }; }; } Mark Aufflick
December 3, 2009
Slide 13/20
Receiving Notifications (Continued) If your app is running - ( void ) application :( UIApplication *) application d i d R e c e i v e R e m o t e N o t i f i c a t i o n :( NSDictionary *) userInfo { NSLog ( @ " %@ " , userInfo ) ; } 2009 -12 -02 23:29:42 .201 PushTest [2309:207] { aps = { alert = { " action - loc - key " = < null >; body = " 02 - send.t fourth " ; }; badge = 1; sound = default ; }; foo = bar ; } Mark Aufflick
December 3, 2009
Slide 14/20
Sending Notifications (Overview) Preparation You need the Certificate and Private key on your server Export them from Keychain Access.app Many server libraries will require PEM format with no password: openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12 openssl pkcs12 -nocerts -out key.pem -in keypw.p12 openssl rsa -in keypw.pem -out key.pem
Remember Dev and Prod Cert/Key pair are different
Server code Create TLS connection Construct one or more binary notification structures send on connection ... Mark Aufflick
December 3, 2009
Slide 15/20
Sending with Net::APNS::Persistent Perl (fast, good binary format & TLS support) Perl 5.8 minimum for reliable UTF-8 handling Automatically limits your payload to 256 bytes Installing: sudo cpan Net::APNS::Persistent use Net :: APNS :: Persistent ; my $apns = Net :: APNS :: Persistent - > new ({ sandbox = > 1 , cert = > ’ cert . pem ’ , key = > ’ key . pem ’ , }) ; $apns - > q u e u e _ n o t i f i c a t i o n ( ’ 04 ef ... a878416 ’ , { aps = > { alert = > " caf \\ xc3 \\ xa9 " , sound = > ’ default ’ , badge = > 1 , } , }) ; $apns - > send_queue ; Mark Aufflick
December 3, 2009
Slide 16/20
Example showing UTF-8 Notification of a speech by Demosthenes in the 4th century BC:
He’d be right into the iPhone for sure. Mark Aufflick
December 3, 2009
Slide 17/20
Getting Feedback–Net::APNS::Feedback use Net :: APNS :: Feedback ; my $apns = Net :: APNS :: Feedback - > new ({ sandbox = > 1 , cert = > ’ cert . pem ’ , key = > ’ key . pem ’ , passwd = > ’ key password ’ , }) ; my @feedback = $apns - > r e t r i e v e _ f e e d b a c k ;
If the iPhone has no active push apps, it will drop the connection to save power This means that the notification is never rejected and you get no feedback Sandbox & Prod connections are different Thus you need at least a dummy sandbox app installed for feedback testing Mark Aufflick
December 3, 2009
Slide 18/20
Feedback response data If there is any time t is an epoc time (in seconds) token is the device token you should stop sending to You can get duplicate tokens (as below) [ { ’ time_t ’ = > 1259577923 , ’ token ’ = > ’ 04 ef31c86205 ...624 f390ea878416 ’ }, { ’ time_t ’ = > 1259577926 , ’ token ’ = > ’ 04 ef31c86205 ...624 f390ea878416 ’ }, ] Mark Aufflick
December 3, 2009
Slide 19/20
Resources
Apple Push Notification Service Programming Guide
Net::APNS::Persistent and ::Feedback On CPAN search.cpan.org/search?q=Net::APNS::Persistent
Source on Github http://github.com/aufflick/p5-net-apns-persistent
Mark Aufflick
December 3, 2009
Slide 20/20