iOS的emoji表情在数据库不支持UTF-8格式的处理
来源:互联网 发布:知行论坛北交大登录 编辑:程序博客网 时间:2024/04/30 02:15
前言
最近遇到苹果手机自带的emoji表情的处理问题,由于我们的数据库编码是GBK编码,而苹果的键盘自带的emoji表情,苹果系统的编码格式是UTF8编码,所以在把emoji表情存到GBK编码的数据库的就会出现乱码的现象,这事非常坑爹的事情。但是还有更坑的,由于我们的emoji表情不是有我们客户端来处理的,其实要是我们客户端处理的话很简单,就是把emoji表情处理成相应的唯一字符串,然后存进数据库,字符串GBK编码的数据库肯定可以存。然后我们展示的再处理回来就好,完全我们客户端就可以操作。坑爹的就是,我们传的emoji表情是要给html5去展示,这就存在问题了。
1.如何从一段文字提取emoji表情
下面我给出一个方案,我们知道emoji表情本质就是字符串,是字符串就会有长度,而emoji表情的字符串的长度有2,4,7,3等等,未来随着emoji表情的扩充可能说不定一个emoji表情的长度大于10都有可能,所以我们来遍历一段含有emoji表情的字符串的问题,来检查出有没有emoji表情是很不理想的选择,虽然可能for循环遍历也可能弄出来,但这可能需要花费大量的时间和精力去完成,不过所幸的是,苹果给我们用了一个好的遍历的方法
检测表情的输入- (NSString *)stringContainsEmoji:(NSString *)string{ __block BOOL returnValue = NO; __block NSString *tempStr = @""; [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { NSString *tempEmoji = @""; const unichar high = [substring characterAtIndex: 0]; *** Surrogate pair (U+1D000-1F9FF)*** if (0xD800 <= high && high <= 0xDBFF) { const unichar low = [substring characterAtIndex: 1]; const int codepoint = ((high - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; if (0x1D000 <= codepoint && codepoint <= 0x1F9FF){ returnValue = YES; tempEmoji = [self getEmojiToShijinZhi:substring]; } ***Not surrogate pair (U+2100-27BF)*** } else { if (0x2100 <= high && high <= 0x27BF){ returnValue = YES; tempEmoji = [self getEmojiToShijinZhi:substring]; } } if (returnValue == YES) { tempStr = [tempStr stringByAppendingString:tempEmoji]; }else{ tempStr = [tempStr stringByAppendingString:substring]; } returnValue = NO; }]; return tempStr;}
上面的* Surrogate pair (U+1D000-1F9FF)和*Not surrogate pair (U+2100-27BF)应该是说明emoji表情的uinicode编码范围。
我是参考这个简书作者: [iOS]检测字符串中是否包含emoji表情
2.emoji表情转化成实体字符
实体字符就是emoji表情可以不用做任何处理就可以显示出来是不是很方便,但是它有个很大毛病,不是所有的表情都支持的,因为的苹果自带的emoji表情一直在扩充,但是对应的实体字符不一定跟上脚步,所以emoji表情也是转化成实体字符也是支持部分。
我也是参考一位楼主的文章: 移动前端手机输入法自带emoji表情字符处理
上面的链接说明的很清楚,但是没有说明怎么把emoji表情转化成uinicode编码格式的字符串,uinicode字符串编码再去取十进制的字符,再然后前面加 &# 就可以了,但是我要说是转化成uinicode编码,我在网上查看到这个
- (NSString *)getEmojiToShijinZhi:(NSString *)text{ NSString *hexstr = @""; for (int i = 0; i < [text length] / 2 && ([text length] % 2 == 0) ; i++) { // three bytes if (([text characterAtIndex:i*2] & 0xFF00) == 0 ) { hexstr = [hexstr stringByAppendingFormat:@"%1X%1X",[text characterAtIndex:i*2],[text characterAtIndex:i*2+1]]; }else{// four bytes hexstr = [hexstr stringByAppendingFormat:@"%1X",MULITTHREEBYTEUTF16TOUNICODE([text characterAtIndex:i*2],[text characterAtIndex:i*2+1])]; } } LYNSLog(@"(unicode) [%@]",hexstr); if (![hexstr isEqualToString:@""]) { NSString * temp10 = [NSString stringWithFormat:@"%lu",strtoul([hexstr UTF8String],0,16)]; LYNSLog(@"心跳数字 10进制 %@",temp10); //转成数字 int cycleNumber = [temp10 intValue]; LYNSLog(@"心跳数字 :%d",cycleNumber); return [NSString stringWithFormat:@"&#%d",cycleNumber]; } return hexstr;}
但是这个有个很大的问题是emoji表情的字符串长度是奇数的话就没法转码,我也不知道是那个楼主的特意写的呢,还是其他的原因,
其实最主要就是
hexstr = [hexstr stringByAppendingFormat:@”%1X%1X”,[text characterAtIndex:i*2],[text characterAtIndex:i*2+1]];
这个%1X就是打印十六进制的,而uinicode就是十六进制的,所以老铁没毛病呀,哈哈,Unicode百度百科 这里就是原因。
所以打印十六进制前面加个U+就是uinicode的表示方法
3.总结
其实他的这个方案也不是解决所有的emoji表情转成实体字符都能显示,只有最基本常用的几个表情才能利用实体字符显示出来,如果谁有更好的方法请告之一下,毕竟分享是一个很有趣的事情,大家共同进步,探讨,才能接触更多的东西,学习了解更多的东西呀
- iOS的emoji表情在数据库不支持UTF-8格式的处理
- 如何让不支持Emoji表情符的数据库存取Emoji表情
- 不支持输入Emoji表情的EditText
- emoji表情符的处理
- ios emoji表情的保存
- emoji 表情不能存入mysql 数据库和在jsp 页面显示的处理
- 在iOS中emoji表情的判断、过滤和禁用
- 总结项目中不支持emoji表情的问题的解决方法
- EditText禁止输入Emoji表情的处理
- java字符串Emoji表情的处理
- iOS中Emoji表情的判断
- iOS去除emoji表情的方法
- iOS自定义的emoji表情键盘
- iOS 过滤输入Emoji表情的问题
- iOS swift-emoji表情的显示
- iOS中Emoji表情的判断
- iOS textView的emoji表情过滤
- iOS中Emoji表情的判断
- 锁和分布式锁
- 我的 10 年自学编程之路
- 5.5 Matrix formulation
- linux增加交换空间
- 【mybatis】分页插件PageHelper
- iOS的emoji表情在数据库不支持UTF-8格式的处理
- Java之自定义注解
- mybatis-many-many
- securecrt 设置
- C++的基础知识(十四)--变量的作用域与生命周期
- 【莫比乌斯反演】莫比乌斯反演入门及推导
- hdu2566(暴力)
- 前方高能 | 你写过什么有趣的程序?最后一个笑出猪叫
- JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环)