Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

adding multiple notification sending

  • Loading branch information...
commit dc664d16623a1389ce3244593ccca4d4150713f8 1 parent e202dda
James Pozdena jpoz authored
40 README.textile
View
@@ -4,14 +4,22 @@ a gem for the Apple Push Notification Service.
h2. Install
-gem sources -a http://gems.github.com
-
-sudo gem install jpoz-apns
-
+sudo gem install apns
h2. Setup:
-Set what host, port, pem file and password on the APNS class:
+Convert your certificate
+
+In Keychain access export your certificate as a p12. Then run the following command to convert it to a .pem
+
+
+<pre>
+ <code>
+ openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts
+ </code>
+</pre>
+
+After you have your .pem file. Set what host, port, certificate file location on the APNS class:
<pre>
<code>
@@ -19,15 +27,14 @@ Set what host, port, pem file and password on the APNS class:
# gateway.sandbox.push.apple.com is default
APNS.pem = '/path/to/pem/file'
- APNS.pass = 'secret'
- # openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts
+ # this is the file you just created
APNS.port = 2195
# this is also the default. Shouldn't ever have to set this, but just in case Apple goes crazy, you can.
</code>
</pre>
-h2. Example:
+h2. Example (Single notification):
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.
@@ -41,6 +48,23 @@ Then to send a push notification you can either just send a string as the alert
</code>
</pre>
+h2. Example (Multiple notifications):
+
+You can also send multiple notifications using the same connection to Apple:
+
+<pre>
+ <code>
+ 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.send_notifications([n1, n2])
+ </code>
+</pre>
+
+
h2. Send other info along with aps
You can send other application specific information as well.
2  Rakefile
View
@@ -6,7 +6,7 @@ require 'spec/rake/spectask'
GEM = 'apns'
GEM_NAME = 'apns'
-GEM_VERSION = '0.0.4'
+GEM_VERSION = '0.9.0'
AUTHORS = ['James Pozdena']
EMAIL = "jpoz@jpoz.net"
HOMEPAGE = "http://github.com/jpoz/apns"
4 apns.gemspec
View
@@ -2,12 +2,12 @@
Gem::Specification.new do |s|
s.name = %q{apns}
- s.version = "0.0.4"
+ s.version = "0.9.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["James Pozdena"]
s.autorequire = %q{apns}
- s.date = %q{2010-01-18}
+ s.date = %q{2010-03-22}
s.description = %q{Simple Apple push notification service gem}
s.email = %q{jpoz@jpoz.net}
s.extra_rdoc_files = ["MIT-LICENSE"]
1  lib/apns.rb
View
@@ -1 +1,2 @@
require 'apns/core'
+require 'apns/notification'
11 lib/apns/core.rb
View
@@ -21,6 +21,17 @@ def self.send_notification(device_token, message)
sock.close
end
+ def self.send_notifications(notifications)
+ sock, ssl = self.open_connection
+
+ notifications.each do |n|
+ ssl.write(n.packaged_notification)
+ end
+
+ ssl.close
+ sock.close
+ end
+
protected
def self.packaged_notification(device_token, message)
34 lib/apns/notification.rb
View
@@ -2,8 +2,38 @@ module APNS
class Notification
attr_accessor :device_token, :alert, :badge, :sound, :other
- def send_notification
- APNS.send_notification(self.device_token, )
+ def initialize(device_token, message)
+ self.device_token = device_token
+ if message.is_a?(Hash)
+ self.alert = message[:alert]
+ self.badge = message[:badge]
+ self.sound = message[:sound]
+ self.other = message[:other]
+ elsif message.is_a?(String)
+ self.alert = message
+ else
+ raise "Notification needs to have either a hash or string"
+ end
end
+
+ def packaged_notification
+ pt = self.packaged_token
+ pm = self.packaged_message
+ [0, 0, 32, pt, 0, pm.size, pm].pack("ccca*cca*")
+ end
+
+ def packaged_token
+ [device_token.gsub(/[\s|<|>]/,'')].pack('H*')
+ end
+
+ def packaged_message
+ aps = {'aps'=> {} }
+ aps['aps']['alert'] = self.alert if self.alert
+ aps['aps']['badge'] = self.badge if self.badge
+ aps['aps']['sound'] = self.sound if self.sound
+ aps.merge!(self.other) if self.other
+ aps.to_json
+ end
+
end
end
44 spec/apns/notification_spec.rb
View
@@ -0,0 +1,44 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe APNS::Notification do
+
+ it "should take a string as the message" do
+ n = APNS::Notification.new('device_token', 'Hello')
+ n.alert.should == 'Hello'
+ end
+
+ it "should take a hash as the message" do
+ n = APNS::Notification.new('device_token', {:alert => 'Hello iPhone', :badge => 3})
+ n.alert.should == "Hello iPhone"
+ n.badge.should == 3
+ end
+
+ describe '#packaged_message' do
+
+ it "should return JSON with notification information" do
+ n = APNS::Notification.new('device_token', {:alert => 'Hello iPhone', :badge => 3, :sound => 'awesome.caf'})
+ n.packaged_message.should == "{\"aps\":{\"badge\":3,\"sound\":\"awesome.caf\",\"alert\":\"Hello iPhone\"}}"
+ end
+
+ it "should not include keys that are empty in the JSON" do
+ n = APNS::Notification.new('device_token', {:badge => 3})
+ n.packaged_message.should == "{\"aps\":{\"badge\":3}}"
+ end
+
+ end
+
+ describe '#package_token' do
+ it "should package the token" do
+ n = APNS::Notification.new('<5b51030d d5bad758 fbad5004 bad35c31 e4e0f550 f77f20d4 f737bf8d 3d5524c6>', 'a')
+ Base64.encode64(n.packaged_token).should == "W1EDDdW611j7rVAEutNcMeTg9VD3fyDU9ze/jT1VJMY=\n"
+ end
+ end
+
+ describe '#packaged_notification' do
+ it "should package the token" do
+ n = APNS::Notification.new('device_token', {:alert => 'Hello iPhone', :badge => 3, :sound => 'awesome.caf'})
+ Base64.encode64(n.packaged_notification).should == "AAAg3vLO/YTnAEB7ImFwcyI6eyJiYWRnZSI6Mywic291bmQiOiJhd2Vzb21l\nLmNhZiIsImFsZXJ0IjoiSGVsbG8gaVBob25lIn19\n"
+ end
+ end
+
+end
5 spec/spec_helper.rb
View
@@ -0,0 +1,5 @@
+require 'rubygems'
+gem 'rspec', '>= 1.2.8'
+require 'spec'
+require File.join(File.dirname(__FILE__), '..', 'lib', 'apns')
+require 'base64'
Please sign in to comment.
Something went wrong with that request. Please try again.