0

I'm having an Array of CNContact. I need them to be sorted by name to have tableView sections sorted by name.

var sortedContactsDictionary: [String: [CNContact]] = [:]
var alphabeticSortedContacts: [CNContact] = []

func setAlphabeticOrderOfContacts(_ contact: CNContact) {
    var name = ""
    if contact.familyName != "" {
        name = contact.familyName.lowercaseFirst
    } else {
        name = contact.givenName.lowercaseFirst
    }

    let currentLetter = name.characters.first

    if self.lastProcessedLetter == nil || self.lastProcessedLetter == currentLetter {
        self.alphabeticSortedContacts.append(contact)
    } else {
        self.alphabeticSortedContacts.removeAll()
        self.alphabeticSortedContacts.append(contact)
    }

    self.lastProcessedLetter = currentLetter

    if let letter = currentLetter {
        self.sortedContactsDictionary["\(letter)"] = self.alphabeticSortedContacts
    }
}

But my problem is, that some of the familyName values contain special character like ( as the first character.

Since the [CNContact] is already sorted, the special character names are sorted where I don't need them and if I do something like this:

let specialCharactersRemoved = name.replacingOccurrences(of: "(", with: "")
let currentLetter = specialCharactersRemoved.characters.first

My sections aren't in order anymore. I have the "second letter" of the name (after () for example as first letter of the sections instead of the desired A and if I sort the dictionary again, I have multiple times a section with (f.e.) the key S.

What am I missing or what would be a better approach to sort the [CNContact] into [String: [CNContact]]? Help is very appreciated.

David Seek
  • 16,783
  • 19
  • 105
  • 136
  • 1
    What do you mean with family name starts with "(" ? – Leo Dabus Apr 27 '17 at 14:34
  • For example one of my contacts works at Andorfine Records and in one of my old phones his family name was (Andorfine Records) (and still is now). I know, that that is not common. But I want to avoid those issues form the very beginning. – David Seek Apr 27 '17 at 14:42
  • You shouldn't deal with it. It is the user responsibility to proper use the contacts app. – Leo Dabus Apr 27 '17 at 14:44
  • What if the user adds that character in purpose to make it list ahead of the rest? – Leo Dabus Apr 27 '17 at 14:45
  • Apple's contacts works the same. (Andorfine Records) is sorted into the A of the contact list. – David Seek Apr 27 '17 at 14:48
  • Take a look at http://stackoverflow.com/questions/34851296/how-to-sort-contacts-using-contacts-with-swift – Mike Taverne Apr 27 '17 at 15:54

1 Answers1

0

I have re-coded my function and now I append on existing keys and create a new Array on missing keys.

func setAlphabeticOrderOfContacts(_ contact: CNContact) {
    if let letter = self.getCurrentLetter(contact) {
        let keyExists = self.sortedContactsDictionary["\(letter)"] != nil

        if keyExists {
            var arrayOfContacts = self.sortedContactsDictionary["\(letter)"]
            arrayOfContacts?.append(contact)
            self.sortedContactsDictionary["\(letter)"] = arrayOfContacts
        } else {
            var arrayOfContacts = [CNContact]()
            arrayOfContacts.append(contact)
            self.sortedContactsDictionary["\(letter)"] = arrayOfContacts
        }
    }
}

func getCurrentLetter(_ contact: CNContact) -> Character? {
    var name = String()
    if contact.familyName != "" {
        name = contact.familyName
    } else {
        name = contact.givenName
    }

    let specialCharactersRemoved = name.replacingOccurrences(of: "(", with: "").lowercaseFirst
    let currentLetter = specialCharactersRemoved.characters.first
    guard let letter = currentLetter else { return nil }
    return letter
}
David Seek
  • 16,783
  • 19
  • 105
  • 136