Addressbook for RubyMotion
A RubyMotion wrapper around the iOS and OSX Address Book frameworks for RubyMotion apps.
Apple's Address Book Programming Guide for iOS or for OSX
Installation
If you're using bundler
(this is recommended):
Add these lines to your application's Rakefile
:
require 'bundler'
Bundler.require
Add this line to your application's Gemfile
:
gem 'motion-addressbook'
And then execute:
$ bundle
Manually without bundler
Or install it yourself (remember to add the bubble-wrap dependency) as:
$ gem install bubble-wrap
$ gem install motion-addressbook
Usage
Requesting access
iOS 6/7 requires that the user give permission before it allows an app to access the AddressBook.
1 - Let the gem take care of it for you
ab = AddressBook::AddrBook.new
# ...do something else...
people = ab.people
The people
method will raise an exception if called while
authorization has not been granted.
2 - Manually decide when to ask the user for authorization
# asking whether we are already authorized
if AddressBook.
puts "This app is authorized!"
else
puts "This app is not authorized!"
end
# ask the user to authorize us (blocking)
if AddressBook.
# do something now that the user has said "yes"
else
# do something now that the user has said "no"
end
3 - Manually ask the user but do it asynchronously (this is how Apple's API works)
# ask the user to authorize us
if AddressBook.request_authorization do |granted|
# this block is invoked sometime later
if granted
# do something now that the user has said "yes"
else
# do something now that the user has said "no"
end
end
# do something here before the user has decided
The iOS6 simulator does not demand AddressBook authorization. The iOS7 simulator does.
Showing the ABPeoplePickerNavigationController
AddressBook.pick do |person|
if person
# person is an AddressBook::Person object
else
# canceled
end
end
You can also specify the presenting controller:
AddressBook.pick presenter: self do |person|
...
end
Showing the ABNewPersonViewController
AddressBook.create do |person|
if person
# person is an AddressBook::Person object
else
# canceled
end
end
Working with Person objects
Get a list of existing people from the Address Book. On IOS, results are sorted using the sort order (First/Last or Last/First) chosen by the user in iOS Settings.
ab = AddressBook::AddrBook.new
ab.people
=> [#<AddressBook::Person:3: {:first_name=>"John", :last_name=>"Appleseed", ...}>, ...]
Create a new Person and save to the Address Book.
Note that Person records can take multiple values for email addresses, phone numbers, postal address, social profiles, and instant messaging profiles.
ab.create_person(:first_name => 'Alex', :last_name => 'Rothenberg', :emails => [{ :value => '[email protected]', :label => 'Home'}], :phones => [{ :value => '9920149993', :label => 'Mobile'}])
=> #<AddressBook::Person:7: {:first_name=>"Alex", :last_name=>"Rothenberg", ...}>
Construct a new blank Person but do not store it immediately in the Address Book.
ab.new_person(:first_name => "Bob")
=> #<AddressBook::Person:-1: {:first_name=>"Bob"}>
ab.last_name = 'Brown'
ab.save
=> #<AddressBook::Person:9: {:first_name=>"Bob", :last_name=>"Brown"}>
Get a list of all people matching one attribute with .find_all_by_XXX
AddressBook::Person.find_all_by_email('[email protected]')
=> [#<AddressBook::Person:14: {:first_name=>"Alex", :last_name=>"Rothenberg", ...}>]
Get the first person matching one attribute with .find_by_XXX
AddressBook::Person.find_by_email('[email protected]')
=> #<AddressBook::Person:14: {:first_name=>"Alex", :last_name=>"Rothenberg", ...}>]
Get a list of all people matching several attributes with .where
AddressBook::Person.where(:email => '[email protected]', :first_name => 'Alex')
=> [#<AddressBook::Person:14: {:first_name=>"Alex", :last_name=>"Rothenberg", ...}>]
Look for an existing person or get a new one if none is found find_or_new_by_XXX
AddressBook::Person.find_or_new_by_email('[email protected]')
=> #<AddressBook::Person:17: {:first_name=>"Alex", :last_name=>"Rothenberg", ...}>]
Update existing Person
alex = AddressBook::Person.find_by_email('[email protected]')
alex.job_title = 'RubyMotion Developer'
alex.save
Or to alter all the attributes at once (preserve the record identifier but change some or all of the values):
alex = AddressBook::Person.find_by_email('[email protected]')
alex.replace({:first_name=>"Alex", :last_name=>"Rider", ...})
alex.save
Contact Groups
ab.groups
=> [#<AddressBook::Group:1:Friends: 1 members>, #<AddressBook::Group:2:Work: 0 members>]
g = ab.groups.first
g.members
=> [#<AddressBook::Person:2: {:first_name=>"Daniel", :last_name=>"Higgins", ...}>]
Notifications (* iOS only *)
The iOS Address Book does not deliver notifications of changes through
the standard Notification Center. motion-addressbook
wraps the
framework ABAddressBookRegisterExternalChangeCallback
call with an
optional handler that converts the update event to an iOS
notification.
ab.observe!
App.notification_center.observe :addressbook_updated do |notification|
NSLog "Address Book was changed!"
end
The notification must be explicitly enabled in your application. In some cases iOS appears to trigger multiple notifications for the same change event, and if you are doing many changes at once you will receive a long stream of notifications.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request