Search code examples
iosemojiswift4iphone7plus

Emoji not showing in Swift


I am trying to show emojis coming from JSON response. It work fine when we don't have 0️⃣1️⃣3️⃣5️⃣ in below string and does not work with below string.

var titleLabelString = \ud83d\ude0a\ud83d\ude18\u2626\ufe0f 0️⃣1️⃣3️⃣5️⃣ 

Function I am using:

extension String {
    var decodeEmoji: String? {
      let data = self.data(using: String.Encoding.utf8,allowLossyConversion: false);
      let decodedStr = NSString(data: data!, encoding: String.Encoding.nonLossyASCII.rawValue)
      if decodedStr != nil{
        return decodedStr as String?
    }
      return self
}
}

Using it like:

titleLabelString = titleLabelString.decodeEmoji!

What is wrong in this?


Solution

  • The code points you have shown in the comment:

    U+005C U+0075 U+0064 U+0038 U+0033 U+0064 U+005C U+0075 U+0064 U+0065 U+0030 U+0061 U+005C U+0075 U+0064 U+0038 U+0033 U+0064 U+005C U+0075 U+0064 U+0065 U+0031 U+0038 U+005C U+0075 U+0064 U+0038 U+0033 U+0064 U+005C U+0075 U+0064 U+0065 U+0030 U+0032 U+0035 U+FE0F U+20E3 U+0033 U+FE0F U+20E3 U+0031 U+FE0F U+20E3 U+0030 U+FE0F U+20E3
    

    represents a string like this:

    \ud83d\ude0a\ud83d\ude18\ud83d\ude025️⃣3️⃣1️⃣0️⃣

    (Seems you have chosen another string than in your question.)

    As a valid String literal in Swift, it becomes:

    "\\ud83d\\ude0a\\ud83d\\ude18\\ud83d\\ude02\u{0035}\u{FE0F}\u{20E3}\u{0033}\u{FE0F}\u{20E3}\u{0031}\u{FE0F}\u{20E3}\u{0030}\u{FE0F}\u{20E3}"
    

    Anyway, you have a string where non-BMP characters are represented with JSON-string like escaped sequence. And your decodeEmoji cannot convert them into valid characters.

    You can forcefully convert such strings:

    extension String {
        var jsonStringRedecoded: String? {
            let data = ("\""+self+"\"").data(using: .utf8)!
            let result = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as! String
            return result
        }
    }
    

    (If your string may contain some more meta-characters, you may need to modify this code.)

    var titleLabelString = "\\ud83d\\ude0a\\ud83d\\ude18\\ud83d\\ude02\u{0035}\u{FE0F}\u{20E3}\u{0033}\u{FE0F}\u{20E3}\u{0031}\u{FE0F}\u{20E3}\u{0030}\u{FE0F}\u{20E3}"
    
    print(titleLabelString.jsonStringRedecoded) //->😊😘😂5️⃣3️⃣1️⃣0️⃣
    

    But generally, usual JSON decoder can decode non-BMP characters (including emojis). So, if you get this sort of string from JSON response,

    • Your server may be sending invalid JSON response

    or

    • You may be using a broken JSON decoder

    You should better check these things before using forced re-decoding.