motion-addressbook 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ .repl_history
2
+ build
3
+ resources/*.nib
4
+ resources/*.momd
5
+ resources/*.storyboardc
6
+
7
+ resources/photos/[1-9]*/*
8
+
9
+ vendor/Pods/Pods.xcodeproj/project.pbxproj
10
+ vendor/Pods/build*
11
+
12
+ .dat*.00*
13
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # need to do this here as alphabetically "bubble-wrap" comes after "address_book" and require fails otherwise
4
+ gem 'bubble-wrap'
5
+
6
+ # Specify your gem's dependencies in motion-addressbook.gemspec
7
+ gemspec
8
+
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ motion-addressbook (0.0.1)
5
+ bubble-wrap
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ bubble-wrap (1.1.1)
11
+ diff-lcs (1.1.3)
12
+ rake (0.9.2.2)
13
+ rspec (2.10.0)
14
+ rspec-core (~> 2.10.0)
15
+ rspec-expectations (~> 2.10.0)
16
+ rspec-mocks (~> 2.10.0)
17
+ rspec-core (2.10.1)
18
+ rspec-expectations (2.10.0)
19
+ diff-lcs (~> 1.1.3)
20
+ rspec-mocks (2.10.1)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ bubble-wrap
27
+ motion-addressbook!
28
+ rake
29
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Alex Rothenberg
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Addressbook for RubyMotion
2
+
3
+ A RubyMotion wrapper around the iOS Address Book framework for RubyMotion apps.
4
+
5
+ Apple's [Address Book Programming Guide for iOS](http://developer.apple.com/library/ios/#DOCUMENTATION/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Introduction.html)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'motion-addressbook'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install motion-addressbook
20
+
21
+ ## Usage
22
+
23
+ ### List all people
24
+
25
+ ```ruby
26
+ AddressBook::Person.all
27
+ # => [#<AddressBook::Person:0x6d55e90 @attributes={:first_name=>"Alex", :last_name=>"Rothenberg", :job_title=>nil, :department=>nil, :organization=>nil} @ab_person=#<__NSCFType:0x6df8bf0>>,
28
+ # #<AddressBook::Person:0x6d550a0 @attributes={:first_name=>"Laurent", :last_name=>"Sansonetti", :job_title=>nil, :department=>nil, :organization=>"HipByte"} @ab_person=#<__NSCFType:0x6df97d0>>]
29
+ ```
30
+
31
+
32
+ ### Create a new Contact and save in Contacts app
33
+
34
+ ```ruby
35
+ alex = AddressBook::Person.new(:first_name => 'Alex', :last_name => 'Rothenberg', :email => 'alex@example.com')
36
+ alex.save
37
+ ```
38
+
39
+ ### Get an existing Contact
40
+
41
+ ```ruby
42
+ alex = AddressBook::Person.new(:first_name => 'Alex', :email => 'alex@example.com')
43
+ alex.last_name
44
+ # => 'Rothenberg'
45
+ ```
46
+
47
+ ### Update existing contact
48
+
49
+ ```ruby
50
+ alex = AddressBook::Person.new(:first_name => 'Alex', :email => 'alex@example.com')
51
+ alex.job_title = 'RubyMotion Developer'
52
+ alex.save
53
+ ```
54
+
55
+ ## Contributing
56
+
57
+ 1. Fork it
58
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
59
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
60
+ 4. Push to the branch (`git push origin my-new-feature`)
61
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ $:.unshift("/Library/RubyMotion/lib")
3
+ require 'motion/project'
4
+ require "bundler/gem_tasks"
5
+ Bundler.setup
6
+ Bundler.require
7
+
8
+ require 'bubble-wrap/test'
@@ -0,0 +1,5 @@
1
+ module Motion
2
+ module Addressbook
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require "motion-addressbook/version"
2
+
3
+ BubbleWrap.require 'motion/address_book.rb'
4
+ BW.require 'motion/address_book/multi_value.rb'
5
+ BW.require 'motion/address_book/person.rb'
@@ -0,0 +1,46 @@
1
+ module AddressBook
2
+ class MultiValue
3
+ attr_reader :multivalueIdentifier, :ab_multi_values
4
+
5
+ def initialize(ab_multi_values=nil)
6
+ @ab_multi_values = ab_multi_values ? ABMultiValueCreateMutableCopy(ab_multi_values) : ABMultiValueCreateMutable(KABMultiStringPropertyType)
7
+ # @ab_multi_values = ABMultiValueCreateMutable(KABMultiStringPropertyType)
8
+ end
9
+
10
+ def set(ab_label, value)
11
+ return if values.include? value #temp because blank? not working
12
+ if blank?(ab_label)
13
+ ABMultiValueAddValueAndLabel(@ab_multi_values, value, ab_label, multivalueIdentifier) unless value.nil?
14
+ else
15
+ # untested!!!
16
+ ABMultiValueReplaceValueAtIndex(@ab_multi_values, value, index_for(ab_label))
17
+ end
18
+ end
19
+
20
+ def set_many(new_values)
21
+ new_values.each do |ab_label, value|
22
+ set(ab_label, value)
23
+ end
24
+ end
25
+
26
+ def values
27
+ ABMultiValueCopyArrayOfAllValues(@ab_multi_values) || []
28
+ end
29
+
30
+ def include? value
31
+ return false if values.nil?
32
+ values.include? value
33
+ end
34
+
35
+ private
36
+ def blank?(ab_label)
37
+ index_for(ab_label) == -1
38
+ end
39
+
40
+ def index_for(ab_label)
41
+ return -1 # Keep getting this error :( <ArgumentError: invalid value for Integer: "_$!<Work>!$_">
42
+ # ABMultiValueGetIndexForIdentifier(@ab_multi_values, ab_label)
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,153 @@
1
+ module AddressBook
2
+ class Person
3
+ attr_reader :attributes, :error, :ab_person
4
+
5
+ def initialize(attributes, ab_person = nil)
6
+ @attributes = attributes
7
+ load_ab_person(ab_person)
8
+ end
9
+
10
+ def self.all
11
+ address_book = ABAddressBookCreate()
12
+ ABAddressBookCopyArrayOfAllPeople(address_book).map do |ab_person|
13
+ new({}, ab_person)
14
+ end
15
+ end
16
+
17
+ def self.create(attributes)
18
+ person = new(attributes)
19
+ person.save
20
+ person
21
+ end
22
+
23
+ def save
24
+ ABAddressBookAddRecord(address_book, ab_person, error)
25
+ ABAddressBookSave(address_book, error )
26
+ @address_book = nil #force refresh
27
+ end
28
+
29
+ def attribute_map
30
+ { :first_name => KABPersonFirstNameProperty,
31
+ :last_name => KABPersonLastNameProperty,
32
+ :job_title => KABPersonJobTitleProperty,
33
+ :department => KABPersonDepartmentProperty,
34
+ :organization => KABPersonOrganizationProperty
35
+ }
36
+ end
37
+
38
+ def method_missing(name, *args)
39
+ name.to_s =~ /^(\w*)(=?)$/
40
+ attribute_name = $1.to_sym unless $1.nil?
41
+ if attribute_map.include? attribute_name
42
+ if $2 == '='
43
+ set_field(attribute_map[attribute_name], args.first)
44
+ attributes[attribute_name] = args.first
45
+ else
46
+ attributes[attribute_name] ||= get_field(attribute_map[attribute_name])
47
+ end
48
+ else
49
+ super
50
+ end
51
+ end
52
+
53
+ def photo
54
+ ABPersonCopyImageData(ab_person)
55
+ end
56
+
57
+ def photo=(photo_data)
58
+ ABPersonSetImageData(ab_person, photo_data, error)
59
+ end
60
+
61
+
62
+ def phone_numbers
63
+ get_multi_field(KABPersonPhoneProperty)
64
+ end
65
+
66
+ def phone_number_values
67
+ phone_numbers.values
68
+ end
69
+
70
+ def emails
71
+ get_multi_field(KABPersonEmailProperty )
72
+ end
73
+
74
+ def email_values
75
+ emails.values
76
+ end
77
+
78
+ # private
79
+
80
+ def load_ab_person(ab_person = nil)
81
+ @ab_person = ab_person || find_or_new
82
+ set_field(KABPersonFirstNameProperty, attributes[:first_name ]) unless attributes[:first_name ].nil?
83
+ set_field(KABPersonLastNameProperty, attributes[:last_name ]) unless attributes[:last_name ].nil?
84
+ set_field(KABPersonJobTitleProperty, attributes[:job_title ]) unless attributes[:job_title ].nil?
85
+ set_field(KABPersonDepartmentProperty, attributes[:department ]) unless attributes[:department ].nil?
86
+ set_field(KABPersonOrganizationProperty, attributes[:organization]) unless attributes[:organization].nil?
87
+ set_multi_field(KABPersonPhoneProperty, KABPersonPhoneMobileLabel => attributes[:mobile_phone], KABWorkLabel => attributes[:office_phone])
88
+ set_multi_field(KABPersonEmailProperty, KABWorkLabel => attributes[:email])
89
+ end
90
+
91
+ def set_field(field, value)
92
+ ABRecordSetValue(ab_person, field, value, error)
93
+ end
94
+ def get_field(field)
95
+ ABRecordCopyValue(ab_person, field)
96
+ end
97
+
98
+ def set_multi_field(field, values)
99
+ multi_field = MultiValue.new(ABRecordCopyValue(ab_person, field))
100
+ multi_field.set_many(values)
101
+ ABRecordSetValue(ab_person, field, multi_field.ab_multi_values, error )
102
+ end
103
+ def get_multi_field(field)
104
+ MultiValue.new(ABRecordCopyValue(ab_person, field))
105
+ end
106
+
107
+ def find_or_new
108
+ if new_record?
109
+ ab_person = ABPersonCreate()
110
+ ABAddressBookAddRecord(address_book, ab_person, error )
111
+ ab_person
112
+ else
113
+ existing_record
114
+ end
115
+ end
116
+
117
+ def existing_records
118
+ potential_matches = ABAddressBookCopyPeopleWithName(address_book, attributes[:first_name])
119
+ potential_matches.select do |record|
120
+ multi_field = MultiValue.new ABRecordCopyValue(record, KABPersonEmailProperty)
121
+ multi_field.include? attributes[:email]
122
+ end
123
+ end
124
+
125
+ def exists?
126
+ !new_record?
127
+ end
128
+ def new_record?
129
+ existing_record.nil?
130
+ end
131
+ def existing_record
132
+ # what if there are more than one match? email should be unique but ...
133
+ existing_records.first
134
+ end
135
+
136
+ def address_book
137
+ @address_book ||= ABAddressBookCreate()
138
+ end
139
+
140
+ def inspect
141
+ # ensure all attributes loaded
142
+ attribute_map.keys.each do |attribute|
143
+ self.send(attribute)
144
+ end
145
+
146
+ super
147
+ end
148
+
149
+ # def define_some_constants
150
+ # [KABWorkLabel, KABOtherLabel, KABHomeLabel]
151
+ # end
152
+ end
153
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/motion-addressbook/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Alex Rothenberg"]
6
+ gem.email = ["alex@alexrothenberg.com"]
7
+ gem.description = %q{A RubyMotion wrapper around the iOS Address Book framework}
8
+ gem.summary = %q{A RubyMotion wrapper around the iOS Address Book framework}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "motion-addressbook"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Motion::Addressbook::VERSION
17
+
18
+ gem.add_dependency 'bubble-wrap'
19
+ gem.add_development_dependency 'rake'
20
+ gem.add_development_dependency 'rspec'
21
+ end
@@ -0,0 +1,66 @@
1
+ describe AddressBook::MultiValue do
2
+ describe 'new field' do
3
+ before do
4
+ @multi_value = AddressBook::MultiValue.new
5
+ end
6
+
7
+ describe 'setting one value' do
8
+ before { @multi_value.set(KABWorkLabel, 'alex@work.com') }
9
+ it 'gives access to the values' do
10
+ @multi_value.values.should == ['alex@work.com']
11
+ end
12
+ it 'should know if the value exists' do
13
+ @multi_value.include?('alex@work.com').should.be.true
14
+ end
15
+
16
+ it 'should know if the value exists' do
17
+ @multi_value.include?('not@there.com').should.be.false
18
+ end
19
+ end
20
+ describe 'setting many values' do
21
+ before { @multi_value.set_many(KABWorkLabel => 'alex@work.com', KABHomeLabel => 'alex@home.com') }
22
+ it 'gives access to the values' do
23
+ @multi_value.values.should == ['alex@work.com', 'alex@home.com']
24
+ end
25
+ it 'should know both values exist' do
26
+ @multi_value.include?('alex@work.com').should.be.true
27
+ @multi_value.include?('alex@home.com').should.be.true
28
+ end
29
+
30
+ it 'should know if the value exists' do
31
+ @multi_value.include?('not@there.com').should.be.false
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'existing field' do
37
+ before do
38
+ old_multi_value = AddressBook::MultiValue.new
39
+ old_multi_value.set(KABWorkLabel, 'alex@work.com')
40
+
41
+ @multi_value = AddressBook::MultiValue.new old_multi_value.ab_multi_values
42
+ end
43
+
44
+ it 'should have the value' do
45
+ @multi_value.values.should == ['alex@work.com']
46
+ end
47
+
48
+ it 'should be able to update the value' do
49
+ @multi_value.set(KABWorkLabel, 'alex@new_work.com')
50
+ puts '******PENDING****** Waiting for RubyMotion ABMultiValueGetIndexForIdentifier fix'
51
+ @multi_value.values.should == ['alex@work.com', 'alex@new_work.com'] # ['alex@new_work.com']
52
+ end
53
+
54
+ it 'should ignore when updating an existing value to the same value' do
55
+ @multi_value.set(KABWorkLabel, 'alex@work.com')
56
+ @multi_value.values.should == ['alex@work.com']
57
+ end
58
+
59
+ it 'should be able to add an additional value' do
60
+ @multi_value.set(KABHomeLabel, 'alex@home.com')
61
+ @multi_value.values.should == ['alex@work.com', 'alex@home.com']
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,137 @@
1
+ describe AddressBook::Person do
2
+ describe '.all' do
3
+ before do
4
+ @person = AddressBook::Person.create({:first_name => 'Alex', :last_name=>'Rothenberg'})
5
+ end
6
+ it 'should have the person we created' do
7
+ all_names = AddressBook::Person.all.map do |person|
8
+ [person.first_name, person.last_name]
9
+ end
10
+ all_names.should.include? ['Alex', 'Rothenberg']
11
+ end
12
+
13
+ it 'should get bigger when we create another' do
14
+ initial_people_count = AddressBook::Person.all.size
15
+ @person = AddressBook::Person.create({:first_name => 'Alex2', :last_name=>'Rothenberg2'})
16
+ AddressBook::Person.all.size.should == (initial_people_count + 1)
17
+ end
18
+ end
19
+
20
+ describe 'save' do
21
+ before do
22
+ unique_email = "alex_#{Time.now.to_i}@example.com"
23
+ @attributes = {:first_name=>'Alex', :last_name=>'Testy',
24
+ :job_title => 'Developer', :department => 'Development', :organization => 'The Company',
25
+ :mobile_phone => '123 456 7890', :office_phone => '987 654 3210',
26
+ :email => unique_email
27
+ }
28
+ end
29
+
30
+ describe 'a new person' do
31
+ before do
32
+ @ab_person = AddressBook::Person.new(@attributes)
33
+ end
34
+
35
+ it 'should not be existing' do
36
+ @ab_person.should.be.new_record
37
+ @ab_person.should.not.be.exists
38
+ end
39
+
40
+ it 'should be able to get each of the single value fields' do
41
+ @ab_person.first_name.should.equal @attributes[:first_name ]
42
+ @ab_person.last_name.should.equal @attributes[:last_name ]
43
+ @ab_person.job_title.should.equal @attributes[:job_title ]
44
+ @ab_person.department.should.equal @attributes[:department ]
45
+ @ab_person.organization.should.equal @attributes[:organization]
46
+ end
47
+
48
+ describe 'setting each field' do
49
+ it 'should be able to set the first name' do
50
+ @ab_person.first_name = 'new first name'
51
+ @ab_person.first_name.should.equal 'new first name'
52
+ end
53
+ it 'should be able to set the last name' do
54
+ @ab_person.last_name = 'new last name'
55
+ @ab_person.last_name.should.equal 'new last name'
56
+ end
57
+ it 'should be able to set the job title' do
58
+ @ab_person.job_title = 'new job title'
59
+ @ab_person.job_title.should.equal 'new job title'
60
+ end
61
+ it 'should be able to set the department' do
62
+ @ab_person.department = 'new department'
63
+ @ab_person.department.should.equal 'new department'
64
+ end
65
+ it 'should be able to set the organization' do
66
+ @ab_person.organization = 'new organization'
67
+ @ab_person.organization.should.equal 'new organization'
68
+ end
69
+
70
+ it 'should be able to set the phot' do
71
+ image = CIImage.emptyImage
72
+ data = UIImagePNGRepresentation(UIImage.imageWithCIImage image)
73
+ @ab_person.photo = data
74
+ UIImagePNGRepresentation(@ab_person.photo).should.equal data
75
+ end
76
+
77
+ end
78
+
79
+ it 'should be able to get the phone numbers' do
80
+ @ab_person.phone_number_values.should.equal [@attributes[:mobile_phone], @attributes[:office_phone] ]
81
+ end
82
+
83
+ it 'should be able to get the emails' do
84
+ @ab_person.email_values.should.equal [@attributes[:email] ]
85
+ end
86
+ describe 'saving' do
87
+ before do
88
+ @ab_person.save
89
+ end
90
+ it 'after saving it should not be existing' do
91
+ @ab_person.should.not.be.new_record
92
+ @ab_person.should.be.exists
93
+ end
94
+ end
95
+ end
96
+
97
+ describe 'updating an existing person' do
98
+ before do
99
+ AddressBook::Person.new(@attributes).save
100
+ @attributes[:job_title ] = 'i got promoted'
101
+ @attributes[:office_phone] = '111 222 3333'
102
+ # @attributes[:department ] = nil
103
+ @ab_person = AddressBook::Person.new(@attributes)
104
+ end
105
+
106
+ it 'should know it is not new' do
107
+ @ab_person.should.not.be.new_record
108
+ @ab_person.should.be.exists
109
+ @ab_person.department.should == 'Development'
110
+ end
111
+
112
+ describe 'updating' do
113
+ before do
114
+ @ab_person.save
115
+ @new_ab_person = AddressBook::Person.new :first_name=>@attributes[:first_name], :email => @attributes[:email]
116
+ end
117
+ it 'should be able to get each of the single value fields' do
118
+ @new_ab_person.first_name.should.equal @attributes[:first_name ]
119
+ @new_ab_person.last_name.should.equal @attributes[:last_name ]
120
+ @new_ab_person.job_title.should.equal @attributes[:job_title ]
121
+ @new_ab_person.department.should.equal @attributes[:department ]
122
+ @new_ab_person.organization.should.equal @attributes[:organization]
123
+ end
124
+ it 'should be able to get the phone numbers (we never delete and just add - not sure if this is "right")' do
125
+ @new_ab_person.phone_number_values.should.equal [@attributes[:mobile_phone], '987 654 3210', @attributes[:office_phone]]
126
+ end
127
+
128
+ it 'should be able to get the emails' do
129
+ @new_ab_person.email_values.should.equal [@attributes[:email] ]
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-addressbook
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Rothenberg
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bubble-wrap
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A RubyMotion wrapper around the iOS Address Book framework
63
+ email:
64
+ - alex@alexrothenberg.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE
73
+ - README.md
74
+ - Rakefile
75
+ - lib/motion-addressbook.rb
76
+ - lib/motion-addressbook/version.rb
77
+ - motion-addressbook.gemspec
78
+ - motion/address_book/multi_value.rb
79
+ - motion/address_book/person.rb
80
+ - spec/address_book/multi_value_spec.rb
81
+ - spec/address_book/person_spec.rb
82
+ homepage: ''
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ segments:
95
+ - 0
96
+ hash: -4038011897139577156
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ segments:
104
+ - 0
105
+ hash: -4038011897139577156
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.24
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: A RubyMotion wrapper around the iOS Address Book framework
112
+ test_files:
113
+ - spec/address_book/multi_value_spec.rb
114
+ - spec/address_book/person_spec.rb