Which contacts changed outside your iOS app? Better CNContactStoreDidChange notification: Get real changes, without the noise.

Swift Version License CocoaPods Compatible Platform PRs Welcome

Why Oh Why

Sadly, the Contacts changes API is a mess:

  • The CNContactStoreDidChange notification is received for changes your own code did, not just outside your app. ?
  • It contains undocumented userInfo fields. ?
  • To get the actual changes, you need to use an Objective-C API that is not even callable from Swift. ?
  • That API is easy to get wrong, and requires maintaining opaque state, or receiving the complete changes history. ?

It’s the API that time forgot. ?‍♂️

ContactsChangeNotifier Features

  • Only get notified for changes outside your app. ?
  • Get the list of changes included in the notification. ?
  • Only get changes since last notification, not the full all-time history. ✨
  • No Objective-C required. ?


  1. Get the user’s Contacts access permission (see docs).
  2. Keep a ContactsChangeNotifier instance.
  3. Observe ContactsChangeNotifier.didChangeNotification notification.
  4. See change events in the notification’s contactsChangeEvents.

// 2. Keep a ContactsChangeNotifier instance.
let contactsChangeNotifier = try! ContactsChangeNotifier(
    store: myCNContactStore,
    fetchRequest: .fetchRequest(additionalContactKeyDescriptors: myCNKeyDescriptors)

// 3. Observe ContactsChangeNotifier.didChangeNotification notification.
let observation = NotificationCenter.default.addObserver(
    forName: ContactsChangeNotifier.didChangeNotification,
    object: nil,
    queue: nil
) { notification in
    // 4. See change events in the notification's `contactsChangeEvents`.
    for event in notification.contactsChangeEvents ?? [] {
        switch event {
        case let addEvent as CNChangeHistoryAddContactEvent:
        case let updateEvent as CNChangeHistoryUpdateContactEvent:
        case let deleteEvent as CNChangeHistoryDeleteContactEvent:



pod 'ContactsChangeNotifier'

Swift Package Manager:

dependencies: [
    .package(url: "", from: "1.0.0")


View Github