houston 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 665f646fd8d10f128f8b408a5723bdfa846a6e49
4
+ data.tar.gz: a7d075a67f504cbdfcbebe585d21e8e26d770d9e
5
+ SHA512:
6
+ metadata.gz: 00c7bc4612f323d159411ce835a21e5c28acf85395c685bab5b7ad87e9d1a7d0378d02e2c4980e29bbb10bfe32c4ad844d04447c37edb18954ff36bafa58ab87
7
+ data.tar.gz: 4b4be23b6122e002f391e5d4577cae6897f519696008c5c926e1e39de917055bba0e6740cf53533b967cd14da8581076e2f4d65ab5e89ff84681f4fece50e530
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
@@ -1,17 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- houston (0.1.1)
5
- commander (~> 4.1.2)
6
- json (~> 1.7.3)
4
+ houston (0.2.1)
5
+ commander (~> 4.1)
6
+ json
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
- commander (4.1.2)
11
+ commander (4.1.3)
12
12
  highline (~> 1.6.11)
13
- highline (1.6.15)
14
- json (1.7.5)
13
+ highline (1.6.18)
14
+ json (1.7.7)
15
15
  rake (0.9.2.2)
16
16
  rspec (0.6.4)
17
17
 
@@ -20,5 +20,5 @@ PLATFORMS
20
20
 
21
21
  DEPENDENCIES
22
22
  houston!
23
- rake (~> 0.9.2)
24
- rspec (~> 0.6.1)
23
+ rake (~> 0.9)
24
+ rspec (~> 0.6)
data/README.md CHANGED
@@ -1,23 +1,23 @@
1
1
  # Houston
2
2
  **Apple Push Notifications. No Dirigible Required**
3
3
 
4
- > Houston, We Have Liftoff!
5
-
6
4
  Push Notifications don't have to be difficult.
7
5
 
8
6
  Houston is a simple gem for sending Apple Push Notifications. Pass your credentials, construct your message, and send it.
9
7
 
10
8
  In a production application, you will probably want to schedule or queue notifications into a background job. Whether you're using [queue_classic](https://github.com/ryandotsmith/queue_classic), [resque](https://github.com/defunkt/resque), or rolling you own infrastructure, integrating Houston couldn't be simpler.
11
9
 
12
- Another caveat is that Houston doesn't manage device tokens for you. Infrastructures can vary dramatically for these kinds of things, so being agnostic and not forcing any conventions here is more a feature than a bug, perhaps. Treat it the same way as you would an e-mail address, associating one or many for each user account.
10
+ Another caveat is that Houston doesn't manage device tokens for you. For that, you should check out [Helios](http://helios.io)
11
+
12
+ > Houston's is named for [Houston, TX](http://en.wikipedia.org/wiki/Houston), the metonymical home of [NASA's Johnson Space Center](http://en.wikipedia.org/wiki/Lyndon_B._Johnson_Space_Center), as in _Houston, We Have Liftoff!_.
13
+
14
+ > It's part of a series of world-class command-line utilities for iOS development, which includes [Cupertino](https://github.com/mattt/cupertino) (Apple Dev Center management), [Shenzhen](https://github.com/mattt/shenzhen) (Building & Distribution), [Venice](https://github.com/mattt/venice) (In-App Purchase Receipt Verification), and [Dubai](https://github.com/mattt/dubai) (Passbook pass generation).
13
15
 
14
- _That said, a simple web service adapter, similar to [Rack::CoreData](https://github.com/mattt/rack-core-data) is in the cards._
16
+ > This project is also part of a series of open source libraries covering the mission-critical aspects of an iOS app's infrastructure. Be sure to check out its sister projects: [GroundControl](https://github.com/mattt/GroundControl), [SkyLab](https://github.com/mattt/SkyLab), [houston](https://github.com/mattt/houston), and [Orbiter](https://github.com/mattt/Orbiter).
15
17
 
16
18
  ## Installation
17
19
 
18
- ```
19
- $ gem install houston
20
- ```
20
+ $ gem install houston
21
21
 
22
22
  ## Usage
23
23
 
@@ -34,22 +34,38 @@ token = "<ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b596
34
34
  notification = Houston::Notification.new(device: token)
35
35
  notification.alert = "Hello, World!"
36
36
 
37
- # Notifications can also change the badge count, have a custom sound, or pass along arbitrary data.
37
+ # Notifications can also change the badge count, have a custom sound, indicate available Newsstand content, or pass along arbitrary data.
38
38
  notification.badge = 57
39
39
  notification.sound = "sosumi.aiff"
40
+ notification.content_available = true
40
41
  notification.custom_data = {foo: "bar"}
41
42
 
42
43
  # And... sent! That's all it takes.
43
44
  APN.push(notification)
44
45
  ```
45
46
 
47
+ ### Persistent Connections
48
+
49
+ If you want to manage your own persistent connection to Apple push services, such as for background workers, here's how to do it:
50
+
51
+ ```ruby
52
+ certificate = File.read("/path/to/apple_push_notification.pem")
53
+ passphrase = "..."
54
+ connection = Houston::Connection.new(APPLE_DEVELOPMENT_GATEWAY_URI, certificate, passphrase)
55
+ connection.open
56
+
57
+ notification = Houston::Notification.new(device: token)
58
+ notification.alert = "Hello, World!"
59
+ connection.write(notification.message)
60
+
61
+ connection.close
62
+ ```
63
+
46
64
  ## Command Line Tool
47
65
 
48
66
  Houston also comes with the `apn` binary, which provides a convenient way to test notifications from the command line.
49
67
 
50
- ```
51
- $ apn push "<token>" -c /path/to/apple_push_notification.pem -m "Hello from the command line!"
52
- ```
68
+ $ apn push "<token>" -c /path/to/apple_push_notification.pem -m "Hello from the command line!"
53
69
 
54
70
  ## Enabling Push Notifications on iOS
55
71
 
@@ -62,8 +78,8 @@ $ apn push "<token>" -c /path/to/apple_push_notification.pem -m "Hello from the
62
78
  [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
63
79
  }
64
80
 
65
- - (void)application:(UIApplication *)application
66
- didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
81
+ - (void)application:(UIApplication *)application
82
+ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
67
83
  {
68
84
  NSLog(@"application:didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken);
69
85
 
@@ -71,7 +87,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
71
87
  }
72
88
 
73
89
  - (void)application:(UIApplication *)application
74
- didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
90
+ didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
75
91
  {
76
92
  NSLog(@"Error: %@", error);
77
93
  }
@@ -84,15 +100,13 @@ didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
84
100
  Once you have the certificate from Apple for your application, export your key
85
101
  and the apple certificate as p12 files. Here is a quick walkthrough on how to do this:
86
102
 
87
- 1. Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
88
- 2. Right click and choose `Export 2 items…`.
103
+ 1. Click the disclosure arrow next to your certificate in Keychain Access and select the certificate and the key.
104
+ 2. Right click and choose `Export 2 items…`.
89
105
  3. Choose the p12 format from the drop down and name it `cert.p12`.
90
106
 
91
107
  Now covert the p12 file to a pem file:
92
108
 
93
- ```
94
- $ openssl pkcs12 -in cert.p12 -out apple_push_notification.pem -nodes -clcerts
95
- ```
109
+ $ openssl pkcs12 -in cert.p12 -out apple_push_notification.pem -nodes -clcerts
96
110
 
97
111
  ## Contact
98
112
 
data/Rakefile CHANGED
@@ -7,5 +7,4 @@ task :build => "#{gemspec.full_name}.gem"
7
7
 
8
8
  file "#{gemspec.full_name}.gem" => gemspec.files + ["houston.gemspec"] do
9
9
  system "gem build houston.gemspec"
10
- system "gem install houston-#{Houston::VERSION}.gem"
11
10
  end
data/bin/apn CHANGED
@@ -25,10 +25,13 @@ command :push do |c|
25
25
  c.option '-m', '--alert ALERT', 'Body of the alert to send in the push notification'
26
26
  c.option '-b', '--badge NUMBER', 'Badge number to set with the push notification'
27
27
  c.option '-s', '--sound SOUND', 'Sound to play with the notification'
28
- c.option '-e', '--environment [production|development]', 'Environment to send push notification (defaults to development)'
28
+ c.option '-n', '--[no]-newsstand', 'Indicates content available for Newsstand'
29
+ c.option '-d', '--data KEY=VALUE', Array, 'Passes custom data to payload (as comma-delimited "key=value" declarations)'
30
+ c.option '-P', '--payload PAYLOAD', 'JSON payload for notifications'
31
+ c.option '-e', '--environment ENV', [:production, :development], 'Environment to send push notification (production or development (default))'
29
32
  c.option '-c', '--certificate CERTIFICATE', 'Path to certificate (.pem) file'
30
33
  c.option '-p', '--[no]-passphrase', 'Prompt for a certificate passphrase'
31
-
34
+
32
35
  c.action do |args, options|
33
36
  say_error "One or more device tokens required" and abort if args.empty?
34
37
 
@@ -44,21 +47,38 @@ command :push do |c|
44
47
  @alert = options.alert
45
48
  @badge = options.badge.nil? ? nil : options.badge.to_i
46
49
  @sound = options.sound
50
+ @content_available = options.newsstand
51
+
52
+ if options.payload
53
+ begin
54
+ @data = JSON.parse(options.payload)
55
+ rescue => message
56
+ say_error "Exception parsing JSON payload: #{message}" and abort
57
+ end
58
+ elsif options.data
59
+ begin
60
+ @data = Hash[options.data.collect{|data| data.split(/\=/)}]
61
+ rescue => message
62
+ say_error "Exception parsing JSON payload: #{message}" and abort
63
+ end
64
+ end
47
65
 
48
- unless @alert or @badge
66
+ unless @alert or @badge or @newsstand or @data
49
67
  placeholder = "Enter your alert message"
50
68
  @alert = ask_editor placeholder
51
- say_error "Alert message or badge required" and abort if @alert.nil? or @alert == placeholder
69
+ say_error "Payload contents required" and abort if @alert.nil? or @alert == placeholder
52
70
  end
53
71
 
54
- notifications = []
72
+ @notifications = []
55
73
  args.each do |token|
56
- notification = Houston::Notification.new(device: token)
57
- notification.alert = @alert
58
- notification.badge = @badge
59
- notification.sound = @sound
60
-
61
- notifications << notification
74
+ notification = Houston::Notification.new(@data || {})
75
+ notification.device = token
76
+ notification.alert = @alert if @alert
77
+ notification.badge = @badge if @badge
78
+ notification.sound = @sound if @sound
79
+ notification.content_available = @newsstand if @newsstand
80
+
81
+ @notifications << notification
62
82
  end
63
83
 
64
84
  client = @environment == :production ? Houston::Client.production : Houston::Client.development
@@ -66,9 +86,9 @@ command :push do |c|
66
86
  client.passphrase = @passphrase
67
87
 
68
88
  begin
69
- client.push(*notifications)
70
- rescue => e
71
- say_error "Exception sending notification: #{e}" and abort
89
+ client.push(*@notifications)
90
+ rescue => message
91
+ say_error "Exception sending notification: #{message}" and abort
72
92
  end
73
93
 
74
94
  say_ok "Push notifications successfully sent"
@@ -6,17 +6,18 @@ Gem::Specification.new do |s|
6
6
  s.name = "houston"
7
7
  s.authors = ["Mattt Thompson"]
8
8
  s.email = "m@mattt.me"
9
+ s.license = "MIT"
9
10
  s.homepage = "http://github.com/mattt/houston"
10
11
  s.version = Houston::VERSION
11
12
  s.platform = Gem::Platform::RUBY
12
13
  s.summary = "Send Apple Push Notifications"
13
14
  s.description = "Houston is a simple gem for sending Apple Push Notifications. Pass your credentials, construct your message, and send it."
14
15
 
15
- s.add_dependency "commander", "~> 4.1.2"
16
- s.add_dependency "json", "~> 1.7.3"
16
+ s.add_dependency "commander", "~> 4.1"
17
+ s.add_dependency "json"
17
18
 
18
- s.add_development_dependency "rspec", "~> 0.6.1"
19
- s.add_development_dependency "rake", "~> 0.9.2"
19
+ s.add_development_dependency "rspec", "~> 0.6"
20
+ s.add_development_dependency "rake", "~> 0.9"
20
21
 
21
22
  s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
22
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,5 +1,5 @@
1
1
  module Houston
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
4
4
 
5
5
  require 'houston/client'
@@ -3,11 +3,27 @@ module Houston
3
3
  APPLE_PRODUCTION_FEEDBACK_URI = "apn://feedback.push.apple.com:2196"
4
4
 
5
5
  APPLE_DEVELOPMENT_GATEWAY_URI = "apn://gateway.sandbox.push.apple.com:2195"
6
- APPLE_DEVELOPMENT_FEEDBACK_URI = "apn://feedback.push.apple.com:2196"
6
+ APPLE_DEVELOPMENT_FEEDBACK_URI = "apn://feedback.sandbox.push.apple.com:2196"
7
7
 
8
8
  class Client
9
9
  attr_accessor :gateway_uri, :feedback_uri, :certificate, :passphrase
10
10
 
11
+ class << self
12
+ def development
13
+ client = self.new
14
+ client.gateway_uri = APPLE_DEVELOPMENT_GATEWAY_URI
15
+ client.feedback_uri = APPLE_DEVELOPMENT_FEEDBACK_URI
16
+ client
17
+ end
18
+
19
+ def production
20
+ client = self.new
21
+ client.gateway_uri = APPLE_PRODUCTION_GATEWAY_URI
22
+ client.feedback_uri = APPLE_PRODUCTION_FEEDBACK_URI
23
+ client
24
+ end
25
+ end
26
+
11
27
  def initialize
12
28
  @gateway_uri = ENV['APN_GATEWAY_URI']
13
29
  @feedback_uri = ENV['APN_FEEDBACK_URI']
@@ -15,24 +31,10 @@ module Houston
15
31
  @passphrase = ENV['APN_CERTIFICATE_PASSPHRASE']
16
32
  end
17
33
 
18
- def self.development
19
- client = self.new
20
- client.gateway_uri = APPLE_DEVELOPMENT_GATEWAY_URI
21
- client.feedback_uri = APPLE_DEVELOPMENT_FEEDBACK_URI
22
- client
23
- end
24
-
25
- def self.production
26
- client = self.new
27
- client.gateway_uri = APPLE_PRODUCTION_GATEWAY_URI
28
- client.feedback_uri = APPLE_PRODUCTION_FEEDBACK_URI
29
- client
30
- end
31
-
32
34
  def push(*notifications)
33
35
  return if notifications.empty?
34
36
 
35
- Connection.open(connection_options_for_endpoint(:gateway)) do |connection, socket|
37
+ Connection.open(@gateway_uri, @certificate, @passphrase) do |connection|
36
38
  notifications.flatten.each do |notification|
37
39
  next unless notification.kind_of?(Notification)
38
40
  next if notification.sent?
@@ -46,9 +48,9 @@ module Houston
46
48
  def devices
47
49
  devices = []
48
50
 
49
- Connection.open(connection_options_for_endpoint(:feedback)) do |connection, socket|
51
+ Connection.open(@feedback_uri, @certificate, @passphrase) do |connection|
50
52
  while line = connection.read(38)
51
- feedback = line.unpack('N1n1H140')
53
+ feedback = line.unpack('N1n1H140')
52
54
  token = feedback[2].scan(/.{0,8}/).join(' ').strip
53
55
  devices << token if token
54
56
  end
@@ -56,23 +58,5 @@ module Houston
56
58
 
57
59
  devices
58
60
  end
59
-
60
- private
61
-
62
- def connection_options_for_endpoint(endpoint = :gateway)
63
- uri = case endpoint
64
- when :gateway then URI(@gateway_uri)
65
- when :feedback then URI(@feedback_uri)
66
- else
67
- raise ArgumentError
68
- end
69
-
70
- {
71
- certificate: @certificate,
72
- passphrase: @passphrase,
73
- host: uri.host,
74
- port: uri.port
75
- }
76
- end
77
61
  end
78
62
  end
@@ -1,32 +1,65 @@
1
1
  require 'uri'
2
2
  require 'socket'
3
3
  require 'openssl'
4
+ require 'forwardable'
4
5
 
5
6
  module Houston
6
7
  class Connection
8
+ extend Forwardable
9
+ def_delegators :@ssl, :read, :write
10
+ def_delegators :@uri, :scheme, :host, :port
11
+
12
+ attr_reader :ssl, :socket, :certificate, :passphrase
13
+
7
14
  class << self
8
- def open(options = {})
15
+ def open(uri, certificate, passphrase)
9
16
  return unless block_given?
10
17
 
11
- [:certificate, :passphrase, :host, :port].each do |option|
12
- raise ArgumentError, "Missing connection parameter: #{option}" unless option
13
- end
14
-
15
- socket = TCPSocket.new(options[:host], options[:port])
18
+ connection = new(uri, certificate, passphrase)
19
+ connection.open
16
20
 
17
- context = OpenSSL::SSL::SSLContext.new
18
- context.key = OpenSSL::PKey::RSA.new(options[:certificate], options[:passphrase])
19
- context.cert = OpenSSL::X509::Certificate.new(options[:certificate])
21
+ yield connection
20
22
 
21
- ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
22
- ssl.sync = true
23
- ssl.connect
24
-
25
- yield ssl, socket
26
-
27
- ssl.close
28
- socket.close
23
+ connection.close
29
24
  end
30
25
  end
26
+
27
+ def initialize(uri, certificate, passphrase)
28
+ @uri = URI(uri)
29
+ @certificate = certificate
30
+ @passphrase = passphrase
31
+ end
32
+
33
+ def open
34
+ return false if open?
35
+
36
+ @socket = TCPSocket.new(@uri.host, @uri.port)
37
+
38
+ context = OpenSSL::SSL::SSLContext.new
39
+ context.key = OpenSSL::PKey::RSA.new(@certificate, @passphrase)
40
+ context.cert = OpenSSL::X509::Certificate.new(@certificate)
41
+
42
+ @ssl = OpenSSL::SSL::SSLSocket.new(@socket, context)
43
+ @ssl.sync = true
44
+ @ssl.connect
45
+ end
46
+
47
+ def open?
48
+ not (@ssl and @socket).nil?
49
+ end
50
+
51
+ def close
52
+ return false if closed?
53
+
54
+ @ssl.close
55
+ @ssl = nil
56
+
57
+ @socket.close
58
+ @socket = nil
59
+ end
60
+
61
+ def closed?
62
+ not open?
63
+ end
31
64
  end
32
65
  end
@@ -2,7 +2,7 @@ require 'json'
2
2
 
3
3
  module Houston
4
4
  class Notification
5
- attr_accessor :device, :alert, :badge, :sound, :custom_data
5
+ attr_accessor :device, :alert, :badge, :sound, :content_available, :custom_data
6
6
  attr_reader :sent_at
7
7
 
8
8
  def initialize(options = {})
@@ -10,6 +10,7 @@ module Houston
10
10
  @alert = options.delete(:alert)
11
11
  @badge = options.delete(:badge)
12
12
  @sound = options.delete(:sound)
13
+ @content_available = options.delete(:content_available)
13
14
 
14
15
  @custom_data = options
15
16
  end
@@ -17,9 +18,10 @@ module Houston
17
18
  def payload
18
19
  json = {}.merge(@custom_data || {})
19
20
  json['aps'] = {}
20
- json['aps']['alert'] = @alert
21
- json['aps']['badge'] = @badge.to_i rescue 0
22
- json['aps']['sound'] = @sound
21
+ json['aps']['alert'] = @alert if @alert
22
+ json['aps']['badge'] = @badge.to_i rescue 0 if @badge
23
+ json['aps']['sound'] = @sound if @sound
24
+ json['aps']['content-available'] = 1 if @content_available
23
25
 
24
26
  json
25
27
  end
metadata CHANGED
@@ -1,80 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: houston
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Mattt Thompson
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-31 00:00:00.000000000 Z
11
+ date: 2013-04-24 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: commander
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 4.1.2
19
+ version: '4.1'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
29
- version: 4.1.2
26
+ version: '4.1'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: json
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - ! '>='
36
32
  - !ruby/object:Gem::Version
37
- version: 1.7.3
33
+ version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - ! '>='
44
39
  - !ruby/object:Gem::Version
45
- version: 1.7.3
40
+ version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
53
- version: 0.6.1
47
+ version: '0.6'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
61
- version: 0.6.1
54
+ version: '0.6'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
69
- version: 0.9.2
61
+ version: '0.9'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
77
- version: 0.9.2
68
+ version: '0.9'
78
69
  description: Houston is a simple gem for sending Apple Push Notifications. Pass your
79
70
  credentials, construct your message, and send it.
80
71
  email: m@mattt.me
@@ -86,7 +77,6 @@ files:
86
77
  - ./apple_push_notification_production.pem
87
78
  - ./Gemfile
88
79
  - ./Gemfile.lock
89
- - ./houston-0.1.0.gem
90
80
  - ./houston.gemspec
91
81
  - ./lib/houston/client.rb
92
82
  - ./lib/houston/connection.rb
@@ -97,33 +87,27 @@ files:
97
87
  - ./README.md
98
88
  - bin/apn
99
89
  homepage: http://github.com/mattt/houston
100
- licenses: []
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
101
93
  post_install_message:
102
94
  rdoc_options: []
103
95
  require_paths:
104
96
  - lib
105
97
  required_ruby_version: !ruby/object:Gem::Requirement
106
- none: false
107
98
  requirements:
108
99
  - - ! '>='
109
100
  - !ruby/object:Gem::Version
110
101
  version: '0'
111
- segments:
112
- - 0
113
- hash: -1059375513586504727
114
102
  required_rubygems_version: !ruby/object:Gem::Requirement
115
- none: false
116
103
  requirements:
117
104
  - - ! '>='
118
105
  - !ruby/object:Gem::Version
119
106
  version: '0'
120
- segments:
121
- - 0
122
- hash: -1059375513586504727
123
107
  requirements: []
124
108
  rubyforge_project:
125
- rubygems_version: 1.8.24
109
+ rubygems_version: 2.0.3
126
110
  signing_key:
127
- specification_version: 3
111
+ specification_version: 4
128
112
  summary: Send Apple Push Notifications
129
113
  test_files: []
Binary file