2012-05-22 8 views
22

Używamy AFNetworking w naszej aplikacji mobilnej i wiele razy będziemy mieć JSON, który ma wartość NULL dla niektórych wartości.Czy można uzyskać AFNetworking, aby automatycznie parsować NULL do zera?

Mam już dość wykonywania następujących czynności.

if ([json objectForKey:@"nickname"] isKindOfClass:[NSNull class]]) { 
    nickname = nil; 
} else { 
    nickname = [json objectForKey:@"nickname"]; 
} 

Wszystko, co możemy zrobić, aby AFNetworking automagicznie zestaw przedmiotów do zera lub cyfr na 0, jeśli wartość jest null w odpowiedzi JSON?

Odpowiedz

20

To naprawdę niemożliwe, ponieważ słownik nie może zawierać nil jako obiektu dla klucza. Klucz musiałby zostać całkowicie pominięty, aby uzyskać pożądane zachowanie, które byłoby niepożądane na swój sposób.

Załóżmy, że nie masz kontroli nad danymi, które otrzymałeś i nie wiesz, jakie klucze były obecne w JSON. Jeśli chcesz wyświetlić listę wszystkich lub wyświetlić je w tabeli, a klucze dla obiektów zerowych zostały pominięte w słowniku, zobaczysz niepoprawną listę.

NSNull to "nicość" zastępcza dla kolekcji Cocoa i dlatego jest używana w tym przypadku.

Można zrobić typowania trochę łatwiej z makra:

#define nilOrJSONObjectForKey(JSON_, KEY_) [[JSON_ objectForKey:KEY_] isKindOfClass:[NSNull class]] ? nil : [JSON_ objectForKey:KEY_] 

nickname = nilOrJSONObjectForKey(json, @"nickname"); 
+0

Myślę, że to jest prawdopodobnie to, co zrobię, makro, które mam na myśli. Dzięki! – birarda

+0

Właściwie nie jestem pewien, dlaczego całkowite pominięcie klucza jest złe? Wolałbym zrobić 'nickname = [json objectForKey: @" nick "]" i mieć wartość null i móc po prostu powiedzieć 'if (! Nickname)' elsewhere. – birarda

+0

@birarda: A co jeśli chcesz zapytać słownik o listę wszystkich jego kluczy? Otrzymasz nieprawidłową odpowiedź - klucz istnieje w JSON. –

1

W przypadku zastąpienia domyślnej NSJSONSerialization SBJSON rozwiąże on problem.

SBJSON sprawia obiekty nil zamiast wyboru NSJSONSerialization dnia „null”

spojrzenie na wymagania dla poszczególnych analizatorów JSON można użyć. https://github.com/AFNetworking/AFNetworking#requirements

+0

prostu próbowałem to i to nie wydaje się być domyślne zachowanie SBJSON. Jeśli usunę instrukcję sterującą, aby sprawdzić, czy jest ona pusta, wówczas podczas próby ustawienia właściwości pojawia się ten błąd '[NSNull stringByDecodingHTMLEntities]'. – birarda

29

Można ustawić setRemovesKeysWithNullValues ​​flag YES AFHTTPSessionManager odpowiedzi serializatora: odpowiedź

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:url sessionConfiguration:config]; 
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; 
[serializer setRemovesKeysWithNullValues:YES]; 
[manager setResponseSerializer:serializer]; 
+0

Lubię twoje odpowiedzi bardziej niż inne – Lolloz89

2

DV_ za działa świetnie na AFHTTPSessionManager. Ale jeśli używasz AFHTTPRequestOperation zamiast menedżera, spróbuj tego:

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer]; 
serializer.removesKeysWithNullValues = YES; 
op.responseSerializer = serializer; 
+0

Działa. Sądzę jednak, że chodziło Ci o: 'AFJSONResponseSerializer * serializer = [seriser AFJSONResponseSerializer];' –

+0

Tak, rzeczywiście zrobiłem. Edytowane. Dziękuję Ci – gavdotnet

2

Jest jeden piękny cocoapod nazywa mielone https://github.com/hyperoslo/Minced że można zrobić coś, co może pomóc poradzić NULL z odpowiedzi JSON. Zamiast NULL wstawia pusty łańcuch.

0

Za pomocą tej funkcji można wykonać niestandardową funkcję AFNetworking. ustawić dowolną wartość domyślną do obiektów, które są NULL

static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) { 
if ([JSONObject isKindOfClass:[NSArray class]]) { 
    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]]; 
    for (id value in (NSArray *)JSONObject) { 
     [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)]; 
    } 

    return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray]; 
} else if ([JSONObject isKindOfClass:[NSDictionary class]]) { 
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject]; 
    for (id <NSCopying> key in [(NSDictionary *)JSONObject allKeys]) { 
     id value = (NSDictionary *)JSONObject[key]; 
     if (!value || [value isEqual:[NSNull null]]) { 
      // custom code here 
      //[mutableDictionary removeObjectForKey:key]; 
      [mutableDictionary setObject:@"" forKey:key]; 
     } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) { 
      mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions); 
     } 
    } 

    return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary]; 
} 

return JSONObject; 

}

Powiązane problemy