0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • are you using system font, or some custom one? – Milan Nosáľ Oct 27 '17 at 07:05
  • Your first line of code is not valid as Swift, so it is not clear what you are suffering for. Can you show us the actual contents of the original string? `print(titleLabelString.unicodeScalars.map{uc in String(format:"U+%04X", uc.value)}.joined(separator: " "))` – OOPer Oct 27 '17 at 07:13
  • @OOPer: The actual string is " \ud83d\ude0a\ud83d\ude18\u2626\ufe0f 0️⃣1️⃣3️⃣5️⃣ " , it prints the string as it is with out converting the encoded emojis. – Daksh Agarwal Oct 27 '17 at 10:07
  • @MilanNosáľ: I am using Font-Awesome font family. – Daksh Agarwal Oct 27 '17 at 10:09
  • `" \ud83d\ude0a\ud83d\ude18\u2626\ufe0f 0️⃣1️⃣3️⃣5️⃣ "` is not a valid String literal in Swift. Please show exact output generated with my code above. – OOPer Oct 27 '17 at 10:10
  • @OOPer: Below Is the output: 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 – Daksh Agarwal Oct 27 '17 at 10:51

1 Answers1

3

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.

Community
  • 1
  • 1
OOPer
  • 47,149
  • 6
  • 107
  • 142