Reputation: 598
I'm trying to read the contact image of my iOS addressbook but I'm having some troubles with it.
I have a method that read the information of contacts of ABAddressBookRef and put it on a struct.
func readContacts(addressBook: ABAddressBookRef){
let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBookRef).takeRetainedValue() as NSArray
var numeros : [Numeros] = []
//lendo todos os contatos
for person: ABRecordRef in allPeople{
let firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty).takeRetainedValue() as! String
let lastName = ABRecordCopyValue(person, kABPersonLastNameProperty).takeRetainedValue() as! String
let phones : ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty).takeUnretainedValue() as ABMultiValueRef
let data = ABPersonCopyImageData(person).takeRetainedValue() as NSData
let imagemContato = UIImage(data: data)
for(var numberIndex : CFIndex = 0; numberIndex < ABMultiValueGetCount(phones); numberIndex++) {
let phoneUnmaganed = ABMultiValueCopyValueAtIndex(phones, numberIndex)
let phoneNumber : NSString = phoneUnmaganed.takeUnretainedValue() as! NSString
let locLabel : CFStringRef = (ABMultiValueCopyLabelAtIndex(phones, numberIndex) != nil) ? ABMultiValueCopyLabelAtIndex(phones, numberIndex).takeUnretainedValue() as CFStringRef : ""
let cfStr:CFTypeRef = locLabel
let nsTypeString = cfStr as! NSString
let swiftString:String = nsTypeString as String
//let customLabel = String (stringInterpolationSegment: ABAddressBookCopyLocalizedLabel(locLabel))
let numero: Numeros = Numeros(tipoNumero: swiftString, numero: phoneNumber as String)
numeros.append(numero)
}
let registroContato: Contato = Contato(primeiroNome: firstName, ultimoNome: lastName, contatoRecord: person, numeros: numeros, imagemContato: imagemContato!)
contatos.append(registroContato)
}
}
but when I debug it, it stops on:
let data = ABPersonCopyImageData(person).takeRetainedValue() as NSData
and doesn't show any error message.
What am I doing wrong?
I'm using the simulator default contacts to test it, they did not have images but have the placeholder with his/her first letter of the name.
EDITED:
i've change the code to
let imagemContato: UIImage?
if let data = ABPersonCopyImageData(person)?.takeRetainedValue() as? NSData {
print("\(firstName) with image")
imagemContato = UIImage(data: data)
}
else {
print("\(firstName) without image")
imagemContato = UIImage(named: "UooQo.jpg")
}
and on the console all contacts have no image:
console output: Kate without image Daniel without image John without image Anna without image Hank without image David without image
it shows no image for contact but i add one to John.
Upvotes: 2
Views: 1948
Reputation: 598
i solved it using
let imagemContato: UIImage?
let imgData: CFData?
if ABPersonHasImageData(person) {
imgData = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail).takeRetainedValue()
imagemContato = UIImage(data: imgData!)
}else{
//placeholder
imagemContato = UIImage(named: "UooQo.jpg")
}
is this the correct way?
Upvotes: 0
Reputation: 1442
Same problem that I faced in my project earlier. Try this,
//To Get image
let img = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail).takeRetainedValue()
//To set image in your ImageView
YourImageView.image=UIImage(data: img as! NSData)
Upvotes: 1
Reputation: 11143
The AddressBook
framework is one of the frameworks that is really nasty to use with Swift. First I'll point out that there is a new Contacts framework in iOS 9, which I would suggest you use if you have the option of not supporting 8 and earlier (AddressBook
is deprecated as of iOS 9).
Having said that, the function ABPersonCopyImageData(ABRecord!)
returns a value that has the type Unmanaged<CFData>!
, which means that it is possible that it will be a nil
value (it really should be Unmanaged<CFData>?
, but I think Apple didn't bother fixing up AddressBook types because they were working on the Contacts
framework instead. Given that it can and will return nil
, you'll need to treat it like it could be nil
even though it is an implicitly unwrapped type.
Change:
let data = ABPersonCopyImageData(person).takeRetainedValue() as NSData
let imagemContato = UIImage(data: data)
to:
let imagemContato: UIImage?
if let data = ABPersonCopyImageData(person)?.takeRetainedValue() as? NSData {
imagemContato = UIImage(data: data)
}
else {
imagemContato = nil
}
Note: Later on in your code you force unwrap imagemContato
when you create your Contato
instance. You will have to handle the case where it is a nil
value or your program will potentially crash when you do this.
Upvotes: 4