There is some problem with AddressBook which I can't reproduce, code works on my iPhone and iPad, this happens on client phone and result in app crash. As far as I can see from Crashlytics problem should be in following line:
let data = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail).takeRetainedValue()
Here is complete code for reading address book:
var err : Unmanaged<CFError>? = nil
let addressBookRef : ABAddressBook? = ABAddressBookCreateWithOptions(nil, &err).takeRetainedValue()
if addressBookRef == nil {
print(err)
return
}
let contacts = ABAddressBookCopyArrayOfAllPeople(addressBookRef).takeRetainedValue() as NSArray as [ABRecord]
for contact in contacts {
let firstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty)?.takeRetainedValue() as? String
let lastName = ABRecordCopyValue(contact, kABPersonLastNameProperty)?.takeRetainedValue() as? String
var image: UIImage?
if ABPersonHasImageData(contact) {
let data = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail).takeRetainedValue()
if let img = UIImage(data: data) {
image = img
}
}
…
}
Do you have any suggestions what could happen on clients phone so I can reproduce this error? Is it possible that some contact is corrupt? How should I handle this?
I've seen this post Get iOS contact image with ABPersonCopyImageData that ABPersonCopyImageData could return nil, I tried to handle that but app is still crashing.
check all for nil. if ABPersonCopyImageDataWithFormat returns nil, you call takeRetainedValue on nil. and then use it nil to create image too
guard let CFData = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail) else {
print("no cfdata")
return
}
if let data = CFData.takeRetainedValue {
if let img = UIImage(data: data) {
image = img
}
}