版权/注册符号编码不起作用

aqs*_*had 7 unicode ios

我开发了一个iOS应用程序,我们可以将emojis从iOS发送到Web门户,反之亦然.从iOS发送到门户网站的所有表情符号都显示完美,除了"©和®".

这是表情符号编码代码片段.

NSData *data = [messageBody dataUsingEncoding:NSNonLossyASCIIStringEncoding]; 
NSString *encodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Run Code Online (Sandbox Code Playgroud)

//这段代码\251\256作为Unicodes copyright和emojis 返回registered,因为这两个Unicode不符合标准代码,所以它不会显示在门户网站上.

那么我应该怎么做才能将它们转换为标准的Unicodes?

测试运行 :

messageBody = @"Copy right symbol : © AND Registered Mark symbol : ®";
Run Code Online (Sandbox Code Playgroud)

//我从上面的编码得到的编码字符串是

Copy right symbol : \\251 AND Registered Mark symbol : \\256
Run Code Online (Sandbox Code Playgroud)

它应该在哪里(在标准unicodes上)

Copy right symbol : \\u00A9 AND Registered Mark symbol : \\u00AE
Run Code Online (Sandbox Code Playgroud)

Jon*_*ose 5

messageBody是一个字符串,没有理由将其转换为数据,只是将其转换回字符串.替换你的代码

NSString *encodedString = messageBody;
Run Code Online (Sandbox Code Playgroud)

如果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 < escapedString.length / 4 ;index++ ){
   uint32_t charValue =  bytes[index];
    if (charValue <= 127) {
        [escapedString appendFormat:@"%C", (unichar)charValue];
    }else{
        [escapedString appendFormat:@"\\\\u%04X", charValue];
    }
}
Run Code Online (Sandbox Code Playgroud)


Mer*_*ran 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 < self.length; i++) {
        unichar character = [self characterAtIndex:i];
        if ((character >> 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];
}
Run Code Online (Sandbox Code Playgroud)

(注意:我猜Jon Rose的方法也是如此,但我不想分享一种我没有测试过的方法)

现在您有以下字符串: Copy right symbol : \u00A9 AND Registered Mark symbol : \u00AE

逃脱unicode已完成.现在让我们将它转​​换回来显示表情符号.

转换回来

这一开始会让人感到困惑,但事实就是如此:

NSData *data = [escapedString dataUsingEncoding:NSUTF8StringEncoding];
NSString *converted = [[NSString alloc] data encoding:NSNonLossyASCIIStringEncoding];
Run Code Online (Sandbox Code Playgroud)

现在你有你的表情符号(和其他非ASCII).

怎么了?

问题

在您的情况下,您尝试在服务器端和应用程序之间创建通用语言.但是,NSNonLossyASCIIStringEncoding这个目的是非常糟糕的选择.因为这是一个由Apple创建的黑盒子,我们真的不知道它究竟在里面做什么.正如我们所看到的,它将unicode转换为\uXXXX将非ASCII字符转换为\XXX.这就是为什么你不应该依赖它来构建一个多平台系统.在后端平台和Android中没有相同的功能.

然而,这是非常神秘的,NSNonLossyASCIIStringEncoding仍然可以转换回来\u00AE,因为它首先将它转换成\256.我确信其他平台上有工具可以转换\uXXXX成unicode字符,这对你来说应该不是问题.