0

让我首先说我并不是特别想找到解决方案,只是寻找问题的根本原因。我正在尝试从 url 检索 JSON。在浏览器中,url 调用工作得很好,我可以毫无问题地看到整个 JSON。但是,在 x 代码中,当简单地使用 NSURLConnection 时,我正在获取数据字节,但我的 NSString 为空。

    theString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];

在做了一些研究之后,我发现我可能试图使用错误的编码。我不确定 url 使用的是什么类型的编码,所以第一直觉我只是尝试了一些随机编码类型。

    NSString* myString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSString* myString2 = [[NSString alloc] initWithData:data encoding:NSUTF16StringEncoding];
    NSString* myString3 = [[NSString alloc] initWithData:data encoding:NSWindowsCP1252StringEncoding];

NSASCIIStringEncoding 和 NSWindowsCP1252StringEncoding 能够带回部分正确的 JSON。我能够在浏览器中查看的不是整个 JSON,而且有些字符有点乱,但它是一些东西。为了尝试更好地确定使用了什么编码,我决定使用以下方法来尝试通过查看返回的编码来确定它。

NSError *error = nil;
NSStringEncoding encoding;
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
                                                 usedEncoding:&encoding
                                                        error:&error];

我的 NSStringEncoding 值为 3221214344。每次运行应用程序时,这个数字都是一致的。我找不到任何甚至接近匹配的 NSStringEncoding 值。

我的最后一个问题是:iOS 不能使用此 url 使用的编码,是否有可能此 url 使用了多种类型的编码,或者我可能做错了什么?

4

2 回答 2

1

尽管评论中似乎已经提供了答案(使用 iso-8859-1 作为正确的编码),但我认为值得讨论如何调试这个问题。

您说桌面浏览器(Chrome)可以正确消化数据,所以让我们使用它:

  1. 启用开发者工具https://developers.google.com/chrome-developer-tools/
  2. 当开发工具窗口打开时,切换到“网络”并在该浏览器选项卡中执行您的调用
  3. 通过单击请求 url 检查输出 - 它应该会给你一些线索。

如果这不起作用,Postman之类的工具可以帮助您在设备上实现之前重新创建调用

于 2014-02-08T18:53:56.690 回答
1

如果可能,最好不要依赖 Cocoa 来确定字符串编码,尤其是在数据可能损坏的情况下。更好的方法是检查 HTTP Content-Type 标头指示的值是否指定了一个字符集,如下例所示:

Content-Type: text/html; charset=ISO-8859-4

一旦您能够从 Content-Type 标头解析和检索字符集名称,您需要将其转换为NSStringEncoding,首先将其传递给CFStringConvertIANACharSetNameToEncoding,然后将返回的 CF 字符串编码传递给CFStringConvertEncodingToNSStringEncoding. 之后,您可以使用-[NSString initWithData:encoding:].

NSData *HTTPResponseBody = …; // Get the HTTP response body
NSString *charSetName = …;  // Get a charset name from the Content-Type HTTP header

// Get the Core Foundation string encoding
CFStringEncoding cfencoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)charSetName);

// Confirm this is a known encoding
if (cfencoding != kCFStringEncodingInvalidId) {
    // Initialize the string
    NSStringEncoding nsencoding = CFStringConvertEncodingToNSStringEncoding(cfencoding);
    NSString *JSON = [[NSString alloc] initWithData: HTTPResponseBody 
                                           encoding: nsencoding];
}

如果您正在使用的字符串数据已损坏,您仍然可能会遇到问题。例如,在上面的代码片段中,可能charSetName是 UTF-8,但HTTPResponseBody由于存在无效的字节序列,因此无法解析为 UTF-8。在这种情况下,当您尝试实例化您的字符串时,Cocoa 将返回nil,并且没有清理数据以使其符合报告的字符串编码(可能通过去除无效的字节序列),您可能希望将错误报告给最终用户。

作为最后的努力——而不是报告错误——你可以使用可以处理你扔给它的任何东西的编码来初始化一个字符串,例如NSMacOSRomanStringEncoding. 这里需要注意的是,unicode / 损坏的数据可能会间歇性地显示为符号或意外的字母数字。

于 2014-02-08T20:30:08.527 回答