I'm trying to get a list of all names and phone numbers in my app with Swift. It runs perfectly and I see no errors with a standard debug build however when I pushed to the app store and use the release build, the app always crashes when getting the contacts from the address book. I checked that the debug version requests the contacts before trying to actually access them so I don't see anything glaringly wrong.
My code to load contacts is below:
func getAllContacts() {
var errorRef: Unmanaged<CFError>? = nil
var addressBookRef = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, { success, error in
if (success) {
self.loadContacts()
}
else {
var alertView = UIAlertView(title: "Error", message:"Please allow Favour to access to your contacts", delegate:nil, cancelButtonTitle: "OK")
alertView.show()
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized) {
self.loadContacts()
}
else {
var alertView = UIAlertView(title: "Error", message:"Please allow Favour to access to your contacts", delegate:nil, cancelButtonTitle: "OK")
alertView.show()
}
}
func loadContacts() {
var errorRef: Unmanaged<CFError>?
var addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
for record:ABRecordRef in contactList {
var contactPerson: ABRecordRef = record
if(ABRecordCopyCompositeName(contactPerson)? == nil) {
continue
}
var contactName: String = ABRecordCopyCompositeName(contactPerson).takeRetainedValue() as NSString
let phoneProperty: ABMultiValueRef = ABRecordCopyValue(record, kABPersonPhoneProperty).takeRetainedValue() as ABMultiValueRef
if (ABMultiValueGetCount(phoneProperty) > 0) {
let allPhones : NSArray = ABMultiValueCopyArrayOfAllValues(phoneProperty).takeUnretainedValue() as NSArray
for phone in allPhones {
let phoneString = phone as String
var newDictionary = NSMutableDictionary()
newDictionary["name"] = contactName.lowercaseString
newDictionary["phone"] = phoneString
contacts.addObject(newDictionary)
}
}
}
contacts = filterInvites(contacts)
contacts = NSMutableArray(array: (contacts as Array).sorted {($0["name"] as String) < ($1["name"] as String)})
tableView.reloadData()
}
This is the symbolized stack trace from the release build from the App Store
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 Favour
0x000e2f48 reabstraction thunk helper from
@callee_owned (@owned Swift.AnyObject, @owned Swift.AnyObject) -> (@unowned Swift.Bool) to @callee_owned (@in Swift.AnyObject, @in Swift.AnyObject) -> (@unowned Swift.Bool) with unmangled suffix "_constprop0" (DetailViewController.swift:285)
1 Favour 0x000e5b1c specialization <Swift.UnsafeMutableBufferPointer<Swift.AnyObject> with Swift.UnsafeMutableBufferPointer<Swift.AnyObject> : Swift.MutableCollectionType, Swift.UnsafeBufferPointerGenerator<Swift.AnyObject> with Swift.UnsafeBufferPointerGenerator<Swift.AnyObject> : Swift.GeneratorType, Swift.AnyObject, Swift.Int with Swift.Int : Swift.RandomAccessIndexType, Swift.Int with Swift.Int : Swift._SignedIntegerType, Swift.Int with Swift.Int : Swift._BuiltinIntegerLiteralConvertible, Swift.Int with Swift.Int : Swift.SignedNumberType, Swift.Int with Swift.Int : Swift._BuiltinIntegerLiteralConvertible, Swift.Int, Swift.AnyObject> of Swift._introSortImpl <A : Swift.MutableCollectionType>(inout A, Swift.Range<A.Index>, inout (A.Generator.Element, A.Generator.Element) -> Swift.Bool, Swift.Int) -> () (DetailViewController.swift:0)
2 Favour 0x000e4e44 specialization <Swift.AnyObject> of Swift.Array.sort <A>(inout [A])((A, A) -> Swift.Bool) -> () (DetailViewController.swift:0)
3 Favour 0x000e8a34 Favour.InviteViewController.loadContacts (Favour.InviteViewController)() -> () (InviteViewController.swift:0)
4 Favour 0x000e7960 @objc Favour.InviteViewController.viewDidLoad (Favour.InviteViewController)() -> () (InviteViewController.swift:74)
...
Does anyone have any idea why it's crashing each time it's trying to load contacts? I can't reproduce it in debug so I'm stumped on this one.