Emoji не отображается в Swift

Я пытаюсь показать смайлики из ответа JSON. Он отлично работает, когда у нас нет 0️⃣1️⃣3️⃣5️⃣ в строке ниже и не работает с строкой ниже.

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

Функция, которую я использую:

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
}
}

Используя это как:

titleLabelString = titleLabelString.decodeEmoji!

Что в этом плохого?

1 ответ

Решение

Кодовые точки, которые вы указали в комментарии:

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

представляет строку как это:

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

(Кажется, вы выбрали другую строку, чем в вашем вопросе.)

Как действительный строковый литерал в Swift, он становится:

"\\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}"

В любом случае, у вас есть строка, где не-BMP символы представлены JSON-строкой, как экранированная последовательность. И ваш decodeEmoji не может преобразовать их в действительные символы.

Вы можете принудительно конвертировать такие строки:

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

(Если ваша строка может содержать еще несколько метасимволов, вам может потребоваться изменить этот код.)

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️⃣

Но, как правило, обычный JSON-декодер может декодировать не-BMP символы (включая эмодзи). Так что, если вы получите такую ​​строку из ответа JSON,

  • Ваш сервер может отправлять неверный ответ JSON

или же

  • Возможно, вы используете сломанный JSON-декодер

Вы должны лучше проверить эти вещи перед использованием принудительного перекодирования.

Другие вопросы по тегам