表情符号无法被编码为JSON。

17
我有一个名为messageFieldUITextView,其中的数据以JSON格式POST到服务器。当用户输入一个Emoji字符时,我遇到了编码数据到JSON的问题。我认为Emoji使用Unicode编码。
有没有一种方法将Emoji字符编码为JSON?并且从JSON返回Emoji以在UILabel中显示?

我能否更改在php端编码的iOS中的表情符号解码?如果可以,那么如何在两个端口进行操作?我尝试过了,但是没有效果,只有编码和解码大小相同才有效。否则就不起作用:(所以请给我一些解决方案。谢谢您的提前致谢。 - Ilesh P
6个回答

28

我使用以下代码对表情符号进行编码

NSString *uniText = [NSString stringWithUTF8String:[textview.text UTF8String]]; 
NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding]; 
NSString *goodMsg = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding] ;

以下代码用于解码并在UILabel中显示

const char *jsonString = [body UTF8String]; 
NSData *jsonData = [NSData dataWithBytes:jsonString length:strlen(jsonString)]; 
NSString *goodMsg = [[NSString alloc] initWithData:jsonData encoding:NSNonLossyASCIIStringEncoding];

是的,这对我很有帮助...通过推送通知发送和接收表情符号字符。 - Pradeep
我能否更改在php端编码的iOS中的表情符号解码?如果可以,那么如何在两个端口进行操作?我尝试过了,但是没有效果,只有编码和解码大小相同才有效。否则就不起作用:(所以请给我一些解决方案。谢谢您的提前致谢。 - Ilesh P
@ilesh:这取决于您在PHP端进行的编码类型。 - Karun

12

编辑-2016年03月03日请注意,本答案是在2011年撰写的,可能已经不再适用。

表情符号只是用于呈现特定Unicode代码点的特定字体。iOS使用一个统一的专用区为表情符号提供特定的代码点。将这些“字符”视为表情符号的唯一方法是拥有可用的表情符号字体以及知道如何从默认文本字体(例如Helvetica)切换到表情符号字体的机器。

我不知道您如何编码JSON,但是由于表情符号只是文本,因此只要以Unicode友好格式(例如UTF-8或UTF-16)传输文本,就不应该存在任何问题。您在服务器端或数据库中看不到它(除非使用先前的必备条件查看数据),但是您应该能够发送相同的原始字节并且它应该看起来相同。

以下是一些可能更有帮助的文章:


嗨,感谢您的评论。它帮了我很多 :) 我现在唯一的问题是当我将JSON数据POST到Web服务器时,尝试使用$ postData = file_get_contents(“php:// input”)获取数据时,无法获取数据。但是当我使用类似于$ postData ='{"body":"characters here "}';这样的虚拟数据时,我可以成功地将数据插入数据库并在设备中读取它们。 - janusfidel

4
感谢 @Karu 的回答,我编辑了你的回复,我使用了以下代码:
发送到服务器时进行编码:
NSString *uniText = [NSString stringWithUTF8String:[text_to_send UTF8String]];

NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding];

NSString *str = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding];

解码以接收和显示表情符号文本:

NSData *newdata = [received_string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

NSString *mystring = [[NSString alloc] initWithData:newdata encoding:NSNonLossyASCIIStringEncoding];

NSString *finalString= @"";

if (mystring) {
   finalString = mystring;
}else{
   finalString = received_string;
}

这段代码在iOS 9上运行完美。


4

我曾经遇到同样的问题,查了几个小时,最终找到了这个对我有用的答案:https://dev59.com/hG435IYBdhLWcg3w7k6b#8339255

如果您正在使用Rails作为服务器,这就是您需要做的全部。无需在ios/xcode中进行任何UTF8/16编码操作,只需将NSString传递给服务器即可,Postegre会正确存储代码,只是当您将json响应发送回ios客户端时,假定您使用render json:@message,json编码会出现问题。

您可以通过在rails控制台中进行简单测试来测试是否存在json编码问题:

test = {"smiley"=>"u{1f604}"} test.to_json

如果它打印出"{\"smiley\":\"\uf604\"}"(请注意数字1丢失了),那么您就有这个问题,链接中的修补程序将解决它。


非常感谢。是的,我也注意到了缺失的那个。很奇怪。不管怎样,那个猴子补丁对我有用。谢谢! - Sam Soffes

2
更新 Swift 和 Objective C
如果你想通过 JSON 发送一个表情符号,首先需要将数据库格式化为 UTF-8,并在 IOS 中对 NSUTF8StringEncoding 进行编码。因此,首先确保你的数据库格式为 UTF-8,然后将参数编码为 NSUTF8StringEncoding。以下是发送消息时的示例请求。
    let post:NSString = parameters!
    let url:NSURL = NSURL(string: serverURL!)!
    let postData:NSData = post.dataUsingEncoding(NSUTF8StringEncoding)! // Change Here
    let postLength:NSString = String( postData.length )
    let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("*/*", forHTTPHeaderField: "Accept")
    return request

但在iOS中,您不需要使用NSUTF8StringEncoding解码。因为根据苹果文档,它可以解码5种编码格式。

数据必须是JSON规范中列出的5种支持的编码之一:UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE。数据可能有BOM也可能没有。最有效的解析编码是UTF-8,因此如果您可以选择编码传递给此方法的数据,请使用UTF-8。

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/#//apple_ref/occ/clm/NSJSONSerialization/JSONObjectWithData:options:error:


2

需要注意的一点是 Emoji - 如果您的JSON编码器设置为生成ASCII输出(即使用\u<4个十六进制数字>字符格式),某些Emoji字符将无法正常显示,因为它们使用超过两个字节,因此无法适应允许的4个十六进制数字。

所以在Python中,确保使用:

json.dumps(<object containing emoji strings>, ensure_ascii=False)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接