I am migrating an application from the deprecated Address Book Framework to the new Contacts Framework. The application utilizes ABAddressBookRegisterExternalChangeCallback
to be notified when another application changes a contact.
I am unable to find equivalent functionality in the Contacts Framework. Apple documentation says to use the default notification center with the CNContactStoreDidChangeNotification
notification:
The notification posted when changes occur in another
CNContactStore
.
Taking Apple's advice, my code looks like this:
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "contactsChanged:",
name: CNContactStoreDidChangeNotification,
object: nil)
However, I have found two problems with this approach:
If I log the debug description of the notification when the change was made within my app, I get something like this:
NSConcreteNotification 0x7d3370e0 {name = CNContactStoreDidChangeNotification; userInfo = {
CNNotificationOriginationExternally = 1;
CNNotificationSourcesKey = (
);
}}
And if the changes are made externally:
NSConcreteNotification 0x7bf7a690 {name = CNContactStoreDidChangeNotification; userInfo = {
CNNotificationOriginationExternally = 1;
CNNotificationSourcesKey = (
);
}}
As you can see, nothing obvious with which to distinguish them.
Can anyone tell me how to get the same behavior from the Contacts Framework as one can get from ABAddressBookRegisterExternalChangeCallback
?
First, I'd recommend filing a bug with Apple about the lack of a way to identify internal vs external changes in the API.
As a possible workaround, you could see if unregistering your observer before making a change and re-registering immediately afterward ensures that you miss all of your change notifications and still get all the external ones:
class ContactsThingy {
var observer: NSObjectProtocol?
let contacts = CNContactStore()
func contactStoreDidChange(notification: NSNotification) {
NSLog("%@", notification)
}
func registerObserver() {
let center = NSNotificationCenter.defaultCenter()
observer = center.addObserverForName(CNContactStoreDidChangeNotification, object: nil, queue: NSOperationQueue.currentQueue(), usingBlock: contactStoreDidChange)
}
func unregisterObserver() {
guard let myObserver = observer else { return }
let center = NSNotificationCenter.defaultCenter()
center.removeObserver(myObserver)
}
func changeContacts(request: CNSaveRequest) {
unregisterObserver() // stop watching for changes
defer { registerObserver() } // start watching again after this change even if error
try! contacts.executeSaveRequest(request)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With