Swift ABAddressBook crashes in production app but not in debug

391 views Asked by At

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.

0

There are 0 answers