1

In Objective-C, I'd sort an array of people as follows:

CFArraySortValues(mutablePeople,
                  CFRangeMake(0, CFArrayGetCount(mutablePeople)),
                  (CFComparatorFunction) ABPersonComparePeopleByName,
                  kABPersonSortByFirstName)

I'm struggling to figure out how to do the same in Swift. The following:

let ctx = UnsafeMutablePointer<Void>.alloc(kABPersonSortByFirstName)

CFArraySortValues(mutablePeople, 
                  CFRangeMake(0, CFArrayGetCount(mutablePeople)), 
                  ABPersonComparePeopleByName, 
                  ctx)

Gives compilation error:

Cannot invoke 'CFArraySortValues' with an argument list of type '(CFMutableArray!, CFRange, (ABRecord!, ABRecord!, ABPersonSortOrdering) -> CFComparisonResult, UnsafeMutablePointer)'

The problem looks to be with the ABPersonComparePeopleByName which would be cast to a CFComparatorFunction in Objective-C.

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160

1 Answers1

5

Here are two alternatives that avoid CFArraySortValues altogether:

  1. Use ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering to retrieve the contacts already sorted:

    let people = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, ABPersonSortOrdering(kABPersonSortByFirstName)).takeRetainedValue() as [ABRecordRef]
    

    If you use nil for the source, it uses all sources (though that behavior is not documented).

  2. Alternatively, if you have a Swift array of ABRecordRef, you can then use the standard Swift sort routine, using ABPersonComparePeopleByName for the comparison:

    var people = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue() as [ABRecordRef]
    people.sort() { ABPersonComparePeopleByName($0, $1, ABPersonSortOrdering(kABPersonSortByFirstName)) != .CompareGreaterThan }
    

Both of these approaches return a Swift Array<ABRecordRef>, which is a nice native Swift collection. For example, to print the list of the names:

for record in people {
    let name = ABRecordCopyCompositeName(record).takeRetainedValue()
    println(name)
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044