iOS框架--NSString中的Emoji表情

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS框架--NSString中的Emoji表情相关的知识,希望对你有一定的参考价值。

参考技术A 苹果API文档是这样解释NSString的length方法:返回UTF-16编码单元(码元)的个数。

因此我们猜测NSString底层是使用UTF-16编码存储字符数据的,那何为UTF-16?

通过UTF-16的定义,我们知道英文字母和一般汉字在UTF-16中用两个字节表示,即占一个码元,而一般的Emoji表情用四个字节表示,即占两个码元。所以英文字母和汉字在NSString中的length为1,而一般的Emoji表情在NSString中length为2。

输出

查看表情编码地址: https://apps.timwhitlock.info/unicode/inspect

通过分析,这个复杂表情其实是由四个小表情(两男两女)和三个连接符号组合出来的:

所以,在NSString中length为 4*2 + 3*1 = 11 (UTF-16码元个数)

但是当把NSString转换成UTF-8格式的NSData时,数据是这样存储的:

所以转成NSData后的存储总长度为 4*4 + 3*3 = 25 (字节个数)。

补充:这种组合出来的复杂表情是苹果自己定义的,不属于Unicode编码范围,但每个小表情属于Unicode编码范围,所以将此表情发给安卓端,会被显示成多个连续的小表情。而连接符本身显示出来不占宽度,所以跟没有连接符效果一样。

输出

php过滤文字中的表情字符和mysql服务端对emoji的支持

1.过滤emoji表情的原因

  在我们的项目开发中,emoji表情是个麻烦的东西,即使我们可以能存储,也不一定能完美显示,因为它的更新速度很快:在iOS以外的平台上,例如PC或者android。如果你需要显示emoji,就得准备一大堆emoji图片并使用第三方前端类库才行。即便如此,还是可能因为emoji图片不够全而出现无法显示的情况
在大多数业务场景下,emoji也不是非要不可的。我们可以适当地考虑干掉它,节约各种成本。

 

2.php过滤emoji原理

  Emoji (絵文字,词义来自日语えもじ,e-moji,moji在日语中的含义是字符)是一套起源于日本的12x12像素表情符号,由栗田穣崇(Shigetaka Kurit)创作,最早在日本网络及手机用户中流行。自苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,目前emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。近期,更是有不少网友用emoji图案玩猜字游戏,享受这种表情文化带来的乐趣。

 

关于emoji的发音:很多人第一眼见到emoji便会下意识将其误读作“一磨叽”,其实不然,emoji音译过来大概读作“诶磨叽”,当中“e”的发音颇似字母abc的a的发音。

 

最初日本的三大电信运营商各自有不同的字符定义,分别是DoCoMo、KDDI和Softbank。随着iOS内置了Softbank的版本,emoji在全球范围内风靡(iOS5版本以前)。而Google又自己定义了一套emoji字符。iOS5以后,apple采用了unicode定义的emoji字符(iOS5版本以后)。

 

unicode定义的emoji是四个字符,softbank为3个字符,emoji的四个字符从存储到展示对应没有做过考虑的系统来说,简直就是灾难。

 

3.针对unicode定义的emoji表情过滤

  ①.unicode定义的emoji是四个字符,根据这个原理进行过滤

  

复制代码
// 过滤掉emoji表情
function filter_Emoji($str)
{
    $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            \'/./u\',
            function (array $match) {
                return strlen($match[0]) >= 4 ? \'\' : $match[0];
            },
            $str);

     return $str;
 }
复制代码

 

  

  ②. unicode emoji是4个字节,softbank定义的emoji占用3个字节存储,通过emoji for php ,我们可以把unicode的emoji方式转换为softbank方式,从而实现不修改数据库,就能存储emoji,相对于数据库层面的解决问题的方式,动作要小的多,并且也不会有性能,运维等方面的问题。但是有个不可避免的问题是,Softbank方式已经不再维护,所以新增加的emoji表情,Softbank中都没有,会造成部分emoji表情丢失的情况,对于这种情况不推荐使用。

 

  后续还有一些方法没有亲自实践过,但是给大家提供出来。

  

  1、使用utf8mb4字符集

 

  如果你的mysql版本>=5.5.3,你可以尝试直接将utf8直接升级为utf8mb4字符集
  这种4字节的utf8编码可完美兼容旧的3字节utf8字符集,并且可以直接存储emoji表情,是较好的解决方案之一。
  至于字节增大带来的性能损耗,根据自己的项目,自己估算吧....

 

  2、使用base64编码

 

  如果你因为某些原因无法使用utf8mb4字符集的话,你还可以使用base64来曲线救国
  使用例如base64_encode之类的函数编码过后的emoji可以直接存储在utf8字节集的数据表中,取出时decode一下即可

 

 

1.utf8mb4的最低mysql版本支持版本为5.5.3+,若不是,请升级到较新版本。

mysql版本查看命令请看:查看mysql版本的四种方法;mysql安装步骤请看:Linux中升级Mysql到Mysql最新版本的方法
2.修改database、table和column字符集。参考以下语句:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3.修改mysql配置文件my.cnf(windows为my.ini)

my.cnf一般在etc/mysql/my.cnf位置。找到后请在以下三部分里添加如下内容:

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect=\'SET NAMES utf8mb4\'

4.重启 MySQL Server、检查字符集

1.)重启命令参考:/etc/init.d/mysql restart

2.)输入命令:mysql,进入mysql命令行(如果提示没权限,可以尝试输入mysql -uroot -p你的密码)

3.)在mysql命令行中输入:SHOW VARIABLES WHERE Variable_name LIKE \'character_set_%\' OR Variable_name LIKE \'collation%\';

检查是否如下:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client    | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database  | utf8mb4            |
| character_set_filesystem | binary            |
| character_set_results    | utf8mb4            |
| character_set_server    | utf8mb4            |
| character_set_system    | utf8              |
| collation_connection    | utf8mb4_unicode_ci |
| collation_database      | utf8mb4_unicode_ci |
| collation_server        | utf8mb4_unicode_ci |
+--------------------------+--------------------+
rows in set (0.00 sec)

特别说明下:collation_connection/collation_database/collation_server如果是utf8mb4_general_ci,没有关系。但必须保证character_set_client/character_set_connection/character_set_database/character_set_results/character_set_server为utf8mb4。关于这些字符集配置是干什么用的,有什么区别,请参考:深入Mysql字符集设置

5.修改连接数据字符集设置uft8mb4

\'db\' => [
\'class\' => \'yii\\db\\Connection\',
\'dsn\' => \'mysql:host=192.168.1.130;dbname=\',
\'username\' => \'\',
\'password\' => \'\',
\'charset\' => \'utf8mb4\',
],

以上是关于iOS框架--NSString中的Emoji表情的主要内容,如果未能解决你的问题,请参考以下文章

iOS 输入框如何限制字符长度和emoji

判断字符串中是不是含有emoji表情,并将emoji表情替换成其他字符串

emoji表情处理,emoji表情的编码解码

emoji探寻之路

emoji处理方法汇总

微信公众平台开发(57)Emoji表情符号