AFJSONRequestOperation崩溃,“data parameter is nil”NSJSONSerialization错误

时间:2013-03-15 11:35:24

标签: iphone ios objective-c afnetworking

我之前曾就此问过一个类似的问题,但没有得到太多帮助,现在进一步研究了这个问题,仍然无法理解为什么我有问题。

NSURL *url = [NSURL URLWithString:@"http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/sitelist?res=daily&key=<MY API KEY>"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"Success");
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Fail");
}];
[operation start];

以下

失败
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'

我认为问题是由于ISO-8859-1返回的JSON类型,我设法通过将重新调整后的字符串编码为NSJSONSerialization

来使用NSUTF8StringEncoding

示例...

NSString *string = [NSString stringWithContentsOfURL:kMetOfficeAllSites encoding:NSISOLatin1StringEncoding error:&error];
NSData *metOfficeData = [string dataUsingEncoding:NSUTF8StringEncoding];
id jsonObject = [NSJSONSerialization JSONObjectWithData:metOfficeData options:kNilOptions error:&error];
if (error) {
    //Error handling
} else {
    //use JSON

所以我查看了responseJSON

中的AFJSONRequestOperation.m
- (id)responseJSON {
[self.lock lock];
if (!_responseJSON && [self.responseData length] > 0 && [self isFinished] && !self.JSONError) {
    NSError *error = nil;

    // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
    // See https://github.com/rails/rails/issues/1742
    if ([self.responseData length] == 0 || [self.responseString isEqualToString:@" "]) {
        self.responseJSON = nil;
    } else {
        // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character
        // See http://stackoverflow.com/a/12843465/157142
        NSData *JSONData = [self.responseString dataUsingEncoding:self.responseStringEncoding];
        self.responseJSON = [NSJSONSerialization JSONObjectWithData:JSONData options:self.JSONReadingOptions error:&error];
    }

    self.JSONError = error;
}
[self.lock unlock];

return _responseJSON;
}

代码在else语句中崩溃,但是这似乎正在执行我之前在直接使用NSJSONSerialization并重新编码responseString时所做的事情。

我甚至将dataUsingEncoding硬编码到NSUTF8StringEncoding,但它仍然崩溃,我不明白为什么?

注意:以上内容适用于其他JSON Feed,也适用于

上的其他Feed

http://datapoint.metoffice.gov.uk/但是

http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/sitelist?res=daily&key=

包含导致问题的地名Sóil Chaorainn

1 个答案:

答案 0 :(得分:0)

问题似乎是响应的文本编码是错误的。有些字符无法使用ISO-8859-1进行编码。这就是responseString方法(参见AFURLConnectionOperation.m)返回nil并且JSON序列化失败的原因。

要解决此问题,您可以通过这种方式继承AFJSONRequestOperation并覆盖responseStringEncoding以强制执行UTF-8编码:

- (NSStringEncoding)responseStringEncoding {
    [self.lock lock];
    if (!_responseStringEncoding && self.response) {
        self.responseStringEncoding = NSUTF8StringEncoding;
    }
    [self.lock unlock];

    return _responseStringEncoding;
}