Contact Framework equivalente a ABAddressBook.ABAddressBookRegisterExternalChangeCallback

Estoy migrando una aplicación del Marco de Libreta de direcciones en desuso al nuevo Marco de contactos. La aplicación utiliza ABAddressBookRegisterExternalChangeCallback para recibir una notificación cuando otra aplicación cambia un contacto.

No puedo encontrar una funcionalidad equivalente en el marco de contactos. La documentation de Apple dice que use el centro de notificación pnetworkingeterminado con la notificación CNContactStoreDidChangeNotification :

La notificación se publica cuando se producen cambios en otro CNContactStore .

Tomando el consejo de Apple, mi código se ve así:

 NSNotificationCenter.defaultCenter().addObserver( self, selector: "contactsChanged:", name: CNContactStoreDidChangeNotification, object: nil) 

Sin embargo, he encontrado dos problemas con este enfoque:

  1. Me notifican todos los cambios, incluidos los realizados por mi propia aplicación.
  2. Las notifications son espurias: recibo muchas notifications para un solo cambio.

Si logging la descripción de debugging de la notificación cuando se realizó el cambio dentro de mi aplicación, obtengo algo como esto:

 NSConcreteNotification 0x7d3370e0 {name = CNContactStoreDidChangeNotification; userInfo = { CNNotificationOriginationExternally = 1; CNNotificationSourcesKey = ( ); }} 

Y si los cambios se hacen externamente:

 NSConcreteNotification 0x7bf7a690 {name = CNContactStoreDidChangeNotification; userInfo = { CNNotificationOriginationExternally = 1; CNNotificationSourcesKey = ( ); }} 

Como puede ver, nada es obvio para distinguirlos.

¿Alguien puede decirme cómo get el mismo comportamiento del marco de contactos que se puede get de ABAddressBookRegisterExternalChangeCallback ?

Primero, recomendaría archivar un error con Apple sobre la falta de una forma de identificar los cambios internos vs externos en la API.

Como posible solución, podría ver si anular el logging de su observador antes de hacer un cambio y volver a registrarse inmediatamente después, asegura que se pierda todas sus notifications de cambio y aún obtenga todas las externas:

 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) } }