前言
關於emoji,有的同學會很奇怪,為什麼要特意寫這個,原生的本來不就支持了emoji輸入以及顯示嗎?的確,原生的控件都支持emoji的顯示以及輸入。但是有的需求一旦進入了開發階段,你就會發現並不是那麼簡單的一件事情。
Server端:
由於server一開始並不支持emoji,現在你post含有emoji的數據到server,server會出現異常,主要是server的mysql開始的時候沒有定義4位的字段,varchar都是3位的(普通的字符串或者表情都是占位3個字節,所以utf8足夠用了,但是移動端的表情符號占位是4個字節,普通的utf8就不夠用了,為了應對無線互聯網的機遇和挑戰、避免 emoji 表情符號帶來的問題、涉及無線相關的 MySQL 數據庫建議都提前采用 utf8mb4 字符集,這必須要作為移動互聯網行業的一個技術選型的要點)。
Android端:
大家都知道,Android和iOS的表情顯示是不一樣的(Android的更萌,不信去試試),據說Android N的推出使Android的emoji更加像iOS的了。圖不同編碼相同倒不是什麼問題,致命的是我們需要做得和微信那樣,emoji表情保持一致性,而且Android裡面的輸入法(例如搜狗)鍵盤顯示的是iOS樣式的(emoji最原始樣式),想一下如果用戶輸入的和看到的是不一樣的會是什麼樣的體驗?所以我們這裡必須拿emoji出來處理!而且和iOS一樣需要做過濾處理!這裡的過濾處理主要是過濾掉iOS8.3推出的膚色。但是本文提到的Android庫裡面包含了膚色,所以如果Android需要顯示膚色的話,可以不用過濾,對了,就算你可以顯示帶膚色的emoji,你是輸入不了的,因為Android的輸入法不支持輸入帶膚色的emoji。更多處理請看下面。
iOS端:
別以為iOS端自帶了emoji就輕松,因為需要做和server端,Android的一致性,我們這裡需要將emoji轉化為共用的字符(下文會知道他們是以兩個“:”來定義的例如 :emoji:),除開兼容,我們還要做emoji的過濾!emoji的列表不是一成不變的!在不同的版本蘋果都會推出新的emoji,也就是說emoji是動態的!參考微信朋友圈的實現我們就知道,在一些低版本的設備中不支持高版本的emoji的話微信會直接過濾掉!所以我們這裡也需要做過濾處理!更多處理請看下面。
走過的彎路
參考文獻:iOS & Android:
解決方案:
https://github.com/arvida/emoji-cheat-sheet.com/
https://github.com/quxionglie/emoji-convertor
http://blog.csdn.net/qdkfriend/article/details/7576524
http://www.cnblogs.com/YungMing/p/5080437.html
emoji過濾(用於缺失定義的emoji): http://www.pigg.co/emoji-filter.html
iOS:
http://jeason.gitcafe.io/blog/iOS+Anroid+Emoji/
http://cenalulu.github.io/linux/character-encoding/
emoji編碼范圍:http://blog.csdn.net/liujinlongxa/article/details/44207003
ANDROID:
https://github.com/rockerhieu/emojicon
SERVER:
升級數據庫:https://segmentfault.com/a/1190000000616820
用於前端網頁顯示emoji:https://github.com/pepibumur/emojize
EMOJI列表:
http://apps.timwhitlock.info/emoji/tables/unicode
http://www.emoji-cheat-sheet.com/
https://en.wikipedia.org/wiki/Emoji
http://punchdrunker.github.io/iOSEmoji/table_html/index.html
工具庫:(GITHUB上STAR最多的)
iOS:
https://github.com/valeriomazzeo/NSString-Emoji
https://github.com/diy/NSStringEmojize/
ANDROID:
https://github.com/rockerhieu/emojicon
MAC OS X 查看所有EMOJI圖片的方法:
快捷鍵:control + command + 空格
彈出如下圖:
點擊左上角設置按鈕–>自定義列表—>勾選Unicode—>點擊完成。
就可以看到完整emoji列表和對應的Unicode碼或者UTF-8碼了。
遇到的問題:iOS端從iOS8.3開始出現的emoji膚色
最終的解決方案
Android:
使用工具:https://github.com/rockerhieu/emojicon
安卓的同學比較懶,沒有寫文字的習慣。故這裡我僅貼出工具。
iOS:
使用工具庫:https://github.com/valeriomazzeo/NSString-Emoji
注意:
這個工具裡面的emoji字符表不全,需要自己新增一些進去。
這個工具裡面沒有iOS8.3開始Apple新增的emoji膚色選擇!
沒有使用另外一個cheat-emoji官方工具的原因是官方工具只是將“:test:”等字符的轉化為emoji,但是卻缺少了將emoji反轉成“:test:”的方法!!。想想也是醉了!
我這裡給出膚色對應的編碼:
//by Vbon haha //here is emoji color unicode sinces iOS8.3 //default is not containt color unicode which look like yellow color sinces iOS8.3 //Before iOS8.3 emoji is no color unicode containt and look like white color. @"??": @":skinColor1:",//white --> Unicode: U+1F3FB @"??": @":skinColor2:",//white&littleBrown --> Unicode: U+1F3FC @"??": @":skinColor3:",//white&deepBrown --> Unicode: U+1F3FD @"??": @":skinColor4:",//brown --> Unicode: U+1F3FE @"??": @":skinColor5:" //black --> Unicode: U+1F3FF
注意一點:emoji的不斷新增!
iOS&Android的同學注意了!
由於emoji會不斷新增,也就是說emoji的Unicode范圍會一直增大!所以需要做一下處理,對於不在自己代碼定義的范圍內的emoji需要過濾掉!例子:微信朋友圈。
小道消息稱Unicode協會將會在明年新增多150個emoji,具體時間還沒定。新增表情對於大家的使用時很爽!(例如iOS9後多了個中指的表情)。但是對於我們程序本身來說就意味著必須要做emoji字庫和對應的key不全的問題的處理!就算以後他新增1000個我也無所謂了!因為我是按照微信的做法(直接忽略沒有的emoji,不信你試試在iOS端發????這個emoji,去Android設備看看,你就知道了,微信是直接過濾掉的!)。下面我直接點,貼代碼,大家直接拿去用。
注意:這裡的代碼是結合上面的工具來用的。
Android:
工具:https://github.com/rockerhieu/emojicon
修改工具裡面的編碼:
安卓的同學需要特別注意兩點:
這個emoji庫是通過不斷對比map裡面的數據來查詢的,會導致在列表中的多emoji時滾動會很卡。解決辦法:在得到列表json數據的時候,在映射的時候轉碼成emoji,並將該emoji直接放入實體。這樣就避免了滾動list的時候轉碼帶來的卡頓!
在輸入emoji的地方(發表內容),連續輸入多個emoji會卡頓甚至卡死,原因同上,因為這個庫是對比查找的,默認的算法是假如有1000個emoji,那麼就1個emoji的key對比1000次,而輸入的時候由於每次輸入都進行了轉碼,所以輸入一個emoji就要對整段text進行emoji對比。性能嚴重下滑!解決辦法是改變自己的算法,只轉碼新輸入的那個字符。
總的來說就是特殊場景特殊處理,看自己的解決問題的能力了!
iOS:
工具:https://github.com/valeriomazzeo/NSString-Emoji
修改工具裡面的編碼:
需要注意的幾種情況:
上傳字符串前需要將字符串使用工具轉碼。
用戶輸入字符串的時候看情況是否需要轉碼。
如果有字數限制的!注意emoji轉碼帶來的字數問題喲!
安卓的同學注意了!上面推薦的工具是十分強大的!裡面包括了iOS的膚色emoji。需要和iOS端溝通處理。例如我這裡用skinColor1-5來區分除了默認顏色(白種人)的之外的5中顏色。安卓也是需要定義這幾種編碼的!用於過濾或者顯示不同膚色!
(更新:2016.5.12)
測試今天發來了bug,說是有的字符沒過濾掉。我看了一下的確,在iOS9.3開源的代碼中沒有添加進去一些新的emoji。而且值得注意的是:新增的emoji中竟然出現了新的[emoji語法]!!!新增了同性之間的emoji和家庭的emoji有著不同的語法!一個emoji可能有很多個編碼。
例如:“????????????” 這個emoji表示的是女女之間的同志關系。
你會發些這一類emoji竟然連控制台也打印不出來!(我的系統是最新的10.11.4)。
打開emoji列表,我們可以看到他的編碼語法。
總共由6個4字節的編碼組成!比以前的最多3個4字節編碼翻了一倍!
細心的同學可以在上面控制台的圖片裡面發現一些端倪,上面6個4字節組成的實際上可以用已經有的emoji進行翻譯!像“????????????”翻譯過來就是:woman::heart::woman:,看是不是通俗易懂?至於中間的“?”號我們可以看回emoji列表裡面的字節是什麼,可以知道的是“U+200D”這樣的東西。這樣就好辦了,我們可以將它轉換成“U0000200D”,那樣程序就知道了。由於安卓沒有這樣新增的圖片我們只好過濾掉這樣的東西了。在文件中新增key-value如下:
這樣就可以完美過濾了。
我在新增iOS9.3 emoji的過程中發現文件中的emoji國旗沒有多少支持。
對比系統emoji列表可以在文件中新增進去。
這樣就可以將app的emoji支持到最新的iOS9.3了。
為了大家方便我將文件開源到這裡:https://github.com/vbonluk/iOS_Emoji
文件隨著系統升級及時更新,歡迎star。謝謝
Last:
本以為emoji是個很簡單的東西。沒想到真正弄起來的時候需要考慮的東西還是有點多的!server端,Android端,iOS端。走過的彎路遠不止上面列出的鏈接。上面的鏈接只是找到了比較有用的給大家參考。 文章是後來才寫的,中間一些細節可能忘記了。