如何使服務(wù)器兼容Emoji表情符號(hào)的幾種辦法

我們都知道 用戶(hù)使用移動(dòng)設(shè)備發(fā)表評(píng)論或昵稱(chēng)時(shí)會(huì)輸入一些emoji表情,服務(wù)器對(duì)emoji表情直接保存不兼容, 如果客戶(hù)端直接把表情符號(hào)傳給服務(wù)端保存的話(huà), 會(huì)得到一個(gè)保存失敗的錯(cuò)誤, 一般原因是數(shù)據(jù)庫(kù)使用的是mysql utf8字符集存儲(chǔ)的。utf8最大支持3個(gè)字節(jié)的unicode,而emoji表情和一些特殊符號(hào)需要4個(gè)字節(jié)才能存儲(chǔ)。因此導(dǎo)致用戶(hù)輸入的emoji表情時(shí)存儲(chǔ)失敗。 那如何解決這個(gè)問(wèn)題呢,下面列出幾種解決的辦法:

辦法一:

  • 修改數(shù)據(jù)庫(kù)字符集編碼,通過(guò)把原來(lái)的utf8編碼修改為utf8mb4可以完美解決問(wèn)題,操作步驟如下:
    1. 修改mysql服務(wù)器配置文件中的 character_set_database=utf8mb4 和 character_set_server=utf8mb4,可以是mysql支持utf8mb4編碼。

    2. 在應(yīng)用中連接mysql服務(wù)器時(shí)指定字符集為utf8mb4可以 保證讀取和寫(xiě)入的數(shù)據(jù)是utf8mb4的編碼,從而達(dá)到客戶(hù)端和服務(wù)器端一直。在連接時(shí)指定字符集將影響到 character_set_client 和character_set_connection 兩個(gè)參數(shù)為utf8mb4。

    3. 修改現(xiàn)有的數(shù)據(jù)庫(kù)表字符集,如下


      修改前
修改為
修改后
  1. 然后修改表中字段的字符集為utf8mb4,不推薦在一張表中使用多種字符集。

utf8mb4的優(yōu)勢(shì)

1、utf8mb4是今后的趨勢(shì)
2、utf8mb4是utf8的超集,兼容utf8并且可以支持emoji表情存儲(chǔ)

utf8mb4的缺點(diǎn)

由于utf8mb4采用4個(gè)字節(jié)存儲(chǔ)數(shù)據(jù),而utf8最多使用3個(gè)字節(jié)存儲(chǔ)數(shù)據(jù),所以使用utf8mb4需要占用更大的存儲(chǔ)空間

風(fēng)險(xiǎn)點(diǎn)

1、在一張表里面混用utf8字符集和utf8mb4字符集在進(jìn)行 連接 查詢(xún)時(shí)會(huì)發(fā)生類(lèi)型的隱式轉(zhuǎn)換,導(dǎo)致索引失效

規(guī)避風(fēng)險(xiǎn)

1、在同一個(gè)表中使用相同的字符集編碼,禁止混用不同字符集
2、先在測(cè)試環(huán)境實(shí)施改造,觀(guān)察運(yùn)行情況
3、做好數(shù)據(jù)的備份工作

效果演示

修改數(shù)據(jù)庫(kù)字符集編碼效果演示

辦法二:

  • 在客戶(hù)端輸入表情的時(shí)候直接過(guò)濾掉那些表情,只要不過(guò)濾掉不傳給服務(wù)器, 就不會(huì)存在保存失敗的情況; 當(dāng)然這個(gè)辦法沒(méi)有從根本上解決保存的問(wèn)題, 如果你的需求需要保存表情, 自然這個(gè)方法不滿(mǎn)足要求;

注意:保持嚴(yán)格遵守不觸碰用戶(hù)數(shù)據(jù)的原則,如果能盡量考慮用戶(hù)體驗(yàn)的前提下,該方案慎重考慮

  • 這里是邊輸入邊用正則表達(dá)式去過(guò)濾表情, 可以在輸入文字的代理方法里面加做過(guò)濾的邏輯;
#pragma mark - <UITextViewDelegate>

- (void)textViewDidChange:(UITextView *)textView
{
    NSLog(@"沒(méi)有過(guò)濾前輸入的字符串===%@",textView.text);
    NSString *filterString = [self disableEmoji:textView.text];
    NSLog(@"過(guò)濾Emoji表情后的字符串===%@",filterString);
    textView.text = filterString;
}

/**
 *  正則過(guò)濾表情
 */
- (NSString *)disableEmoji:(NSString *)text
{
    if (!text.length) return text;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]" options:NSRegularExpressionCaseInsensitive error:nil];
    NSString *modifiedString = [regex stringByReplacingMatchesInString:text
                                                               options:0
                                                                 range:NSMakeRange(0, [text length])
                                                          withTemplate:@""];
    return modifiedString;
}

辦法三:

  • 第三種辦法使用base64編碼解決,此可以聯(lián)想到我們?cè)谡?qǐng)求有中文鏈接的網(wǎng)址時(shí)會(huì)請(qǐng)求失敗, 正常的處理是先把含有中文的網(wǎng)址進(jìn)行編碼后在請(qǐng)求就會(huì)成功, 因此,我們保存表情時(shí)也可以你用這種辦法;

使用:這里在你把轉(zhuǎn)碼后的操作發(fā)給服務(wù)器后, 需要做的一個(gè)額外操作就是, 你再?gòu)姆?wù)器取回來(lái)顯示時(shí), 需要反轉(zhuǎn)一下之前的編碼才能正常顯示出表情符號(hào), 否則就是一堆亂碼, 如: 123456%F0%9F%98%83%E2%98%BA%F0%9F%98%9A%F0%9F%98%99%F0%9F%99%8412 ;

  1. 把含有表情的字符串進(jìn)行編碼后再發(fā)送給服務(wù)端:
NSString *inputText = [self.editTextView.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  • 注意: 這里如果你輸入的字符串中已經(jīng)含有一些已轉(zhuǎn)義的特殊符號(hào): % @ $等時(shí), 上面的方法就不會(huì)再對(duì)這些特殊的進(jìn)行轉(zhuǎn)碼, 可以使用下面的方法
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlString, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL, kCFStringEncodingUTF8);
  1. 對(duì)從服務(wù)器獲取回來(lái)含有表情的字符串進(jìn)行反轉(zhuǎn)后顯示在頁(yè)面上:
NSString *showText = [serverString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  1. 把編碼的字符串反轉(zhuǎn)之后的顯示效果圖:
反轉(zhuǎn)后顯示的效果.png

注意點(diǎn):
1、如果是針對(duì)一些用戶(hù)輸入的評(píng)論內(nèi)容,可能需要進(jìn)行人工審核,需要看到原始的數(shù)據(jù),編碼后會(huì)無(wú)法清晰的查看問(wèn)題;
2、管理后臺(tái)需要對(duì)評(píng)論內(nèi)容,用戶(hù)昵稱(chēng)等內(nèi)容進(jìn)行模糊匹配,編碼后無(wú)法實(shí)現(xiàn)搜索;
3、評(píng)論內(nèi)容從接收到最終在站點(diǎn)顯示需要經(jīng)過(guò)多個(gè)流程,頻繁編碼及解碼會(huì)損失一些性能;

辦法四:

  • 第三種辦法就是把輸入的表情轉(zhuǎn)成NSData的二進(jìn)制數(shù)據(jù)傳給服務(wù)器;
NSData *data =[inputText dataUsingEncoding:NSUTF8StringEncoding];

不過(guò)這種辦法客戶(hù)端和服務(wù)端兩邊處理都比較麻煩, 不建議使用這種方法;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容