motion-addressbook 1.6.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a59a907d0d36c0d0686a4b6455df055b334c54d
4
- data.tar.gz: f5e42916903f43b8c06b80d759d1f31771434db8
3
+ metadata.gz: 062e2ed0b9018682964f43fcaf0711c7c9147cc6
4
+ data.tar.gz: ac3392b93c651c531dd6f506ffc9e6d5c1f272fb
5
5
  SHA512:
6
- metadata.gz: 3bb1564f7250614c5d5c9e1413b514661860ff89460fa11f1aa1fddbb11f815ee3d967c95d971ac9f4a7bb396d35f0be43483cf0c9411186eb2762b6836c122a
7
- data.tar.gz: 13cb80adb5b232de7e6d2aa355b1754252d06d64c0d74cff0a53bde0ca9d7385b8a1853e5085921d3f7a67da234af25dd022a5352268c7c3d4e362cdab5b5959
6
+ metadata.gz: fe803b3bf9eeae54d44b33ce8bd8f1c9016ca5ce62ba36c47a15da3b2fa0a09cca2141e7314c10b756a0a42afa0fbd9b64df8cf5b3b523963858de94721ef85a
7
+ data.tar.gz: 0e3dd574fd3eb184f6408843613315816095cb69f4653465d056f29d0c8ae2d128c03eb782fbfe516d7eb9b4f616fc270971927914d61df16e6b942d362980ec
data/README.md CHANGED
@@ -175,6 +175,15 @@ alex.job_title = 'RubyMotion Developer'
175
175
  alex.save
176
176
  ```
177
177
 
178
+ Or to alter all the attributes at once (preserve the record identifier
179
+ but change some or all of the values):
180
+
181
+ ```ruby
182
+ alex = AddressBook::Person.find_by_email('alex@example.com')
183
+ alex.replace({:first_name=>"Alex", :last_name=>"Rider", ...})
184
+ alex.save
185
+ ```
186
+
178
187
  ### Contact Groups
179
188
 
180
189
  ```ruby
@@ -186,6 +195,27 @@ g.members
186
195
  => [#<AddressBook::Person:2: {:first_name=>"Daniel", :last_name=>"Higgins", ...}>]
187
196
  ```
188
197
 
198
+ ### Notifications (\* iOS only \*)
199
+
200
+ The iOS Address Book does not deliver notifications of changes through
201
+ the standard Notification Center. `motion-addressbook` wraps the
202
+ framework `ABAddressBookRegisterExternalChangeCallback` call with an
203
+ optional handler that converts the update event to an iOS
204
+ notification.
205
+
206
+ ```ruby
207
+ ab.observe!
208
+
209
+ App.notification_center.observe :addressbook_updated do |notification|
210
+ NSLog "Address Book was changed!"
211
+ end
212
+ ```
213
+
214
+ The notification must be explicitly enabled in your application. In
215
+ some cases iOS appears to trigger multiple notifications for the same
216
+ change event, and if you are doing many changes at once you will
217
+ receive a long stream of notifications.
218
+
189
219
  ## Contributing
190
220
 
191
221
  1. Fork it
@@ -1,5 +1,5 @@
1
1
  module Motion
2
2
  module Addressbook
3
- VERSION = "1.6.3"
3
+ VERSION = "1.7.0"
4
4
  end
5
5
  end
@@ -4,6 +4,7 @@ require File.expand_path('../lib/motion-addressbook/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = "motion-addressbook"
6
6
  gem.version = Motion::Addressbook::VERSION
7
+ gem.license = 'MIT'
7
8
 
8
9
  gem.authors = ["Alex Rothenberg", "Jason May"]
9
10
  gem.email = ["alex@alexrothenberg.com", "jmay@pobox.com"]
@@ -13,9 +13,14 @@ module AddressBook
13
13
  end
14
14
  end
15
15
 
16
+ def instance
17
+ @instance ||= AddrBook.new
18
+ end
19
+
16
20
  def count
17
21
  if App.ios?
18
- ABAddressBookGetPersonCount(address_book)
22
+ # ABAddressBookGetPersonCount(address_book)
23
+ instance.count
19
24
  else
20
25
  address_book.count
21
26
  end
@@ -28,6 +28,14 @@ module AddressBook
28
28
  def activate!
29
29
  @ab = LiveAddrBook.new(AddressBook.address_book)
30
30
  end
31
+
32
+ def observe!
33
+ @notifier = Proc.new do |ab_instance, always_nil, context|
34
+ App.notification_center.post :addressbook_updated, self
35
+ end
36
+ ab.register_callback(@notifier)
37
+ end
38
+
31
39
  def authorized?
32
40
  AddressBook.authorized?
33
41
  end
@@ -143,8 +151,8 @@ module AddressBook
143
151
  def sources
144
152
  ABAddressBookCopyArrayOfAllSources(ab)
145
153
  end
146
- def register_callback(callback, context)
147
- ABAddressBookRegisterExternalChangeCallback(ab, callback, context)
154
+ def register_callback(callback)
155
+ ABAddressBookRegisterExternalChangeCallback(ab, callback, nil)
148
156
  end
149
157
  end
150
158
  end
@@ -4,6 +4,7 @@ module AddressBook
4
4
 
5
5
  def initialize
6
6
  @ab = ABAddressBook.addressBook
7
+ yield self if block_given?
7
8
  end
8
9
  def people(opts = {})
9
10
  if opts[:local]
@@ -58,9 +59,9 @@ module AddressBook
58
59
  end
59
60
  end
60
61
 
61
- def notify_changes(callback, context)
62
+ def observe!
62
63
  App.notification_center.observe KABDatabaseChangedExternallyNotification do |notification|
63
- callback.call(context)
64
+ App.notification_center.post :addressbook_updated, self
64
65
  end
65
66
  end
66
67
 
@@ -18,12 +18,12 @@ describe AddressBook::Person do
18
18
  @alex.should.not.exists?
19
19
  end
20
20
  it 'should have initial values' do
21
- @alex.first_name.should == 'Alex'
21
+ @alex.first_name.should.equal 'Alex'
22
22
  @alex.last_name.should == 'Testy'
23
- @alex.email_values.should == [@data[:emails][0][:value]]
23
+ @alex.email_values.should.equal [@data[:emails][0][:value]]
24
24
  end
25
25
  it 'should have a composite name' do
26
- @alex.composite_name.should == 'Alex Testy'
26
+ @alex.composite_name.should.equal 'Alex Testy'
27
27
  end
28
28
  end
29
29
 
@@ -39,9 +39,9 @@ describe AddressBook::Person do
39
39
  it 'should find match' do
40
40
  @alex.uid.should.not.be.nil
41
41
  alex = AddressBook::Person.find_by_uid @alex.uid
42
- alex.uid.should == @alex.uid
42
+ alex.uid.should.equal @alex.uid
43
43
  alex.email_values.should.include? @email
44
- alex.first_name.should == 'Alex'
44
+ alex.first_name.should.equal 'Alex'
45
45
  alex.last_name.should == 'Testy'
46
46
  end
47
47
  end
@@ -52,13 +52,13 @@ describe AddressBook::Person do
52
52
  alexes.each do |alex|
53
53
  alex.uid.should != nil
54
54
  alex.email_values.should.include? @email
55
- alex.first_name.should == 'Alex'
55
+ alex.first_name.should.equal 'Alex'
56
56
  alex.last_name.should == 'Testy'
57
57
  end
58
58
  end
59
59
  it 'should give empty list when nothing matches' do
60
60
  alexes = AddressBook::Person.find_all_by_email unique_email
61
- alexes.should == []
61
+ alexes.should.equal []
62
62
  end
63
63
  end
64
64
  describe '.find_by_email' do
@@ -66,7 +66,7 @@ describe AddressBook::Person do
66
66
  alex = AddressBook::Person.find_by_email @email
67
67
  alex.uid.should.not.be.nil
68
68
  alex.email_values.should.include? @email
69
- alex.first_name.should == 'Alex'
69
+ alex.first_name.should.equal 'Alex'
70
70
  alex.last_name.should == 'Testy'
71
71
  end
72
72
  it 'should give empty list when nothing matches' do
@@ -81,13 +81,13 @@ describe AddressBook::Person do
81
81
  alexes.each do |alex|
82
82
  alex.uid.should != nil
83
83
  alex.email_values.should.include? @email
84
- alex.first_name.should == 'Alex'
84
+ alex.first_name.should.equal 'Alex'
85
85
  alex.last_name.should == 'Testy'
86
86
  end
87
87
  end
88
88
  it 'should give empty list when nothing matches' do
89
89
  alexes = AddressBook::Person.where(:email => unique_email)
90
- alexes.should == []
90
+ alexes.should.equal []
91
91
  end
92
92
  end
93
93
 
@@ -102,7 +102,7 @@ describe AddressBook::Person do
102
102
  it 'should get bigger when we create another' do
103
103
  initial_people_count = AddressBook::Person.all.size
104
104
  @person = AddressBook::Person.create({:first_name => 'Alex2', :last_name=>'Rothenberg2'})
105
- AddressBook::Person.all.size.should == (initial_people_count + 1)
105
+ AddressBook::Person.all.size.should.equal (initial_people_count + 1)
106
106
  @person.delete!
107
107
  end
108
108
  end
@@ -121,17 +121,17 @@ describe AddressBook::Person do
121
121
  alex = AddressBook::Person.find_or_new_by_email(@email)
122
122
  alex.should.not.be.new_record
123
123
  alex.uid.should != nil
124
- alex.first_name.should == 'Alex'
124
+ alex.first_name.should.equal 'Alex'
125
125
  alex.last_name.should == 'Testy'
126
- alex.emails.attributes.map{|r| r[:value]}.should == [@email]
126
+ alex.emails.attributes.map{|r| r[:value]}.should.equal [@email]
127
127
  end
128
128
  it 'should return new person when no match found' do
129
129
  never_before_used_email = unique_email
130
130
  new_person = AddressBook::Person.find_or_new_by_email(never_before_used_email)
131
131
  new_person.should.be.new_record
132
132
  new_person.should.not.exists
133
- new_person.email_values.should == [never_before_used_email]
134
- new_person.first_name.should == nil
133
+ new_person.email_values.should.equal [never_before_used_email]
134
+ new_person.first_name.should.equal nil
135
135
  end
136
136
  end
137
137
  end
@@ -284,7 +284,7 @@ describe AddressBook::Person do
284
284
  end
285
285
 
286
286
  it 'should have a composite name' do
287
- @ab_person.composite_name.should == 'Mr. Alex Q. Testy III'
287
+ @ab_person.composite_name.should.equal 'Mr. Alex Q. Testy III'
288
288
  end
289
289
 
290
290
  it 'should be able to count the emails' do
@@ -325,8 +325,8 @@ describe AddressBook::Person do
325
325
  it 'should know it is not new' do
326
326
  @ab_person.should.not.be.new_record
327
327
  @ab_person.should.be.exists
328
- @ab_person.first_name.should == 'Alex'
329
- @ab_person.department.should == 'Development'
328
+ @ab_person.first_name.should.equal 'Alex'
329
+ @ab_person.department.should.equal 'Development'
330
330
  end
331
331
 
332
332
  it 'should not change ID' do
@@ -341,7 +341,7 @@ describe AddressBook::Person do
341
341
 
342
342
  it 'should be able to get each of the single value fields' do
343
343
  @match = AddressBook::Person.find_by_email(@ab_person.email_values.first)
344
- @match.first_name.should == 'New First Name'
344
+ @match.first_name.should.equal 'New First Name'
345
345
  @match.uid.should.equal @ab_person.uid
346
346
  end
347
347
  end
@@ -494,4 +494,26 @@ describe AddressBook::Person do
494
494
  ordered.should.equal [@p1, @p2, @p4, @p5, @p3]
495
495
  end
496
496
  end
497
+
498
+ describe "notifications" do
499
+ before do
500
+ @ab1 = AddressBook::AddrBook.new
501
+ @ab2 = AddressBook::AddrBook.new
502
+ @ab1.observe!
503
+ @ab2.observe!
504
+ @notifications = 0
505
+ App.notification_center.observe :addressbook_updated do |notification|
506
+ @notifications += 1
507
+ end
508
+
509
+ @alice = @ab2.create_person({first_name: 'Alice'})
510
+ @bob = @ab1.create_person({first_name: 'Bob'})
511
+ @alice.delete!
512
+ @bob.delete!
513
+ end
514
+
515
+ it "should be notified of every change" do
516
+ @notifications.should.equal 4
517
+ end
518
+ end
497
519
  end
@@ -2,6 +2,15 @@
2
2
  # instance from destruction when the spec suite runs. Specifically,
3
3
  # the contents of the iOS Address Book, which is global to all
4
4
  # applications.
5
+ #
6
+ # WARNING: Altering the simulator configuration at runtime is a risky
7
+ # practice. If we use `Kernel.system` instead of backquotes when
8
+ # invoking `mv` and `rm` below, the simulator throws a warning:
9
+ #
10
+ # The iOS Simulator libSystem was initialized out of order. This
11
+ # is most often caused by running host executables or inserting
12
+ # host dylibs. In the future, this will cause an abort.
13
+ #
5
14
 
6
15
  SIMULATOR_ROOT = "#{ENV['HOME']}/../.."
7
16
  AB_PATH = SIMULATOR_ROOT + "/Library/AddressBook"
@@ -12,21 +21,28 @@ def protect_existing_address_book
12
21
  # iOS layer protects them, but shelling out is still allowed so we
13
22
  # can alter the world that way.
14
23
 
15
- unless AddressBook.authorized?
16
- warn "BLOCKING FOR AUTHORIZATION"
17
- AddressBook.request_authorization
18
- end
19
-
20
24
  warn "PROTECTING EXISTING ADDRESS BOOK IN SIMULATOR"
21
25
 
22
- `mv \"#{AB_PATH}\" "#{AB_PATH_BAK}"`
26
+ `rm -rf \"#{AB_PATH_BAK}\"`
27
+ `mv \"#{AB_PATH}\" \"#{AB_PATH_BAK}\"`
28
+ # Kernel.system "rm -rf \"#{AB_PATH_BAK}\""
29
+ # Kernel.system "mv \"#{AB_PATH}\" \"#{AB_PATH_BAK}\""
23
30
  end
24
31
 
25
32
  at_exit do
26
33
  warn "RESTORING ORIGINAL ADDRESS BOOK IN SIMULATOR"
27
34
 
28
- `rm -rf \"#{AB_PATH}\"`
29
- `mv \"#{AB_PATH_BAK}\" "#{AB_PATH}"`
35
+ Kernel.system "rm -rf \"#{AB_PATH}\""
36
+ Kernel.system "mv \"#{AB_PATH_BAK}\" \"#{AB_PATH}\""
37
+ end
38
+
39
+ def wait_for_authorization
40
+ @semaphore = Dispatch::Semaphore.new(0)
41
+ AddressBook::AddrBook.new do
42
+ @semaphore.signal
43
+ end
44
+ @semaphore.wait
30
45
  end
31
46
 
32
47
  protect_existing_address_book
48
+ wait_for_authorization
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-addressbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Rothenberg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-30 00:00:00.000000000 Z
12
+ date: 2013-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bubble-wrap
@@ -95,7 +95,8 @@ files:
95
95
  - spec/osx/helpers/hacks.rb
96
96
  - spec/osx/helpers/person_helpers.rb
97
97
  homepage: ''
98
- licenses: []
98
+ licenses:
99
+ - MIT
99
100
  metadata: {}
100
101
  post_install_message:
101
102
  rdoc_options: []
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
114
  version: '0'
114
115
  requirements: []
115
116
  rubyforge_project:
116
- rubygems_version: 2.0.5
117
+ rubygems_version: 2.1.11
117
118
  signing_key:
118
119
  specification_version: 4
119
120
  summary: A RubyMotion wrapper around the iOS & OSX Address Book frameworks