Skip to content

yonat/ContactsChangeNotifier

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ContactsChangeNotifier

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. 💥

Usage

  1. Get the user's Contacts access permission (see docs).
  2. Keep a ContactsChangeNotifier instance - it will observe all Contacts changes but post only those that from outside your app.
  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:
            print(addEvent.contact)
        case let updateEvent as CNChangeHistoryUpdateContactEvent:
            print(updateEvent.contact)
        case let deleteEvent as CNChangeHistoryDeleteContactEvent:
            print(deleteEvent.contactIdentifier)
        default:
            // group event
            break
        }
    }
}

Installation

CocoaPods:

pod 'ContactsChangeNotifier'

Swift Package Manager:

dependencies: [
    .package(url: "https://github.com/yonat/ContactsChangeNotifier", from: "1.0.3")
]

About

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

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project