如何在NSString中正确编码Unicode字符?

时间:2013-04-18 09:06:47

标签: ios objective-c unicode nsstring uitextfield

问题陈述

我创建了许多字符串,将它们连接成CSV格式,然后通过电子邮件将字符串作为附件发送。

当这些字符串仅包含ASCII字符时,将生成CSV文件并通过电子邮件发送。当我包含非ASCII字符时,结果字符串变得格式错误,并且未正确创建CSV文件。 (电子邮件视图显示附件,但不会发送。)

例如,这有效:

uncle bill's house of pancakes

但这不是(注意卷曲撇号):

uncle bill’s house of pancakes

问题

如何正确创建和编码最终字符串,以便包含所有有效的unicode字符并正确形成结果字符串?

注释

  • 字符串是通过UITextField创建的,然后写入并从核心数据存储中读取。

  • 这表明问题在于字符串的初始创建和编码: NSString unicode encoding problem

  • 我不想这样做: remove non ASCII characters from NSString in objective-c

  • 字符串被写入数据存储并从数据存储中读取。字符串在应用程序的表视图中正确显示(单独)。只有在为电子邮件附件连接字符串时才会出现此问题。

字符串处理代码

我将我的字符串拼接在一起:

[reportString appendFormat:@"%@,", category];
[reportString appendFormat:@"%@,", client];
[reportString appendFormat:@"%@\n", detail];
etc.

用无聊的引号替换卷曲引号使其有效,但我不想这样做:

- (NSMutableString *)cleanString:(NSString *)activity {
    NSString *temp1 = [activity stringByReplacingOccurrencesOfString:@"’" withString:@"'"];
    NSString *temp2 = [temp1 stringByReplacingOccurrencesOfString:@"‘" withString:@"'"];
    NSString *temp3 = [temp2 stringByReplacingOccurrencesOfString:@"”" withString:@"\""];
    NSString *temp4 = [temp3 stringByReplacingOccurrencesOfString:@"“" withString:@"\""];
    return [NSMutableString temp4];
}

修改 电子邮件已发送:

    NSString *attachment = [self formatReportCSV];
    [picker addAttachmentData:[attachment dataUsingEncoding:NSStringEncodingConversionAllowLossy] mimeType:nil fileName:@"MyCSVFile.csv"];

其中formatReportCSV是连接并返回csv字符串的函数。

1 个答案:

答案 0 :(得分:4)

您似乎遇到了字符串编码问题。如果没有看到你的核心数据模型是什么样的,我认为这个问题归结为下面代码重现的问题。

NSString *string1 = @"Uncle bill’s house of pancakes.";
NSString *string2 = @" Appended with some garbage's stuff.";
NSMutableString *mutableString = [NSMutableString stringWithString: string1];
[mutableString appendString: string2];
NSLog(@"We got: %@", mutableString);
// We got: Uncle bill’s house of pancakes. Appended with some garbage's stuff.

NSData *storedVersion = [mutableString dataUsingEncoding: NSStringEncodingConversionAllowLossy];
NSString *restoredString = [[NSString alloc] initWithData: storedVersion encoding: NSStringEncodingConversionAllowLossy];
NSLog(@"Restored string with NSStringEncodingConversionAllowLossy: %@", restoredString);
// Restored string with NSStringEncodingConversionAllowLossy: 

storedVersion = [mutableString dataUsingEncoding: NSUTF8StringEncoding];
restoredString = [[NSString alloc] initWithData: storedVersion encoding: NSUTF8StringEncoding];
NSLog(@"Restored string with UTF8: %@", restoredString);
// Restored string with UTF8: Uncle bill’s house of pancakes. Appended with some garbage's stuff.

请注意第一个字符串(使用ASCII编码)无法处理非ASCII字符的存在(如果您使用dataUsingEncoding:allowsLossyConversion:且第二个参数为YES),则可以使用该字符串。

此代码应解决此问题:

NSString *attachment = [self formatReportCSV];
[picker addAttachmentData:[attachment dataUsingEncoding: NSUTF8StringEncoding] mimeType:nil fileName:@"MyCSVFile.csv"];

注意:如果您需要处理像日语这样的非UTF8语言,您可能需要使用其中一种UTF16字符串编码。