contacts — Access the iOS Contacts Database#

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.

Quick Start#

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.

Functions#

contacts.get_group(group_id)#

Return the Group with the given id (an integer, c.f. Group.id).

contacts.get_all_groups()#

Return a list of all Group objects in the address book.

contacts.add_group()#

Add a Group to the address book.

contacts.remove_group(group)#

Remove a Group from the address book.

contacts.add_person(person)#

Add a Person to the address book.

contacts.remove_person(person)#

Remove a Person from the address book.

contacts.find(name)#

Do a prefix search for the given name and return a list of all matching Person records.

contacts.get_all_people()#

Return a list of all people in the address book. Each list entry is a Person object.

contacts.get_person(person_id)#

Return the Person with the given id (an integer, c.f. Person.id).

contacts.save()#

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.

contacts.revert()#

Revert all pending changes in the contacts database.

contacts.localized_label(label)#

Return a localized version of a label that is used in a multi-value property.

contacts.is_authorized()#

Returns True if access to the address book is currently allowed, False otherwise (e.g. if the permission dialog hasn’t been shown yet or if access is denied due to parental controls).

Group Objects#

class contacts.Group#

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.

Group.name#

The group’s name, e.g. ‘Friends’ or ‘Family’.

Group.id#

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#

class contacts.Person#

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.

Person.address#

Street address(es) (multi-dictionary). Use the constants contacts.STREET, contacts.CITY, contacts.STATE etc. as keys.

Person.birthday#

Birthday (datetime.datetime).

Person.creation_date#

When the person was added to the address book (readonly, datetime.datetime).

Person.department#

Department (string).

Person.email#

Email address(es) (multi-string)

Person.first_name#

First name (string)

Person.first_name_phonetic#

First name phonetic (string)

Person.full_name#

The person’s full name (readonly, string). To modify the name, use the Person.first_name, Person.last_name and Person.middle_name attributes.

Person.id#

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.

Person.image_data#

The person’s image, e.g. a photo (byte string representing a common image file format, like PNG or JPEG, or None if no image was set).

Person.instant_message#

Instant message accounts (multi-dictionary).

Person.job_title#

Job title (string).

Person.kind#

The kind of address book record (int, 0 for a person, 1 for an organization).

Person.last_name#

Last name (string).

Person.last_name_phonetic#

Last name phonetic (string).

Person.middle_name#

Middle name (string).

Person.middle_name_phonetic#

Middle name phonetic (string).

Person.modification_date#

When the person was last modified (readonly, datetime.datetime).

Person.nickname#

Nickname (string).

Person.note#

Note (string).

Person.organization#

Organization (string).

Person.phone#

Phone number(s) (multi-string).

Person.prefix#

Prefix, e.g. “Sir,” “Duke,” “General” (string).

Person.related_names#

Related names (multi-string).

Person.social_profile#

Social profile(s), e.g. Twitter accounts (multi-dictionary).

Person.suffix#

Suffix, e.g. “Jr.,” “Sr.,” “III” (string).

Person.url#

URL(s), e.g. homepage (multi-string).

Person.vcard#

VCard reprentation of the person’s data (readonly, string).

Constants#

Generic labels for multi-value attributes:

contacts.HOME#
contacts.WORK#
contacts.OTHER#

Labels for the Person.phone multi-string attribute:

contacts.IPHONE#
contacts.MAIN_PHONE#
contacts.HOME_FAX#
contacts.WORK_FAX#
contacts.OTHER_FAX#
contacts.PAGER#

Labels for the Person.related_names multi-string attribute:

contacts.FATHER#
contacts.MOTHER#
contacts.PARENT#
contacts.BROTHER#
contacts.SISTER#
contacts.CHILD#
contacts.FRIEND#
contacts.SPOUSE#
contacts.PARTNER#
contacts.ASSISTANT#
contacts.MANAGER#

Labels for the Person.url multi-string attribute:

contacts.HOMEPAGE#

Keys for Person.address dictionaries:

contacts.STREET#
contacts.CITY#
contacts.STATE#
contacts.ZIP#
contacts.COUNTRY#
contacts.COUNTRY_CODE#