2016-03-22 8 views
19

Ich migriere eine Anwendung aus dem veralteten Adressbuch-Framework in das neue Contacts Framework. Die Anwendung verwendet ABAddressBookRegisterExternalChangeCallback, um benachrichtigt zu werden, wenn eine andere Anwendung einen Kontakt ändert.Contact Framework entspricht ABAddressBook.ABAddressBookRegisterExternalChangeCallback

Ich finde keine entsprechende Funktionalität im Contacts Framework. Apple-Dokumentation sagt das Standardbenachrichtigungszentrum mit the CNContactStoreDidChangeNotification notification zu verwenden:

Die Meldung geschrieben, wenn Änderungen in einer anderen CNContactStore auftreten.

Einnahme von Apple Rat, sieht mein Code wie folgt aus:

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

Allerdings habe ich zwei Probleme mit diesem Ansatz gefunden haben:

  1. ich benachrichtigt werde für alle Änderungen, einschließlich solche, die ich selbst gemacht habe.
  2. Benachrichtigungen sind falsch - ich erhalte viele Benachrichtigungen für eine einzige Änderung.

Wenn ich die Debug-Beschreibung der Benachrichtigung anmelden, wenn die Änderung in meiner app gemacht wurde, habe ich so etwas wie dieses:

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

Und wenn die Änderungen vorgenommen wurden extern:

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

Wie Sie sehen können, ist nichts offensichtlich, mit dem sie zu unterscheiden.

Kann mir jemand sagen, wie man das gleiche Verhalten vom Contacts Framework bekommt, wie man von ABAddressBookRegisterExternalChangeCallback bekommen kann?

+0

Selbst bezieht sich auf die Klasseninstanz, von der Sie diese Methode aufrufen. – ogres

+0

@ogres sicher, schlechte Formulierung meinerseits. Im Grunde erreicht die Weitergabe in "self", was ich möchte (nur die Änderungen von externen Apps erhalten)? Damit das funktioniert, was wäre _type_ selbst? –

+0

Self kann von jedem Typ sein, solange es addressBookDidChange: method deklariert ist. – ogres

Antwort

0

Zuerst würde ich empfehlen filing a bug with Apple über das Fehlen einer Möglichkeit, interne vs. externe Änderungen in der API zu identifizieren.

Als mögliche Abhilfe könnte man sehen, ob Ihr Beobachter enfernen, bevor Sie eine Änderung und zur Re-Registrierung sofort gewährleistet, danach, dass Sie alle Ihre Änderungsbenachrichtigungen verpassen und immer noch alle Externen erhalten:

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