NSJSONSerialization 没有正确读取 UTF 8

NSJSONSerializzation not reading UTF8 correctly

我正在阅读 URL 中的 JSON。它是 UTF8 格式的。当我加载 UITableView 时,它显示不正确的字符。 请在第 2 行找到附加的屏幕截图

读取数据的代码如下:

NSURL *myURL=[NSURL     URLWithString:@"http://www.bancariromani.it/cecadm/newClass/modules/rh/index.php?id_cup=15&json=1"];

NSError *error;
NSData *myData=[[NSData alloc]initWithContentsOfURL:myURL];
if(!myData){

    return;

}

NSArray *jasonArray=[NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:&error];

我也尝试过,但没有成功:

NSURL *myURL=[NSURL URLWithString:@"http://www.bancariromani.it/cecadm/newClass/modules/rh/index.php?id_cup=15&json=1"];

 NSError *error;
NSString *string = [NSString stringWithContentsOfURL:myURL encoding:NSISOLatin1StringEncoding error:nil];

 NSData *myData = [string dataUsingEncoding:NSUTF8StringEncoding];

if(!myData){

    return;

}
NSArray *jasonArray=[NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:&error];

我在哪里丢失了 UTF8 格式?

谢谢你帮助我

达里奥

您的数据使用 HTML 方式来存储特殊字符。它不同于 UTF-8,是一种使用 ASCII 代码点添加特殊字符的方法。

http://www.w3.org/TR/html4/charset.html#h-5.3 for how they work. A way to decode them is answered in HTML character decoding in Objective-C / Cocoa Touch

您是说第二行的“'”部分吗?那是 HTML,您可以通过 url 编码来转换它。你可以试试这个方法:

- (NSString *)stringByReplacingPercentEscapesUsingEncoding:(NSStringEncoding)encoding

那个'是一个字符的HTML转义;这与 UTF-8 完全无关。

要么要求您的 WebService 停止使用百分比转义对 HTML 实体进行编码,因为它们通常不需要这样做……或者您可以使用一种方法来删除它们,就像使用此代码一样:

NSMutableString* yourString = [… mutableCopy];
CFStringTransform((CFMutableStringRef)yourString, NULL, kCFStringTransformToXMLHex, true);
NSLog(@"transformed string: %@", yourString);

不幸的是,这似乎只适用于 HTML 表示为十六进制代码点的实体,如 ' 而不是表示为十进制代码点的实体,如 &#039.

所以这是一个自定义方法来做到这一点(解码十进制 HTML-entities):

NSString* decodeHTMLEntities(NSString* string)
{
    NSRegularExpression* decimalEntity = [NSRegularExpression regularExpressionWithPattern:@"&#(\d+);" options:0 error:nil];
    NSMutableString* resultString = [string mutableCopy];
    NSInteger __block offset = 0;
    [decimalEntity enumerateMatchesInString:string options:0 range:NSMakeRange(0,string.length)
                                 usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
     {
         unsigned decimalCode = [string substringWithRange:[result rangeAtIndex:1]].intValue;
         NSString* decodedChar = [NSString stringWithFormat:@"%C", (unichar)decimalCode];
         result = [result resultByAdjustingRangesWithOffset:offset];
         [resultString replaceCharactersInRange:result.range withString:decodedChar];
         offset += (NSInteger)decodedChar.length - (NSInteger)result.range.length;
     }];
    return [resultString copy];
}

(当然,最好让您的 Web 服务提供商在源头修复它,因为他们首先没有正当理由这样做)