Which contacts changed outside your iOS app? Better CNContactStoreDidChange notification: get real changes, without the noise
ContactsChangeNotifier
Which contacts changed outside your iOS app? Better CNContactStoreDidChange
notification: Get real changes, without the noise.
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
- Get the user’s Contacts access permission (see docs).
- Keep a
ContactsChangeNotifier
instance. - Observe
ContactsChangeNotifier.didChangeNotification
notification. - 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:
break
}
}
}
Installation
CocoaPods:
pod 'ContactsChangeNotifier'
Swift Package Manager:
dependencies: [
.package(url: "https://github.com/yonat/ContactsChangeNotifier", from: "1.0.0")
]