3

In Turkish, there are two i

  • Dotless: ı, I
  • Dotted: i, İ

PROBLEM: Every time I uppercase an i, I get an I.

I want to get an İ (only in Turkish) when I uppercase an i, and an I when I uppercase an ı.

I have a function to do it

@objc public static func uppercaseTurkishString(_ string: String) -> String {
    return String(string.map { (char) -> Character in
        if char == "i" {
            return "İ"
        } else {
            return Character(String(char).uppercased())
        }
    })
}

But I have to check if the language is Turkish every time I use it, and doing it for every single string in the app is a very hard job.

Is there an easier way to do it?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Sergio
  • 1,610
  • 14
  • 28
  • 2
    There is a strange difference, if you do `let turckishI = "Dotless: ı, I Dotted: i, İ"`, then `turckishI.localizedLowercase`, you'll see that the rendered lowercase i (the last one) is different from yours. But there is also locale uppercase. – Larme Sep 19 '18 at 09:20
  • 2
    Related: [Uppercase All String According to Locale - Swift](https://stackoverflow.com/questions/32715323/uppercase-all-string-according-to-locale-swift) – Martin R Sep 19 '18 at 09:25

2 Answers2

7

The problem lies in the fact that the uppercased() function doesn't care about Locales and the small dotted i looks like the normal English i. You should use localizedUppercase, which will use the Turkish Locale for Turkish users (or uppercased(with: Locale(identifier: "tr_TR"), in case you want this to be done for all users of your app regardless of their locale settings, but I wouldn't recommend that).

Moreover, there's no need to do the upper casing character-by-character, you can simply do it on the full String.

@objc public static func uppercaseTurkishString(_ string: String) -> String {
    return string.localizedUppercase
}
Sabuncu
  • 5,095
  • 5
  • 55
  • 89
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
1

Foundation developers already thought about it, and that's exactly why there is uppercased(with: Locale?):

"i".uppercased(with: Locale(identifier: "tr_TR")) // returns "İ"
"i".uppercased(with: Locale(identifier: "en_US")) // returns "I"
"ı".uppercased(with: Locale(identifier: "tr_TR")) // returns "I"
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
user28434'mstep
  • 6,290
  • 2
  • 20
  • 35