PyObjC Contacts Framework

12.1 · active · verified Tue Apr 14

PyObjC-framework-contacts provides Python bindings and wrappers for Apple's Contacts.framework on macOS. It allows Python developers to interact with the system's contact store, fetch, create, update, and delete contacts, and manage contact groups. The current version is 12.1, with a release cadence that generally follows macOS SDK updates and Python version support cycles.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to list the names of all contacts using `CNContactStore` and `CNContactFetchRequest`. It showcases basic object allocation (`alloc().init()`) and method calls specific to the Contacts framework within PyObjC. Running this code will likely trigger a macOS permission prompt for Contacts access if not already granted.

from Contacts import CNContactStore, CNContactFetchRequest, CNContactGivenNameKey, CNContactFamilyNameKey
from Foundation import NSArray

def list_contact_names():
    """Fetches and prints the names of all contacts."""
    store = CNContactStore.alloc().init()
    
    # Define the keys (properties) to fetch for each contact
    keys_to_fetch = [CNContactGivenNameKey, CNContactFamilyNameKey]
    
    # CNContactFetchRequest expects an NSArray of keys
    request = CNContactFetchRequest.alloc().initWithKeysToFetch_(NSArray.arrayWithArray_(keys_to_fetch))
    
    contacts = []
    # Enumerate contacts: the third argument is a Python callable (block)
    # that gets called for each contact found.
    success, error = store.enumerateContactsWithFetchRequest_error_(
        request, None, lambda contact, stop: contacts.append(contact)
    )

    if not success:
        print(f"Error fetching contacts: {error}")
        return

    if contacts:
        print("Found contacts:")
        for contact in contacts:
            full_name = f"{contact.givenName() or ''} {contact.familyName() or ''}".strip()
            if full_name:
                print(f"- {full_name}")
            else:
                print(f"- (Unnamed contact, ID: {contact.identifier()})")
    else:
        print("No contacts found.")

if __name__ == '__main__':
    # Note: Requires Contacts permission. First run might prompt for access.
    list_contact_names()

view raw JSON →