The contacts module allows you to read and modify the iOS contacts (address book) database.
Note
The first time the contacts module is imported, a system-provided permission dialog will be shown. If you deny access, get_all_people() will always return an empty list. If you change your mind later, you can allow access to your contacts from the Privacy section in the Settings app.
As a simple example for reading information in the address book, let’s start with a script that prints out all people that have text in the ‘Notes’ field:
import contacts
print 'Address Book Notes'
print '=' * 40
people = contacts.get_all_people()
for p in people:
note = p.note
if note:
print p.full_name
print '-' * 40
print note
print '=' * 40
The script uses the get_all_people() function to retrieve a list of all Person objects in the address book, iterates over the list, and prints the name and note for each person that has a (non-empty) Person.note field.
As a slightly more complex example, this script prints out a list of upcoming birthdays (as number of days from now):
import contacts
from datetime import datetime
import operator
days_list = []
people = contacts.get_all_people()
now = datetime.now()
for p in people:
b = p.birthday
if b:
next_birthday = datetime(now.year, b.month, b.day)
if next_birthday < now:
next_birthday = datetime(now.year + 1, b.month, b.day)
days = (next_birthday - now).days
days_list.append({'name': p.full_name, 'days': days})
if not days_list:
print 'You don\'t have any birthdays in your address book.'
else:
days_list.sort(key=operator.itemgetter('days'))
print 'Upcoming Birthdays'
print '=' * 40
for item in days_list:
print '* %s in %i days' % (item['name'], item['days'])
The note and birthday fields are very easy to use because there is only one for each person. Many other fields can have multiple values, e.g. a person can have more than one email address. These fields are represented as lists of tuples, with each tuple containing a label (e.g. ‘home’, ‘work’...), and the actual value. An example for the Person.email attribute would be [('home', 'me@example.com'), ('work', 'work@example.com')].
So far, we’ve only read information from the address book database, but you can also use the contacts module to make changes. Because the previous example used a simple single-value attribute, let’s use the more complex Person.address attribute now, which is represented as a list of multiple dictionaries, each wrapped in a tuple that contains a label (e.g. ‘home’, ‘work’...). Let’s change the country of all people that live in Berlin to be Germany:
import contacts
people = contacts.get_all_people()
for p in people:
changed = False
addresses = p.address
for address_tuple in addresses:
address = address_tuple[1]
city = address.get(contacts.CITY, None)
country = address.get(contacts.COUNTRY, None)
if city == 'Berlin' and country != 'Germany':
address[contacts.COUNTRY] = 'Germany'
address[contacts.COUNTRY_CODE] = 'de'
changed = True
if changed:
p.address = addresses
print 'Updated country of', p.full_name
contacts.save()
print 'Done'
Note that we’ve used constants for the keys in the address dictionary – you can find a list of these keys at the end of this document. After making any changes to the address book, you have to call the save() function to make them persistent.
Note that all multi-value attributes are returned as ‘snapshots’. Modifying these lists directly has no effect unless you re-assign the attribute.
Do a prefix search for the given name and return a list of all matching Person records.
Return a list of all people in the address book. Each list entry is a Person object.
Save all pending changes in the contacts database. After changing any attributes of a Group or Person object, this function has to be called in order to make the changes persistent.
Revert all pending changes in the contacts database.
Return a localized version of a label that is used in a multi-value property.
A Group object represents a group in the address book, e.g. friends, family, or co-workers. After initializing a Group object and setting its name attribute, it can be added to the address book database by calling add_group(). When a group’s name is modified, the save() function has to be called in order to make the change persistent.
The group’s name, e.g. ‘Friends’ or ‘Family’.
The persistent identifier of the group record in the address book (int, readonly), or -1 if the group has not been saved yet. The id can be used with the get_group() function.
Person objects represent people in the address book. After initializing a Person and setting its various attributes, it can be added to the address book database by calling add_person(). After any attributes are modified, the save() function has to be called in order to make the changes persistent.
A lot of attributes can have multiple values, e.g. a person can have multiple email addresses (work, private, ...) or phone numbers (home, mobile, ...). Each of these attributes is represented as a list of 2-tuples, with each tuple containing a label and the actual value. For example, this could be the contents of a person’s email attribute: [('home', 'foo@work.com'), ('work', 'foo@work.com')]. Though it’s possible to use any string as a label, it is recommended to use one of the constants at the end of this document. These labels look like '_$!<Work>!$', but will be localized in the UI. You can get a localized representation of a label constant by using the localized_label() function.
Street address(es) (multi-dictionary). Use the constants contacts.STREET, contacts.CITY, contacts.STATE etc. as keys.
Birthday (datetime.datetime).
When the person was added to the address book (readonly, datetime.datetime).
Department (string).
Email address(es) (multi-string)
First name (string)
First name phonetic (string)
The person’s full name (readonly, string). To modify the name, use the Person.first_name, Person.last_name and Person.middle_name attributes.
The persistent identifier of the person record in the address book (int, readonly), or -1 if the person has not been saved yet. The id can be used with the get_person() function.
Instant message accounts (multi-dictionary).
Job title (string).
The kind of address book record (int, 0 for a person, 1 for an organization).
Last name (string).
Last name phonetic (string).
Middle name (string).
Middle name phonetic (string).
When the person was last modified (readonly, datetime.datetime).
Nickname (string).
Note (string).
Organization (string).
Phone number(s) (multi-string).
Prefix, e.g. “Sir,” “Duke,” “General” (string).
Related names (multi-string).
Social profile(s), e.g. Twitter accounts (multi-dictionary).
Suffix, e.g. “Jr.,” “Sr.,” “III” (string).
URL(s), e.g. homepage (multi-string).
VCard reprentation of the person’s data (readonly, string).
Generic labels for multi-value attributes:
Labels for the Person.phone multi-string attribute:
Labels for the Person.related_names multi-string attribute:
Labels for the Person.url multi-string attribute:
Keys for Person.address dictionaries: