A gem for the Apple Push Notification Service. This project was forked from https://github.com/muccy/APNS. This fork adds support for MDM APNS notifications.
Download this project, unzip it, then:
gem build apns.gemspec gem install apns-[version].gem
Convert your certificate
In Keychain access export your certificate as a p12. Then run the following command to convert it to a .pem
openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts
After you have your .pem file. Set what host, port, certificate file location on the APNS class:
APNS::Config.host = 'gateway.push.apple.com'
# gateway.sandbox.push.apple.com is default
APNS::Config.pem = '/path/to/pem/file'
# this is the file you just created
APNS::Config.port = 2195
# this is also the default. Shouldn't ever have to set this, but just in case Apple goes crazy, you can.
You can send single MDM notifications or multiple notifications at once:
# Single Notification
device_token = 'ea560dda056b9bf6825e41f04bcb5e3d6f2f10136db8efa54ca1699916a41c08'
push_magic = '12345678-90AB-CDEF-1234-567890ABCDEF'
APNS::NotificationSender.send_mdm_notification(device_token, push_magic)'
# Multiple Notifications
device_token_1 = 'a59c41d6a748d8abf5c8023b6632ac09996a9e20425fd411b626c7d07ce509b0'
push_magic_1 = '22345678-90AB-CDEF-1234-567890ABCDEF'
n1 = APNS::MdmNotification.new(device_token_1, push_magic_1)
device_token_2 = 'dec53d6ffb14525d12cf0a842f9f61f9f533f5b787705ac3551becbf722276f1'
push_magic_2 = '32345678-90AB-CDEF-1234-567890ABCDEF'
n1 = APNS::MdmNotification.new(device_token_2, push_magic_2)
APNS::NotificationSender.send_notifications([n1, n2])
Then to send a push notification you can either just send a string as the alert or give it a hash for the alert, badge and sound.
device_token = '123abc456def'
APNS::NotificationSender.send_notification(device_token, 'Hello iPhone!' )
APNS::NotificationSender.send_notification(device_token, :alert => 'Hello iPhone!', :badge => 1, :sound => 'default')
You can also send multiple notifications using the same connection to Apple:
device_token = '123abc456def'
n1 = APNS::Notification.new(device_token, 'Hello iPhone!' )
n2 = APNS::Notification.new(device_token, :alert => 'Hello iPhone!', :badge => 1, :sound => 'default')
APNS::NotificationSender.send_notifications([n1, n2])
You can send other application specific information as well.
APNS::NotificationSender.send_notification(device_token, :alert => 'Hello iPhone!', :badge => 1, :sound => 'default',
:other => {:sent => 'with apns gem'})
This will add the other hash to the same level as the aps hash:
{"aps":{"alert":"Hello iPhone!","badge":1,"sound":"default"},"sent":"with apns gem"}
Sending notifications can fail due to a number of reasons. The way the Apple notifications servers work is that,
they will let you know only if something goes wrong and only if you are using the enhanced notification format.
When sending single notifications. The gem will send the notification and will wait for 1 second for the APNS to send
a error message. This is usually enough time for the APNS to send a error message if it decides that your notification
has some error in it.
When you send a notification you will get a return value. Depending on whether there was any error you would get a
error or nil.
device_token = '123abc456def'
result = APNS::NotificationSender.send_notification(device_token, 'Hello iPhone!' )
The error object is a map containing the error.
{
:notification_id => 2,
:error => {
:type => 8,
:code => 7,
:description => "Invalid payload size"
}
}
Description of the fields in the error map
- notification_id – The id of the notification that failed. When sending single notifications the notification_id
is always 0. When sending multiple notifications this indicate the position (0 based index) of the notification
(which resulted in the error) in the array of notifications sent to the send_notifications method. - type – this is always 8. Its the type of the message sent by the APNS.
- code – error code
- description – description of the error
When sending multiple notifications you will get a array as the return value from the send_notifications method. This
contains a collection of map objects which details the errors occurred while sending notifications.
[
{
:token => "device_token_to_which_the_failed_notification_was_sent",
:error =>
{
:notification_id => 2,
:error => {
:type => 8,
:code => 7,
:description => "Invalid payload size"
}
}
}
]
After you setup push notification for your application with Apple. You need to ask Apple for you application specific device token.
ApplicationAppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application { // Register with apple that this app will use push notification [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)]; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // Show the device token obtained from apple to the log NSLog("deviceToken: %", deviceToken); }