2016-03-22 8 views
19

私は非難されたアドレス帳フレームワークから新しい連絡先フレームワークにアプリケーションを移行しています。アプリケーションは、ABAddressBookRegisterExternalChangeCallbackを使用して、別のアプリケーションが連絡先を変更したときに通知を受け取ります。Contact Framework ABAddressBook.ABAddressBookRegisterExternalChangeCallbackに相当します。

連絡先フレームワークで同等の機能を見つけることができません。アップルのドキュメントではthe CNContactStoreDidChangeNotification notificationで、デフォルトの通知センターを使用するように言う:

変更は別のCNContactStoreに発生したときに通知を掲載します。 Appleのアドバイスを受け

、私のコードは次のようになります。

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

しかし、私はこのアプローチには二つの問題を発見した:

  1. を私は含めすべての変更、のために通知しています私自身のアプリケーションで作られたもの。
  2. 通知はスプリアスです - 1回の変更で多くの通知を受け取ります。

変更は私のアプリ内で行われたとき、私は、通知のデバッグの説明を記録した場合、私はこのような何かを得る:

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

、変更が外部に行われた場合:

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

ご覧のとおり、これらを区別することは何も明白ではありません。

ABAddressBookRegisterExternalChangeCallbackから取得できる連絡先フレームワークから同じ動作を取得する方法を教えてもらえますか?

+0

自己は、このメソッドを呼び出すクラスインスタンスを参照しています。 – ogres

+0

@ogres確かに、私の部分で言葉が貧弱です。基本的には、「自己」を渡すことは、私が何をしたのか(外部アプリからの変更だけを受け取る)を達成するのでしょうか?それがうまくいくためには、どのタイプの_type_が「自己」でしょうか? –

+0

addressBookDidChange:メソッドが宣言されている限り、どのような型でも可能です。 – ogres

答えて

0

まず、APIの内部的な変更と外部的な変更を識別する方法がないことについてfiling a bug with Appleをお勧めします。

変更を行うと、直後に再登録する前に、あなたのオブザーバーの登録を解除すると、あなたの変更通知のすべてを欠場し、まだすべての外部のものを得ることを保証した場合の可能な回避策として、あなたが見ることができる:

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) 
    } 
} 
関連する問題