作者:睿芬惠洁育瑋 | 来源:互联网 | 2023-02-08 19:10
我开发了一个iOS应用程序,我们可以将emojis从iOS发送到Web门户,反之亦然.从iOS发送到门户网站的所有表情符号都显示完美,除了"©和®".
这是表情符号编码代码片段.
NSData *data = [messageBody dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *encodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//这段代码\251\256
作为Unicodes copyright
和emojis 返回registered
,因为这两个Unicode不符合标准代码,所以它不会显示在门户网站上.
那么我应该怎么做才能将它们转换为标准的Unicodes?
测试运行 :
messageBody = @"Copy right symbol : © AND Registered Mark symbol : ®";
//我从上面的编码得到的编码字符串是
Copy right symbol : \\251 AND Registered Mark symbol : \\256
它应该在哪里(在标准unicodes上)
Copy right symbol : \\u00A9 AND Registered Mark symbol : \\u00AE
Jon Rose..
5
messageBody
是一个字符串,没有理由将其转换为数据,只是将其转换回字符串.替换你的代码
NSString *encodedString = messageBody;
如果messageBody
对象不正确,那么修复它的方法是更改它的创建方式.服务器发送数据,而不是字符串.服务器发送的数据是以某种商定的方式编码的.通常,此编码为UTF-8.如果您知道编码,则可以将数据转换为字符串; 如果你不这样做,那么数据是无法读取的乱码.如果messageBody
不正确,则从服务器发送的数据转换时出现问题.您似乎可能使用不正确的编码解析它.
您发布的代码完全错误.它使用一种编码(ASCII)将字符串转换为数据,并使用不同的编码(UTF8)读取数据.这就像将一本书翻译成西班牙语,然后让一位葡萄牙语的人将其翻译回来 - 它可能适用于某些词语,但它仍然是错误的.
如果您仍然遇到问题,那么您应该共享messageBody
创建位置的代码.
如果你的服务器期望一个ASCII字符串,其中所有unicode字符都改为\ u00xx那么你应该先对你的服务器员大喊大叫,因为他是个白痴.但如果这不起作用,您可以执行以下代码
NSString* messageBody = @"Copy right symbol : © AND Registered Mark symbol : ®";
NSData* utf32Data = [messageBody dataUsingEncoding:NSUTF32StringEncoding];
uint32_t *bytes = (uint32_t *) [utf32Data bytes];
NSMutableString* escapedString = [[NSMutableString alloc] init];
//Start a 1 because first bytes are for endianness
for(NSUInteger index = 1; index
Mert Buran..
5
首先,我将尝试提供解决方案.然后我会尝试解释原因.
转义非ASCII字符
要在字符串中转义unicode字符,您不应该依赖NSNonLossyASCIIStringEncoding
.下面是我用来在字符串中转义unicode和非ASCII字符的代码:
// NSMutableString category
- (void)appendChar:(unichar)charToAppend {
[self appendFormat:@"%C", charToAppend];
}
// NSString category
- (NSString *)UEscapedString {
char const hexChar[] = "0123456789ABCDEF";
NSMutableString *outputString = [NSMutableString string];
for (NSInteger i = 0; i > 7) > 0) {
[outputString appendString:@"\\u"];
[outputString appendChar:(hexChar[(character >> 12) & 0xF])]; // append the hex character for the left-most 4-bits
[outputString appendChar:(hexChar[(character >> 8) & 0xF])]; // hex for the second group of 4-bits from the left
[outputString appendChar:(hexChar[(character >> 4) & 0xF])]; // hex for the third group
[outputString appendChar:(hexChar[character & 0xF])]; // hex for the last group, e.g., the right most 4-bits
} else {
[outputString appendChar:character];
}
}
return [outputString copy];
}
(注意:我猜Jon Rose的方法也是如此,但我不想分享一种我没有测试过的方法)
现在您有以下字符串: Copy right symbol : \u00A9 AND Registered Mark symbol : \u00AE
逃脱unicode已完成.现在让我们将它转换回来显示表情符号.
转换回来
这一开始会让人感到困惑,但事实就是如此:
NSData *data = [escapedString dataUsingEncoding:NSUTF8StringEncoding];
NSString *cOnverted= [[NSString alloc] data encoding:NSNonLossyASCIIStringEncoding];
现在你有你的表情符号(和其他非ASCII).
怎么了?
问题
在您的情况下,您尝试在服务器端和应用程序之间创建通用语言.但是,NSNonLossyASCIIStringEncoding
这个目的是非常糟糕的选择.因为这是一个由Apple创建的黑盒子,我们真的不知道它究竟在里面做什么.正如我们所看到的,它将unicode转换为\uXXXX
将非ASCII字符转换为\XXX
.这就是为什么你不应该依赖它来构建一个多平台系统.在后端平台和Android中没有相同的功能.
然而,这是非常神秘的,NSNonLossyASCIIStringEncoding
仍然可以转换回来\u00AE
,因为它首先将它转换成\256
.我确信其他平台上有工具可以转换\uXXXX
成unicode字符,这对你来说应该不是问题.
1> Jon Rose..:
messageBody
是一个字符串,没有理由将其转换为数据,只是将其转换回字符串.替换你的代码
NSString *encodedString = messageBody;
如果messageBody
对象不正确,那么修复它的方法是更改它的创建方式.服务器发送数据,而不是字符串.服务器发送的数据是以某种商定的方式编码的.通常,此编码为UTF-8.如果您知道编码,则可以将数据转换为字符串; 如果你不这样做,那么数据是无法读取的乱码.如果messageBody
不正确,则从服务器发送的数据转换时出现问题.您似乎可能使用不正确的编码解析它.
您发布的代码完全错误.它使用一种编码(ASCII)将字符串转换为数据,并使用不同的编码(UTF8)读取数据.这就像将一本书翻译成西班牙语,然后让一位葡萄牙语的人将其翻译回来 - 它可能适用于某些词语,但它仍然是错误的.
如果您仍然遇到问题,那么您应该共享messageBody
创建位置的代码.
如果你的服务器期望一个ASCII字符串,其中所有unicode字符都改为\ u00xx那么你应该先对你的服务器员大喊大叫,因为他是个白痴.但如果这不起作用,您可以执行以下代码
NSString* messageBody = @"Copy right symbol : © AND Registered Mark symbol : ®";
NSData* utf32Data = [messageBody dataUsingEncoding:NSUTF32StringEncoding];
uint32_t *bytes = (uint32_t *) [utf32Data bytes];
NSMutableString* escapedString = [[NSMutableString alloc] init];
//Start a 1 because first bytes are for endianness
for(NSUInteger index = 1; index
2> Mert Buran..:
首先,我将尝试提供解决方案.然后我会尝试解释原因.
转义非ASCII字符
要在字符串中转义unicode字符,您不应该依赖NSNonLossyASCIIStringEncoding
.下面是我用来在字符串中转义unicode和非ASCII字符的代码:
// NSMutableString category
- (void)appendChar:(unichar)charToAppend {
[self appendFormat:@"%C", charToAppend];
}
// NSString category
- (NSString *)UEscapedString {
char const hexChar[] = "0123456789ABCDEF";
NSMutableString *outputString = [NSMutableString string];
for (NSInteger i = 0; i > 7) > 0) {
[outputString appendString:@"\\u"];
[outputString appendChar:(hexChar[(character >> 12) & 0xF])]; // append the hex character for the left-most 4-bits
[outputString appendChar:(hexChar[(character >> 8) & 0xF])]; // hex for the second group of 4-bits from the left
[outputString appendChar:(hexChar[(character >> 4) & 0xF])]; // hex for the third group
[outputString appendChar:(hexChar[character & 0xF])]; // hex for the last group, e.g., the right most 4-bits
} else {
[outputString appendChar:character];
}
}
return [outputString copy];
}
(注意:我猜Jon Rose的方法也是如此,但我不想分享一种我没有测试过的方法)
现在您有以下字符串: Copy right symbol : \u00A9 AND Registered Mark symbol : \u00AE
逃脱unicode已完成.现在让我们将它转换回来显示表情符号.
转换回来
这一开始会让人感到困惑,但事实就是如此:
NSData *data = [escapedString dataUsingEncoding:NSUTF8StringEncoding];
NSString *cOnverted= [[NSString alloc] data encoding:NSNonLossyASCIIStringEncoding];
现在你有你的表情符号(和其他非ASCII).
怎么了?
问题
在您的情况下,您尝试在服务器端和应用程序之间创建通用语言.但是,NSNonLossyASCIIStringEncoding
这个目的是非常糟糕的选择.因为这是一个由Apple创建的黑盒子,我们真的不知道它究竟在里面做什么.正如我们所看到的,它将unicode转换为\uXXXX
将非ASCII字符转换为\XXX
.这就是为什么你不应该依赖它来构建一个多平台系统.在后端平台和Android中没有相同的功能.
然而,这是非常神秘的,NSNonLossyASCIIStringEncoding
仍然可以转换回来\u00AE
,因为它首先将它转换成\256
.我确信其他平台上有工具可以转换\uXXXX
成unicode字符,这对你来说应该不是问题.