我有以下代码将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()
}
}
答案 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提交一份有关此问题的错误报告)。但由于我已获得授权,因此我访问了实际的地址簿数据,因此我的代码可以看到该注释。