2016-03-22 32 views
19

Sto migrando un'applicazione dal deprecato Address Book Framework al nuovo Contacts Framework. L'applicazione utilizza ABAddressBookRegisterExternalChangeCallback per ricevere una notifica quando un'altra applicazione modifica un contatto.Contact Framework equivalente a ABAddressBook.ABAddressBookRegisterExternalChangeCallback

Non riesco a trovare funzionalità equivalenti nel framework dei contatti. la documentazione Apple dice di utilizzare il centro di notifica di default con the CNContactStoreDidChangeNotification notification:

La notifica inviato quando i cambiamenti si verificano in un altro CNContactStore.

Prendendo il consiglio di Apple, il mio codice simile a questo:

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

Tuttavia, ho trovato due problemi con questo approccio:

  1. sto notificato di tutti modifiche, tra cui quelli realizzati dalla mia stessa applicazione.
  2. Le notifiche sono false: ricevo molte notifiche per una singola modifica.

Se entro la descrizione di debug della notifica quando il cambiamento è stato fatto nel mio app, ottengo qualcosa di simile:

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

E se vengono apportate le modifiche esternamente:

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

Come potete vedere, nulla di ovvio con cui distinguerli.

Qualcuno può dirmi come ottenere lo stesso comportamento dal Framework Contatti come si può ottenere da ABAddressBookRegisterExternalChangeCallback?

+0

auto si riferisce all'istanza della classe, da cui si chiama questo metodo. – ogres

+0

@ rogres sicuro, povero testo da parte mia. Fondamentalmente, passando in "self" ottieni ciò che cerco (ricevendo solo quei cambiamenti da app esterne)? Perché ciò funzioni, quale sarebbe il tipo di sé? –

+0

autonomamente potrebbe essere di qualsiasi tipo, purché abbia indirizzoBookDidChange: metodo dichiarato. – ogres

risposta

0

Innanzitutto, suggerirei filing a bug with Apple sulla mancanza di un modo per identificare le modifiche interne e esterne nell'API.

Come possibile soluzione alternativa, si potrebbe vedere se l'annullamento della registrazione il vostro osservatore prima di fare un cambiamento e ri-registrazione subito dopo assicura che si dimentica tutte le tue notifiche di modifica e ancora ottenere tutte quelle esterne:

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