19

ABPeoplePickerNavigationController最初のView Controllerに追加しました。連絡先を選択すると、他のView Controllerに表示する情報が表示されますが、コードを使用しようとしていますが、連絡先をクリックしても表示されません。これは、連絡先をネイティブ アプリに開くだけですABPeoplePickerNavigationController

var people = ABPeoplePickerNavigationController()
var addressBook: ABAddressBookRef?

func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef? {
    if let ab = abRef {
        self.view.addSubview(people.view)
        return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
    }
    return nil
}

この機能を試してみました

func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!,didSelectPerson person: ABRecordRef!) {

    var unmanagedEmails = ABRecordCopyValue(people, kABPersonEmailProperty)
    let emailObj: ABMultiValueRef = Unmanaged.fromOpaque(unmanagedEmails.toOpaque()).takeUnretainedValue() as NSObject as ABMultiValueRef

    var index = 0 as CFIndex

    var unmanagedEmail = ABMultiValueCopyValueAtIndex(emailObj, index)
    var emailAddress:String = Unmanaged.fromOpaque(unmanagedEmail.toOpaque()).takeUnretainedValue() as NSObject as String

    println(emailAddress)      
}

ありがとう!

4

3 に答える 3

17

いくつかの考え:

  1. ピッカー コントローラーのpeoplePickerDelegateプロパティを設定しましたか? peopleそうしないと、クラスでこれらのメソッドを呼び出そうとしてもわかりません。したがって:

    people.peoplePickerDelegate = self
    presentViewController(people, animated: true, completion: nil)
    
  2. あなたの例のメソッドはpeople、あなたが呼び出すときに参照していますABRecordCopyValue。それがピッカーコントローラーです。パラメータとして渡されたpersonを参照するつもりだったと思います。ABRecordRef!

    また、アクセスする前に、実際に電子メール アドレスを持っていることを確認することもできます。使用できますABMultiValueGetCount

    fromOpaqueまた、その/toOpaqueダンスをなくすこともできると思います。

    これにより、次の結果が得られます。

    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, didSelectPerson person: ABRecord) {
        let emails: ABMultiValueRef = ABRecordCopyValue(person, kABPersonEmailProperty).takeRetainedValue()
        if ABMultiValueGetCount(emails) > 0 {
            let index = 0 as CFIndex
            let emailAddress = ABMultiValueCopyValueAtIndex(emails, index).takeRetainedValue() as! String
    
            print(emailAddress)
        } else {
            print("No email address")
        }
    }
    
  3. iOS 7 もサポートする必要がある場合は、次を使用します。

    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, shouldContinueAfterSelectingPerson person: ABRecord, property: ABPropertyID, identifier: ABMultiValueIdentifier) -> Bool {
        let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
        let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
        let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as! String
    
        print("email = \(email)")
    
        peoplePicker.dismissViewControllerAnimated(true, completion: nil)
    
        return false
    }
    
  4. ただし、ユーザーが最初の電子メール アドレスだけを望んでいると想定するのではなく、連絡先が持っている可能性のある複数の電子メール アドレスのいずれかをクリックして選択できるようにすることもできます。そのため、最初に、電子メール アドレスのみを表示するようにピッカーに指示することで、「ノイズ」の一部を排除することができます。

    people.peoplePickerDelegate = self
    people.displayedProperties = [NSNumber(int: kABPersonEmailProperty)]
    presentViewController(people, animated: true, completion: nil)
    

    そして、これまで議論してきた方法を削除し、代わりに以下を実装します。

    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson person: ABRecordRef!, property: ABPropertyID, identifier: ABMultiValueIdentifier) {
        let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
        let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
        let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as String
    
        println("email = \(email)")
    }
    

    また、iOS 7.0 もサポートするには、以下を追加します。

    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, shouldContinueAfterSelectingPerson person: ABRecord, property: ABPropertyID, identifier: ABMultiValueIdentifier) -> Bool {
        let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
        let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
        let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as! String
    
        print("email = \(email)")
    
        peoplePicker.dismissViewControllerAnimated(true, completion: nil)
    
        return false
    }
    
  5. ところで、iOS 8 には、連絡先を有効にするかどうかを制御する機能が用意されています。iOS 7 および 8 をサポートしているため、次のように条件付きで使用する必要があります。

    if people.respondsToSelector(Selector("predicateForEnablingPerson")) {
        people.predicateForEnablingPerson = NSPredicate(format: "emailAddresses.@count > 0")
    }
    

    これにより、ユーザーは個人の電子メール アドレスがあるかどうかを視覚的に示すことができ、電子メール アドレスのないエントリを選択することができなくなります。

明らかに、iOS 9 以降を使用している場合は、これらすべてを廃止してContactsUIフレームワークを使用する必要があります。これにより、コードがさらに簡素化されます。

于 2014-08-09T15:23:43.480 に答える