はじめに
つい最近、
「APIから受け取った絵文字のHTMLエンティティUnicode(10進数)をiOSででてくるいつもの絵文字として出力する。」
ということをやり、めちゃめちゃ悩んで色んな人に教えてもらって解決ました。
その内容をメモとして残しておきます。
ちなみにサーバー側からもらう内容は以下、
☎
表示したいのは以下の絵文字とします。
☎️
出力方法
解説は次の章から書きますが、まずやり方だけ先に書きます。
// サーバーから受け取ったUnicode
let responseCodeString = "☎"
// おまじない、後ほど解説します。
let emojiVariationSequence = 65039
var scalarView = String.UnicodeScalarView()
// 記号の部分はいらないので適当に置き換える
let codeString = responseCodeString.replacingOccurrences(of: "&#", with: "").replacingOccurrences(of: ";", with: "")
let code = Int(codeString)
scalarView.append(UnicodeScalar(code)!)
scalarView.append(UnicodeScalar(emojiVariationSequence)!)
print(scalarView)
準備(HTML EntitiyをIntのUnicodeに)
"&"などの記号はいらないので削除してしまいましょう。
// サーバーから受け取ったUnicode
let responseCodeString = "☎"
// いらないプレフィックスとサフィックスを削除
let codeString = responseCodeString.replacingOccurrences(of: "&#", with: "").replacingOccurrences(of: ";", with: "")
let code = Int(codeString)
10進数Unicodeを絵文字に変換する
Unicodeから文字列を生成するにはIntのUnicodeを引数に
UnicodeScalarを生成します。
これをUnicodeScalarViewとして生成したインスタンスに
先ほどのUnicodeScalarのインスタンスをappendしてやりprintすると...
// code = 9742
let code = Int(codeString)
let codeScalar = UnicodeScalar(code!)
var scalarView = String.UnicodeScalarView()
scalarView.append(codeScalar!)
print(scalarView)
以下の絵文字が得られます。
☎
iOSのいつもの電話の絵文字のこれ「☎️」を想像してたのに
なにかちがいますよね。
なぜ違うのか
絵文字バリエーション・シーケンスなるものが関係しています。
iPhoneではそれが絵文字の赤電話として表示されてびっくり。というような経験をしたことがある人は、たぶん少なくないと思う。こういうことが起きるのは、「絵文字じゃない文字」と「絵文字」がUnicodeでは同じ符号位置に包摂されていて、どちらが表示されるかはフォント(の優先順位)次第だからだ。
絵文字バリエーション・シーケンスとは何か
http://d.hatena.ne.jp/NAOI/20120802/1343876603
つまり電話の絵文字の情報はあるけど
どの電話の絵文字かは指定されてないので違う文字になってたということみたいです。
絵文字バリエーション・シーケンスを追加する
ここで冒頭のおまじないを使います。
先ほどの電話のUnicodeScalarViewにバリエーションシーケンスをappendしてみましょう。
// バリエーションシーケンス
let emojiVariationSequence = 65039
let evs = UnicodeScalar(emojiVariationSequence)
// code = 9742
let code = Int(codeString)
let codeScalar = UnicodeScalar(code!)
var scalarView = String.UnicodeScalarView()
scalarView.append(codeScalar!)
scalarView.append(evs!)
print(scalarView)
これをprintするとあの電話の絵文字が表示できるようになります。
☎️
おまけ・絵文字のバリエーションシーケンスの調べ方
表示させたい絵文字のバリエーションシケーンスがわからない。
そんなときは以下のやり方でUnicodeが出力できます。
let phone = "☎️"
for scalar in phone.unicodeScalars {
print(scalar.hashValue)
}
結果
9742
65039
役に立つかわかりませんがご参考までに