I'm trying to implement the func personViewController(personViewController: ABPersonViewController!,
shouldPerformDefaultActionForPerson person: ABRecord!,
property property: ABPropertyID,
identifier valueIdentifier: ABMultiValueIdentifier) -> Bool
function, which is part of the ABPersonViewControllerDelegate
protocol and is called whenever the user clicks on an item in the ABPersonViewController
, such that any information the user selects will be copied to a [String : String]
dictionary such that the property name will be the key for the property value: [..."kABPersonFirstNameProperty" : "Alexander"...]
, say.
I also want to avoid a switch or a long list of conditions testing for if a property is this or that; I'd rather handle it as generally as possible—I'm trying for only two different cases: if the property is a single value or a multi value. If it's a multi-value, I'd like to copy down all the information available.
For example, if the user clicks on the address, the result might be such: [..."kABPersonAddressStreetKey" : "1 Infinite Loop", "kABPersonAddressCityKey" : "Cupertino" , "kABPersonAddressStateKey", "California (or CA?)"...]
.
This is all I have, after various hours of scouring the Apple Developer Library and related SO questions (pathetic, I know):
func personViewController(personViewController: ABPersonViewController!,
shouldPerformDefaultActionForPerson person: ABRecord!,
property property: ABPropertyID,
identifier valueIdentifier: ABMultiValueIdentifier) -> Bool {
s["kABPersonFirstNameProperty"] = ABRecordCopyValue(person, kABPersonFirstNameProperty) as! String //the name can't actually be selected by the user, but I want to capture it anyway
s["kABPersonLastNameProperty"] = ABRecordCopyValue(person, kABPersonLastNameProperty) as! String
if valueIdentifier == 0 { //property is a single property, not a multivalue property
let record = ABRecordCopyValue(person, property)
s[property as! String!] = record as! String
} else { //property is an ABMultiValue
let multiRecord = ABRecordCopyValue(person, property) as! ABMultiValueRef
s[property as! String] = ABMultiValueGetIndexForIdentifier(multiRecord, valueIdentifier)
}
return false
}
I can tell there are plenty of pieces missing—is it even possible to condense this into a dictionary?
Thanks in advance (and 100 reputation to whomever provides a complete, correct answer).
Using vadian's answer as a starting point, I compiled the following, which will gather and copy to a dictionary almost all of the information a user can select (and some information which a user can't click on—first name, last name, organization—automatically).
It's a work in progress, which I'll update as I continue to add support for more properties, but at present it works for first name, last name, email, phone numbers, address, and some social profiles.
I had to use indirect methods in some cases: storing phone numbers whose labels didn't have a designated key as
kAB_Label
s, for example, and it doesn't yet take the label of an email address.With
s
as of typeDictionary<String, AnyObject>
, here it is:Please, anyone should feel free to copy any/all parts of it which would be helpful.
I'm afraid there can't be a generic method to retrieve information from AddressBook because there are too many different collection and property types.
This is an example to get
first name
,last name
andaddress
information when the user taps on an address field.It's assumed that the dictionary
s
is declared asto be as generic as possible, all values are declared as
AnyObject