Search code examples
androidiosnsattributedstringutf-16emoji

Emoji doesn't show in NSAttributedString when typed using iOS keyboard, does when typed on Android


I'm making a messenging application and when I send an emoji from the Android side, it shows fine on the iOS side, yet the iOS side cannot (it seems) display emojis from iOS's own keyboard!

The label in which I am showing the emoji uses attributed text and the text comes from HTML. The following code is used to generate the NSAttributedString

var msg = getTextForDisplay()//Essentially gets the plain text
msg = "<span style=\"font-family: Helvetica; font-size:14pt;\">" + msg + "</span>"
if let data = msg.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false){
    let attributed = try? NSAttributedString(data: data, options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType ], documentAttributes: nil)
    return attributed
}

Even stranger, when I send the emoji from iOS, although it doesn't show in the label as described above, it does show on the Android side perfectly fine. On the iOS side, in the label, it shows what appears to be jibberish (unicode chasracters perhaps?)

eg: enter image description here

I am absolutely sure the error is with the displaying of the emoji, because when printed to console, I see real emoji and also when saved to the device storage and later read on a Mac, it is real emoji. But when the emoji is loaded into the attributed label, it shows jibberish

Any help is appreciated. I understand the issue is something to do with encoding I'm just not sure what exactly the problem is and how to fix it


Solution

  • We verified in the comments that the source string is okay. There's just one single parameter to change! Swift usually uses UTF-16 for strings. You're losing information processing it as UTF-8.

    Change:

    msg.dataUsingEncoding(NSUTF8StringEncoding

    To:

    msg.dataUsingEncoding(NSUTF16StringEncoding

    For swift 5: use this msg.data(using: String.Encoding.utf16, allowLossyConversion: false)