Grocer
grocer interfaces with the Apple Push Notification Service to send push notifications to iOS devices.
There are other gems out there to do this, but grocer plans to be the cleanest, most extensible, and friendliest.
Installation
Add this line to your application's Gemfile:
gem 'grocer'
Usage
Connecting
# `certificate` is the only required option; the rest will default to the values
# shown here.
#
# Information on obtaining a `.pem` file for use with `certificate` is shown
# later.
pusher = Grocer.pusher(
certificate: "/path/to/cert.pem", # required
passphrase: "", # optional
gateway: "gateway.push.apple.com", # optional; See note below.
port: 2195, # optional
retries: 3 # optional
)
Notes
gateway
: Defaults togateway.push.apple.com
only when running in a production environment, as determined by either theRAILS_ENV
orRACK_ENV
environment variables. In all other cases, it defaults to the sandbox gateway,gateway.sandbox.push.apple.com
.retries
: The number of times grocer will retry writing to or reading from the Apple Push Notification Service before raising any errors to client code.
Sending Notifications
# `device_token` and either `alert` or `badge` are required.
#
# Information on obtaining `device_token` is shown later.
notification = Grocer::Notification.new(
device_token: "fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2",
alert: "Hello from Grocer!",
badge: 42,
sound: "siren.aiff", # optional
expiry: Time.now + 60*60, # optional; 0 is default, meaning the message is not stored
identifier: 1234 # optional
)
pusher.push(notification)
It is desirable to reuse the same connection to send multiple notifications, as is recommended by Apple.
pusher = Grocer.pusher()
notifications.each do |notification|
pusher.push(notification)
end
Feedback
# `certificate` is the only required option; the rest will default to the values
# shown here.
feedback = Grocer.feedback(
certificate: "/path/to/cert.pem", # required
passphrase: "", # optional
gateway: "feedback.push.apple.com", # optional; See note below.
port: 2196 # optional
retries: 3 # optional
)
feedback.each do |attempt|
puts "Device #{attempt.device_token} failed at #{attempt.timestamp}
end
Notes
gateway
: Defaults tofeedback.push.apple.com
only when running in a production environment, as determined by either theRAILS_ENV
orRACK_ENV
environment variables. In all other cases, it defaults to the sandbox gateway,feedback.sandbox.push.apple.com
.retries
: The number of times grocer will retry writing to or reading from the Apple Push Notification Service before raising any errors to client code.
Device Token
A device token is obtained from within the iOS app. More details are in Apple's Registering for Remote Notifications documentation.
The key code for this purpose is:
- (void)applicationDidFinishLaunching:(UIApplication *)app {
// other setup tasks here....
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSLog(@"Got device token: %@", [devToken description]);
[self sendProviderDeviceToken:[devToken bytes]]; // custom method; e.g., send to a web service and store
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Error in registration. Error: %@", err);
}
Certificate File
Login to the iOS Provisioning Portal (App IDs).
Configure the appropriate certificate for push notifications and download the certificate:
Open the file in Keychain Access, then expand the certificate to show both the certificate and the private key. Command select so both are highlighted:
Control click and select to export the 2 items:
Save the items as a .p12
file. Open a terminal window and run the following command:
openssl pkcs12 -in exported_certificate.p12 -out certificate.pem -nodes -clcerts
The certificate.pem
file that is generated can be used with grocer.