2013-03-15 37 views
2

我以前問過一個類似的問題,但沒有得到太多的幫助,現在進一步研究它,仍然不明白爲什麼我有問題。AFJSONRequestOperation與「數據參數爲零」崩潰NSJSONSerialization錯誤

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的類型,我設法通過重新調整字符串編碼到NSUTF8StringEncoding

得到與 NSJSONSerialization該工作

示例...

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 

所以我在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聲明崩潰看着responseJSON,然而,這似乎是在做直接使用NSJSONSerialization時和重新編碼responseString我以前做的事情。

我甚至硬編碼dataUsingEncodingNSUTF8StringEncoding但它仍然崩潰,我不明白爲什麼?

注:以上正常工作與其他JSON源,也從其他飼料上

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

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

包括地名Sóil Chaorainn這會導致問題

回答

0

問題似乎是響應的文本編碼是錯誤的。有些字符不能使用ISO-8859-1進行編碼。這就是爲什麼responseString方法(請參閱AFURLConnectionOperation.m)返回nil並且JSON序列化失敗。

爲了解決你可以繼承AFJSONRequestOperation並以這種方式來執行UTF-8編碼覆蓋responseStringEncoding問題:

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

    return _responseStringEncoding; 
} 
+0

是不是一樣的,當我試圖NSData的* JSONData = [self.responseString dataUsingEncoding :NSUTF8StringEncoding]; – 2013-03-15 13:34:51

+0

不,因爲responseString方法使用responseStringEncoding本身,因此將是零。 – Felix 2013-03-15 16:59:20