0

I am trying to get the composite name of contacts but when both first and last name of the contact is empty this code crashes. How do i test if the composite name property is nil? Also why is not optional binding working in this case?

let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as NSArray
        for person: ABRecordRef in allPeople {
            var compositeName: String? = ""
            // Crashes on the next line
            if let cName = ABRecordCopyCompositeName(person).takeRetainedValue() as? String {
                compositeName = cName
            } else {
                compositeName = ""
            }
            let phones: ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty).takeRetainedValue()
            for counter in 0..<ABMultiValueGetCount(phones) {
                let phone = ABMultiValueCopyValueAtIndex(phones, counter).takeRetainedValue() as! String
                contactArray.append(nameNumber(name: compositeName!, number: phone))
            }
        }
Ankit Goel
  • 6,257
  • 4
  • 36
  • 48

2 Answers2

0

The following piece of code has worked for me:

let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as NSArray

    for person: ABRecordRef in allPeople {
        var compositeName: String? = ""
        let cName = ABRecordCopyCompositeName(person)
        if cName != nil {
            compositeName = cName.takeRetainedValue() as String
        } else {
            compositeName = ""
        }

        let phones: ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty).takeRetainedValue()
        for counter in 0..<ABMultiValueGetCount(phones) {
            let phone = ABMultiValueCopyValueAtIndex(phones, counter).takeRetainedValue() as! String
            contactArray.append(nameNumber(name: compositeName!, number: phone))
        }
    }
Ankit Goel
  • 6,257
  • 4
  • 36
  • 48
0

I'm working on something similar to you- I liked your solution and tried it alongside mine, and yours parses out nils more elegantly than mine. However, yours seemed to cause duplicates. Removing the second for loop seemed to solve the issue, however I'm now having issues with the phone array. Here's what I have:

func readAllPeopleInAddressBookTwo(addressBook: ABAddressBookRef){
    let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as NSArray

    for person: ABRecordRef in allPeople {
        var compositeName: String? = ""
        let cName = ABRecordCopyCompositeName(person)
        if cName != nil {
            compositeName = cName.takeRetainedValue() as String
        } else {
            compositeName = "Unknown Name"
        }

        let phones: ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty).takeRetainedValue()

            //contactArray.append(nameNumber(name: compositeName!, number: phone))
            peopleNames.append(compositeName!)
            peoplePhones.append(phones as! String)
            print("Composite name = \(compositeName)", terminator: "")
            print("Phone = \(phones)", terminator: "")

        }
}

Also- what type of collection type are you using for contractArray? How is it initialized?

Felker
  • 754
  • 7
  • 11
  • The duplicates are intentional as I wanted to show all phone numbers of the contact. And contactArray is an array containing instances of a struct which stores name and number. – Ankit Goel Oct 09 '15 at 01:58
  • I have made a git repository of the whole code in case that helps you. Check it out here: https://github.com/ankit1ank/SwiftPhoneNumbers – Ankit Goel Oct 09 '15 at 07:38
  • Awesome! Thank you, Ankit! – Felker Oct 09 '15 at 20:29