2013-09-06 3 views
6

Я много часов пытался решить эту проблему, но мне кажется, что мой единственный вариант - опубликовать здесь, чтобы узнать, может ли кто-нибудь пролить некоторые свет по этому вопросу. Это может быть проблема с AFNetworking, или (более вероятно), это может быть проблемой с моим кодом.Действительный JSON, но «Cocoa error 3840» из AFNetworking/NSJSONSerialization

Код, который я использую, отлично работает для 99% операций в моем приложении. Я разрабатываю приложение, которое использует Elastic Search, создавая JSON-запросы, отправляя их и получая ответ от сервера.

Вот пример JSON, который возвращается:

{ 
    "took": 4, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": null, 
     "hits": [ 
      { 
       "_index": "asx", 
       "_type": "61a88d3848b00655d9aa59db70847318", 
       "_id": "b91f9257744fedb4ef1c127e275c127c", 
       "_score": null, 
       "_source": { 
        "value": "22/06/1998" 
       }, 
       "sort": [ 
        4.439049394553e-312 
       ] 
      } 
     ] 
    } 
} 

Теперь, подключив это в jsonlint.com (и зная немного о JSON форматирования), легко видеть, что это справедливо в формате JSON.

Я использую подкласс AFHTTPClient для POST моего запроса и получения данных. Вот код, я использую для POST:

[super postPath:path parameters:parameters success:^(AFHTTPRequestOperation *operation, NSDictionary *response) { 
    NSData *responseData = [(AFJSONRequestOperation *)operation responseData]; 
    NSDictionary *responseDictionary; 

    if (responseData != nil) { 
     responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:NULL]; 
    } 

    if (success) { 
     success(operation, responseDictionary); 
    } 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSData *responseData = [(AFJSONRequestOperation *)operation responseData]; 
    NSDictionary *responseDictionary; 

    if (responseData != nil) { 
     responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:NULL]; 
    } 

    if (failure) { 
     failure(operation, error, responseDictionary); 
    } 
}]; 

ничего особенного здесь, я поворачивался ответ в какой-то формат JSON.

Однако проблема заключается в том, что для этого в конкретном запросе AFNetworking рассматривает ответ как отказ, поэтому код в блоке отказов является единственным исполняемым кодом. Я получаю следующее сообщение об ошибке:

(lldb) po error 
$1 = 0x0adbc710 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Number wound up as NaN around character 279.) UserInfo=0xad968d0 {NSDebugDescription=Number wound up as NaN around character 279.} 

JSON содержит экспоненциальное число в нем (4.439049394553e-312 в частности), однако это справедливо и номер должен быть в состоянии быть разобран. Я получаю тот же NSError, когда пытаюсь проанализировать данные ответа, используя NSJSONSerialization. Просто уточнить - AFNetworking дает мне то же сообщение об ошибке, что и NSJSONSerialization.

Я не могу найти никого другого, у кого есть такая же проблема, как и я, и не могу понять, почему мой JSON не может быть проанализирован. Это оставляет мое приложение с очень большой ошибкой, которую я не могу исправить.

Если кто-то может пролить свет на эту проблему, это было бы здорово. Если это не проблема с AFNetworking, если вы можете указать мне на полезный ресурс, который также будет потрясающим. Конечно, если вам нужна дополнительная информация, пожалуйста, задайте вопрос

Спасибо.

ответ

6

NSJSONSerialization использует NSDecimalNumber для представления чисел, и

[NSDecimalNumber decimalNumberWithString:@"4.439049394553e-312"] 

уже возвращает NaN, поскольку NSDecimalNumber может представлять только цифры

mantissa x 10^exponent   where `-128 <= exponent <= 127`. 

Так что это, кажется, "ограничение" (или ошибка) из NSJSONSerialization, что он работает только с номерами в определенном диапазоне.

Я сделал быструю проверку с помощью «SBJsonParser», и у нее была такая же проблема.

+0

Я думаю, что вы здесь. Это немного глупо, как мы ограничены данными, которые мы можем расшифровать. Я бы подумал, что они будут включать какой-то вариант разбора JSON, скажем, для синтаксического анализа их в виде строк, если они не могут быть проанализированы как число. Аналогичным образом вы можете конвертировать потери в NSData. –

+0

Нет, NSJSONSerialization использует NSNumber с целыми значениями для целых чисел <10^18, NSDecimalNumber для целых значений> = 10^18 и NSNumber с двойными значениями для всего, что имеет десятичную точку или показатель степени. – gnasher729

+0

@ gnasher729: Вы правы, что есть случаи, когда используется NSNumber, а не NSDecimalNumber. (Я заметил это также во время долгой дискуссии здесь http://stackoverflow.com/questions/20198040/how-to-determine-the-true-data-type-of-an-nsnumber#comment30126509_20198040). Но, похоже, вы не совсем правы. '1.2e-3' дает (в моем тесте) NSDecimalNumber. '0.0012' дает номер NSNumber, содержащий double. И '4.439049394553e-312' все еще терпит неудачу. (Тесты, выполненные в iOS 7 Simulator.) –

Смежные вопросы