首先我要说的是,我并不是特别想找到一个解决方案,而只是解决问题的根本原因。我正在尝试从网址中检索JSON。在浏览器中,url调用工作得很好,我能够看到整个JSON没有问题。但是,在简单使用NSURLConnection的x代码中,我获取数据字节,但我的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使用,是否可能为此网址使用了多种类型的编码,或者是否有其他我可能在我的网站上做错了?< / p>
答案 0 :(得分:1)
即使看起来答案已在评论中提供(使用iso-8859-1作为正确的编码),我认为值得讨论如何调试此问题。
你说桌面浏览器(Chrome)可以正确地消化数据,所以让我们使用它:
如果这不起作用,Postman之类的工具可以帮助您在设备上实现之前重新创建呼叫
答案 1 :(得分: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 / corrupted数据可能会间歇地显示为符号或意外的字母数字。