I thought I understand Unicode scalars in Swift pretty well, but the dog face emoji proved me wrong.
for code in "🐶".utf16 {
print(code)
}
The UTF-16 codes are 55357 and 56374. In hex, that's d83d and dc36.
Now:
let dog = "\u{d83d}\u{dc36}"
Instead of getting a string with "🐶", I'm getting an error:
Invalid unicode scalar
I tried with UTF-8 codes and it didn't work neither. Not throwing an error, but returning "ð¶" instead of the dog face.
What is wrong here?
The \u{nnnn} escape sequence expects a Unicode scalar value, not the UTF-16 representation (with high and low surrogates):
for code in "🐶".unicodeScalars {
print(String(code.value, radix: 16))
}
// 1f436
let dog = "\u{1F436}"
print(dog) // 🐶
Solutions to reconstruct a string from its UTF-16 representation can be found at Is there a way to create a String from utf16 array in swift?. For example:
let utf16: [UInt16] = [ 0xd83d, 0xdc36 ]
let dog = String(utf16CodeUnits: utf16, count: utf16.count)
print(dog) // 🐶