SerializationOto krótki wpis o Serializacji i Deserializacji JSON-a w Objective-C. Komunikaty w usługach sieciowych zwykle mają notację XML-ową lub JSON-ową. JSON jest lżejszy jest on więc bardziej stosowany. Usługa sieciowa typu SOAP jest ciężka więc urządzenia mobilne lubią usługi sieciowe typu REST.
Przejdźmy jednak do Serializacja i Deserializacja .
Brew pozorom jest to dosyć zaawansowany temat. Gdy chcemy zapisać nasz obiekt do pliku używamy serializacji. Gdy otrzymujemy komunikat i chcemy go przetłumaczyć używamy deserializacji.
To jest przykład bardziej tradycyjnej metody Serializacji i deserializacji bez żadnych pomocniczych bibliotek.
Być może kiedyś spróbuje osiągnąć to samo używając protokołu NSCoding. Chociaż ta metoda jest stworzona do zapisów obiektów na urządzeniu.
Podobnie jak w Androidzie najłatwiej serializuję się tablice i słowniki. Prawdopodobnie chciałbyś aby istniała już gotowa metoda, która by wydrukowała twoją istniejącą klasę do postaci JSON-a. Z tego, co znalazłem istnieje pewna niestandardowa biblioteka, która może ci pomóc.
Przeciwnym wypadku będziesz musiał napisać swoje własne metody, które upraszczają twoje obiekty do postaci słowników i tablic.
Metoda dataWithJSONObject : options : error klasy NSJSONSerialization potrafi serializować słowniki i tablice, które zawierają instancje zmiennych NSString, NSNumber, NSArray, NSDictionary, jak i NSNull dla pustych wartości.
Żadnych złożonych typów żadnych własnych klas. Serializujemy własne utworzone słowniki i tablice.
Oto ukazujący prostą Serializacja JSON.
- (IBAction)btn_JsonSer_Click:(id)sender {
NSMutableDictionary *dictionary =
[NSMutableDictionary dictionaryWithDictionary:@{
@"First Name" : @"Tom",
@"Last Name" : @"Zdzisławski",
@"Age" : @24
}];
NSArray *arrayOfTomsChildren = @[
@" Stefan Zdzisławski",
@" Shin-Chan Zdzisławski",
@" Katarzyna Zdzisławska",
@" Franko Zdzisławski",
@" Darek Zdzisławski"
];
[dictionary setValue:arrayOfTomsChildren forKey:@"children"];
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject:dictionary
options:NSJSONWritingPrettyPrinted
error:&error];
if ([jsonData length] > 0 &&
error == nil){
NSLog(@"Udało się serializować słownik jako JSON");
NSString *jsonString =
[[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
NSLog(@"JSON String = %@", jsonString);
}
else if ([jsonData length] == 0 &&
error == nil){
NSLog(@"Nic nie zostało zwrócone po serializacji");
}
else if (error != nil){
NSLog(@"Błą∂ Sorry = %@", error);
}
}
Jak widzisz słownik zawiera pierwsze imie, nazwisko oraz wiek Tom-a. Klucz o nazwie “children” zawiera listę dzieci Tom-a.
Wartością zwracaną przez metodę dataWithJSONObject : options : error jest NSData. NSData może być w łatwy sposób przekonwertowany do NSString używając inicjatora initWithData:encoding:
Oto wynik w konsoli powyższego kodu.
2013-06-25 20:13:49.741 iPhone_insert[6258:907] Udało się serializować słownik jako JSON
2013-06-25 20:13:49.746 iPhone_insert[6258:907] JSON String = {
"Last Name" : "Zdzisławski",
"First Name" : "Tom",
"children" : [
" Stefan Zdzisławski",
" Shin-Chan Zdzisławski",
" Katarzyna Zdzisławska",
" Franko Zdzisławski",
" Darek Zdzisławski"
],
"Age" : 24
}
Udało serializować obiekt równie dobrze możemy go zdeserializować używając metody JSONObjectWithData:options:error:klasy NSJSONSerialization.
Obiekt zwrócony przez tą metodę będzie albo słownikiem, albo tablicą w zależności od struktury JSONA.
Poniżej znajduję mix kodu serializującego i deserializującego. Najpierw serializuję słownik do obiektu JSON potem go zdeserializuje do słownika. Na końcu wyświetlam wyniki metod.
- (IBAction)btn_DescJsonClick:(id)sender {
NSMutableDictionary *dictionary =
[NSMutableDictionary dictionaryWithDictionary:@{
@"First Name" : @"Tom",
@"Last Name" : @"Zdzisławski",
@"Age" : @24
}];
NSArray *arrayOfTomsChildren = @[
@" Stefan Zdzisławski",
@" Shin-Chan Zdzisławski",
@" Katarzyna Zdzisławska",
@" Franko Zdzisławski",
@" Darek Zdzisławski"
];
[dictionary setValue:arrayOfTomsChildren forKey:@"children"];
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject:dictionary
options:NSJSONWritingPrettyPrinted
error:&error];
/* Deserializacja */
id jsonObject = [NSJSONSerialization
JSONObjectWithData: jsonData
options:NSJSONReadingAllowFragments
error:&error ];
if (jsonObject != nil &&
error == nil ){
NSLog(@"Sukces desarilazcji..." );
if ([jsonObject isKindOfClass:[NSDictionary class ]]){
NSDictionary *deserializedDictionary = (NSDictionary *)jsonObject ;
NSLog(@"Deserialized JSON Dictionary = %@" , deserializedDictionary);
}
else if ([jsonObject isKindOfClass:[NSArray class ]]){
NSArray *deserializedArray = (NSArray *)jsonObject ;
NSLog(@"Deserialized JSON Array = %@" , deserializedArray);
} else {
/* Jakiś inny obiekt został zwrócony. To nie powinno się zdarzyć */
}
}
else if (error != nil){
NSLog(@"Błąd w trakcie desarlizacji" );
}
}
Istnieje kilka opcji parametrów dla metody JSONObjectithData:options:error klasy.NSJSONSerialization.
Klauzura options akceptuje następujące wartości:
- NSJSONReadingMutableContainers.
- Słownik albo tablica może zostać zwrócona przez metodę JSONObjectWithData:options:error:.Mówiąc prościej ta metoda zwróci albo instancje NSMutableArray, albo NSMutableDictionary. Każda z tych kolekcji może być modyfikowana “Mutable”.
- NSJSONReadingMutableLeaves
- Wartość ukazana w postaci drzewa jako napis NSMutableString.
- NSJSONReadingAllowFragments
- Pozwala na deserializacja danych JSON, których element root nie jest słownikiem lub tablicą.
W tym wypadku użyłem opcji NSJSONReadingAllowFragments, gdyż element root nie jest słownikiem ani tablicą.
Oto wynik deserializacji.
2013-06-25 20:24:05.218 iPhone_insert[6287:907] Sukces deseralizacji...
2013-06-25 20:24:05.223 iPhone_insert[6287:907] Deserialized JSON Dictionary = {
Age = 24;
"First Name" = Tom;
"Last Name" = "Zdzisławski";
children = (
" Stefan Zdzisławski",
" Shin-Chan Zdzisławski",
" Katarzyna Zdzisławska",
" Franko Zdzisławski",
" Darek Zdzisławski"
);
}
Miłego programowania na IPhona.