2013-09-06 11 views
6

Hackowałem się przez wiele godzin próbując rozwiązać ten problem bez skutku - wydaje mi się, że moją jedyną opcją jest zamieścić tutaj, aby sprawdzić, czy ktoś może rzucić niektóre światło w tej kwestii. Może to być problem z AFNetworking lub (co bardziej prawdopodobne), może to być problem z moim kodem.Ważny JSON, ale "Błąd kakao 3840" z AFNetworking/NSJSONSerialization

Kod ja doskonale używając prace dla 99% operacji w mojej aplikacji. Pracuję nad aplikacją, która wykorzystuje Elastic Search, budując wyszukiwania JSON, wysyłając je i otrzymując odpowiedź od serwera.

Oto przykład z JSON, który jest zwracany:

{ 
    "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 
       ] 
      } 
     ] 
    } 
} 

Teraz podłączając to pod jsonlint.com (a znając trochę o formatowaniu JSON), to łatwo zauważyć, że jest to ważne JSON.

Używam podklasy AFHTTPClient Aby dodawać moją prośbę i odbierania danych. Oto kod używam do 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); 
    } 
}]; 

Nic specjalnego tutaj, ja po prostu obracając odpowiedź do jakiegoś JSON.

Jednak problemem jest to, że do tego w szczególności wniosek, uznając AFNetworking jest odpowiedź jako niepowodzenie, więc kod w bloku awarii jest tylko kod jest wykonywany. Otrzymuję następujący błąd:

(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 zawiera szereg wykładniczy w nim (konkretnie 4.439049394553e-312), jednak jest to prawidłowy numer i powinien móc być analizowany. Otrzymuję ten sam NSError, gdy próbuję analizować dane odpowiedzi przy użyciu NSJSONSerialization. Aby wyjaśnić - AFNetworking daje mi ten sam komunikat o błędzie, co NSJSONSerialization.

nie mogę znaleźć nikogo, kto jest o ten sam problem jak ja i nie może zrozumieć, dlaczego mój JSON nie może być analizowany. Zostawia moją aplikację z bardzo dużym błędem, którego nie mogę naprawić.

Jeśli ktoś mógłby rzucić trochę światła na tę kwestię, byłoby świetnie. Jeśli to nie jest problem z AFNetworking, możesz wskazać mi pomocne źródło, które również byłoby niesamowite. Oczywiście, jeśli wymagają żadnych dodatkowych informacji, proszę pytaj

Dziękuję.

Odpowiedz

6

NSJSONSerialization wykorzystuje NSDecimalNumber do reprezentowania liczb i

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

już wraca NaN, ponieważ NSDecimalNumber może reprezentować tylko cyfry

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

Więc to wydaje się być "ograniczenie" (lub bug) z NSJSONSerialization, że działa tylko z numerami w pewnym zakresie.

Zrobiłem szybki test z „SBJsonParser” i miał ten sam problem.

+0

Myślę, że coś tu jest. To trochę głupie, że ograniczamy się do danych, które możemy odkodować. Sądziłem, że będą zawierać jakąś opcję analizowania JSON, na przykład, aby przeanalizować je jako łańcuchy, jeśli nie można ich przeanalizować jako liczby. Sortowanie w taki sam sposób, w jaki można stratnie przekonwertować na NSData. –

+0

Nie, NSJSONSerialization używa NSNumber z liczbami całkowitymi dla liczb całkowitych <10^18, NSDecimalNumber dla wartości całkowitych> = 10^18 i NSNumber z podwójnymi wartościami dla wszystkiego, co ma kropkę dziesiętną lub wykładnik. – gnasher729

+0

@ gnasher729: Masz rację, że są przypadki, w których używany jest NSNumber, a nie NSDecimalNumber. (Zauważyłem to również podczas długotrwałej dyskusji tutaj http://stackoverflow.com/questions/20198040/how-to-determine-the-true-data-type-of-an-nsnumber#comment30126509_20198040). Ale wydaje się, że nie jesteś całkowicie poprawny. '1.2e-3' daje (w moim teście) NSDecimalNumber. '0.0012' podaje NSNumber zawierający double. A '4,439049394553e-312' nadal nie działa. (Testy wykonane w Symulatorach iOS 7). –

Powiązane problemy