【问题标题】:Unable to access kABPersonNoteProperty无法访问 kABPersonNoteProperty
【发布时间】:2015-07-09 06:58:26
【问题描述】:

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

firstName 和 lastName 字段正确复制(以及此处未显示的 phone 和 email 字段),但我一直无法访问 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()
}

}

【问题讨论】:

    标签: ios swift abaddressbook


    【解决方案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")
        }
    }
    

    当我的人有便条时,我会看到它;当我的人没有笔记时,我看到“没有笔记”。

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

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

    【讨论】:

    • 我创建了一个带有注释的测试联系人来测试这个,所以我知道这个人有一个注释。似乎至少有一个其他用户拥有same issue,尽管还没有关于该问题的答案。
    • 也许您提供注释的方式会有所不同?我先在通讯录中创建了便笺,然后我的代码看到它就好了。
    • 对不起,我不清楚你的评论。我刚刚在我的 iPhone 上使用 firstName Test 创建了一个标准联系人,添加了一个注释,保存它,然后从我的应用程序中显示的所有联系人列表中选择它。我还用其他带笔记的联系人对其进行了测试。也许这是 Swift 的一个错误。
    • “并从我的应用程序中显示的所有联系人列表中选择它”等待。怎么选的?使用人员选择器导航控制器?这可能就是区别。您能否展示更多用于配置、呈现和处理人员选择器导航控制器的代码?
    • 我刚刚添加了课程的完整代码。感谢您的观看。
    猜你喜欢
    • 2014-01-29
    • 1970-01-01
    • 2021-01-04
    • 2019-12-16
    • 2016-04-05
    • 2014-12-25
    • 2020-08-06
    • 2021-12-01
    • 2021-10-06
    相关资源
    最近更新 更多