无法访问kABPersonNoteProperty

时间:2015-04-29 19:42:44

标签: ios swift abaddressbook

我有以下代码将iPhone的联系人数据复制到NSMutableDictionary中。我正在使用this answer中讨论的可选绑定。

firstName和lastName字段正确复制(以及此处未显示的电话和电子邮件字段),但我从未能够访问kABPersonNoteProperty ,也没有看到中的println语句登录。我试图将注释复制为String和NSString但没有成功。什么可能导致这个问题的想法?

var contactInfoDict:NSMutableDictionary!

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

    self.contactInfoDict = ["firstName":"", "lastName":"", "notes":""]

    if let firstName:String = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(firstName, forKey: "firstName")
        println(firstName)
    }

    if let lastName:String = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(lastName, forKey: "lastName")
        println(lastName)
    }

    if let notes:String = ABRecordCopyValue(person, kABPersonNoteProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(notes, forKey: "notes")
        println("Note: \(notes)")
    }

}

修改以下是完整的课程:

import UIKit
import AddressBookUI

class ContactsVC: UIViewController, ABPeoplePickerNavigationControllerDelegate {

@IBOutlet weak var done_Btn: UIBarButtonItem!
@IBAction func dismissContacts(sender: UIBarButtonItem) {
    self.dismissViewControllerAnimated(true, completion: nil)
    println("ContactsVC dismissed")
}

@IBOutlet weak var viewContainer: UIView!

var object:PFObject = PFObject(className: "Contact")
let personPicker: ABPeoplePickerNavigationController
var contactInfoDict:NSMutableDictionary!

required init(coder aDecoder: NSCoder) {
    personPicker = ABPeoplePickerNavigationController()
    super.init(coder: aDecoder)
    personPicker.peoplePickerDelegate = self
}

override func viewDidLoad() {
    super.viewDidLoad()

    done_Btn.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Avenir Next Medium", size: 16)!], forState: UIControlState.Normal)

}


@IBAction func addContact() {

    let actionSheetController: UIAlertController = UIAlertController(title: nil, message: "Would you like to select a contact from your iPhone or create a new contact directly in the app?", preferredStyle: .ActionSheet)

    let selectContactAction: UIAlertAction = UIAlertAction(title: "Select from iPhone", style: .Default) { action -> Void in
        self.performPickPerson(UIAlertAction)
    }
    actionSheetController.addAction(selectContactAction)

    let createContactAction: UIAlertAction = UIAlertAction(title: "Create App Contact", style: .Default) { action -> Void in
        self.performSegueWithIdentifier("AddContact", sender: self)
    }
    actionSheetController.addAction(createContactAction)

    let cancelAction:UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) {
        action -> Void in
    }
    actionSheetController.addAction(cancelAction)

    self.presentViewController(actionSheetController, animated: true, completion: nil)
}


func performPickPerson(sender : AnyObject) {
    self.presentViewController(personPicker, animated: true, completion: nil)
}


func peoplePickerNavigationControllerDidCancel(peoplePicker: ABPeoplePickerNavigationController!) {
    personPicker.dismissViewControllerAnimated(true, completion: nil)
}

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

    self.contactInfoDict = ["firstName":"", "lastName":"", "company":"", "mobilePhone":"", "homePhone":"", "workPhone":"", "personalEmail":"", "workEmail":"", "street":"", "city":"", "state":"", "zipCode":"", "notes":""]

    if let firstName:String = ABRecordCopyValue(person, kABPersonFirstNameProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(firstName, forKey: "firstName")
        println(firstName)
    }

    if let lastName:String = ABRecordCopyValue(person, kABPersonLastNameProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(lastName, forKey: "lastName")
        println(lastName)
    }

    if let company:String = ABRecordCopyValue(person, kABPersonOrganizationProperty)?.takeRetainedValue() as? String {
        contactInfoDict.setObject(company, forKey: "company")
        println(company)
    }


    if let phonesRef:ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty)?.takeRetainedValue() as ABMultiValueRef? {
        for (var i = 0; i < ABMultiValueGetCount(phonesRef); i++ ) {
            var currentPhoneLabel:CFStringRef = ABMultiValueCopyLabelAtIndex(phonesRef, i).takeRetainedValue()
            var currentPhoneValue:CFStringRef = ABMultiValueCopyValueAtIndex(phonesRef, i)?.takeRetainedValue() as! CFStringRef

            if let mobileResult = CFStringCompare(currentPhoneLabel, kABPersonPhoneMobileLabel, CFStringCompareFlags.CompareCaseInsensitive) as CFComparisonResult? {
                if mobileResult == CFComparisonResult.CompareEqualTo {
                    contactInfoDict.setObject(currentPhoneValue, forKey: "mobilePhone")
                }
            }

            if let homeResult = CFStringCompare(currentPhoneLabel, kABHomeLabel, CFStringCompareFlags.CompareCaseInsensitive) as CFComparisonResult? {
                if homeResult == CFComparisonResult.CompareEqualTo {
                    contactInfoDict.setObject(currentPhoneValue, forKey: "homePhone")
                }
            }
            if let workResult = CFStringCompare(currentPhoneLabel, kABWorkLabel, CFStringCompareFlags.CompareCaseInsensitive) as CFComparisonResult? {
                if workResult == CFComparisonResult.CompareEqualTo {
                    contactInfoDict.setObject(currentPhoneValue, forKey: "workPhone")
                }
            }
        }

    }

    if let emailsRef:ABMultiValueRef = ABRecordCopyValue(person, kABPersonEmailProperty)?.takeRetainedValue() as ABMultiValueRef? {
        for (var i = 0; i < ABMultiValueGetCount(emailsRef); i++ ) {
            var currentEmailLabel:CFStringRef = ABMultiValueCopyLabelAtIndex(emailsRef, i).takeRetainedValue()
            var currentEmailValue:CFStringRef = ABMultiValueCopyValueAtIndex(emailsRef, i)?.takeRetainedValue() as! CFStringRef

            if let email = kABHomeLabel as CFStringRef? {
                if let homeResult = CFStringCompare(currentEmailLabel, kABHomeLabel, CFStringCompareFlags.CompareCaseInsensitive) as CFComparisonResult? {
                    if homeResult == CFComparisonResult.CompareEqualTo {
                        contactInfoDict.setObject(currentEmailValue as String, forKey: "personalEmail")
                    }
                }
            }
            if let workResult = CFStringCompare(currentEmailLabel, kABWorkLabel, CFStringCompareFlags.CompareCaseInsensitive) as CFComparisonResult? {
                if workResult == CFComparisonResult.CompareEqualTo {
                    contactInfoDict.setObject(currentEmailValue as String, forKey: "workEmail")
                }
            }
        }
    }

    if let addressRef:ABMultiValueRef = ABRecordCopyValue(person, kABPersonAddressProperty)?.takeRetainedValue() as ABMultiValueRef? {
        if ABMultiValueGetCount(addressRef) > 0 {
            var addressDict:NSDictionary = ABMultiValueCopyValueAtIndex(addressRef, 0)?.takeRetainedValue() as! NSDictionary

            if let street = addressDict.objectForKey(kABPersonAddressStreetKey) as? String {
                contactInfoDict.setObject(street as NSString, forKey: "street")
            }

            if let city = addressDict.objectForKey(kABPersonAddressCityKey) as? String {
                contactInfoDict.setObject(city as NSString, forKey: "city")
            }

            if let state = addressDict.objectForKey(kABPersonAddressStateKey) as? String {
                contactInfoDict.setObject(state as NSString, forKey: "state")
            }

            if let zipCode = addressDict.objectForKey(kABPersonAddressZIPKey) as? String {
                contactInfoDict.setObject(zipCode as NSString, forKey: "zipCode")
            }
        }
    }

    // Notes is not currently accessible
    if let note:String = ABRecordCopyValue(person, kABPersonNoteProperty)?.takeRetainedValue() as? String {
        println("12")
        contactInfoDict.setObject(note, forKey: "notes")
        println("Note: \(note)")
    }

    saveToContact()
}

func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, shouldContinueAfterSelectingPerson person: ABRecord!, property: ABPropertyID, identifier: ABMultiValueIdentifier) -> Bool {
    return false
}


func saveToContact(){
    self.object["username"] = PFUser.currentUser()!

    if let firstName = contactInfoDict["firstName"] as? String{
        self.object["contactFirstName"] = firstName
    }

    if let lastName = contactInfoDict["lastName"] as? String{
        self.object["contactLastName"] = lastName
    }

    if let company = contactInfoDict["company"] as? String{
        self.object["contactCompany"] = company
    }

    if let mobilePhone = contactInfoDict["mobilePhone"] as? String{
        self.object["contactMobilePhone"] = mobilePhone
    }

    if let homePhone = contactInfoDict["homePhone"] as? String{
        self.object["contactHomePhone"] = homePhone
    }

    if let workPhone = contactInfoDict["workPhone"] as? String{
        self.object["contactWorkPhone"] = workPhone
    }

    if let personalEmail = contactInfoDict["personalEmail"] as? String{
        self.object["contactPersonalEmail"] = personalEmail
    }

    if let workEmail = contactInfoDict["workEmail"] as? String{
        self.object["contactWorkEmail"] = workEmail
    }

    if let street = contactInfoDict["street"] as? String{
        self.object["contactStreet"] = street
    }

    if let city = contactInfoDict["city"] as? String{
        self.object["contactCity"] = city
    }

    if let state = contactInfoDict["state"] as? String{
        self.object["contactState"] = state
    }

    if let zipCode = contactInfoDict["zipCode"] as? String{
        self.object["contactZipCode"] = zipCode
    }

    if let notes = contactInfoDict["notes"] as? String{
        self.object["contactNotes"] = notes
    }

    self.object["contactType"] = "Lead"

    self.object["contactIsActive"] = true


    var addrObject = self.object
    self.object.pinInBackgroundWithName("Contacts")
    self.object.saveEventually{ (success, error) -> Void in
        if (error == nil) {
            println("saved in background")
        } else {
            println(error!.userInfo)
        }
    }
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

1 个答案:

答案 0 :(得分:1)

我刚试过它并且它工作正常,就像你拥有它一样。这实际上是我的整个代码(当然除了获得授权):

@IBAction func doPeoplePicker (sender:AnyObject!) {
    let picker = ABPeoplePickerNavigationController()
    picker.peoplePickerDelegate = self
    self.presentViewController(picker, animated:true, completion:nil)
}

func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, 
didSelectPerson person: ABRecord!) {
    if let note = ABRecordCopyValue(person, kABPersonNoteProperty)?.takeRetainedValue() as? String {
        println(note)
    } else {
        println("no note")
    }
}

当我的人有笔记时,我看到了;当我的人没有笔记时,我会看到&#34;没有笔记&#34;。

编辑你和我玩了一段时间,相互发送实际项目,我观察到你的实现和我的实现之间的以下区别:我的,获取笔记的工作,获得授权访问地址簿(您在我的原始答案的第一段中注意到我确实提到了这一点);你的,提取笔记不起作用,没有获得授权。因此,我认为这是这个难题的缺失部分。

这是我的理论。在iOS 8之前,您需要授权才能使用ABPeoplePickerNavigationController。因此,我的代码仍然可以获得它。这种在iOS 8中可行的方式是,在没有授权的情况下,人员选择器会获取地址簿数据的副本。好吧,我认为这个副本是错误的(你应该向Apple提交一份有关此问题的错误报告)。但由于我已获得授权,因此我访问了实际的地址簿数据,因此我的代码可以看到该注释。