2011-11-21 17 views
6

Użyłem Jacksona szeroko po stronie serwera do konwersji z POJO do JSON i zastanawiałem się, czy istnieje podobna biblioteka dla Objective C/iPhone SDK i na odwrót. Cel C dostarcza refleksji, więc powinno być możliwe zrobienie czegoś podobnego do Jacksona.Odpowiednik Jacksona dla iPhone'a?

+0

Dla jasności, ponieważ może tu istnieć bariera językowa; potrzebujesz kodu do serializowania obiektów do JSON automatycznie, na podstawie ich zadeklarowanych właściwości? – Tommy

+0

Tak, na odwrót byłoby również przydatne, ponieważ nasz serwer wysyła zakodowaną odpowiedź JSON. –

Odpowiedz

4

Możesz spróbować GoldenFleece, która konwertuje obiekty JSON i Objective-C, używając konwencji opartej na konwencji, inspirowanej przez Jackson.

+0

To za około rok za późno dla mnie i dostrzegam autopromocję, ale doceniam twój wysiłek pisania tej biblioteki. Obecny stan sztuki był bolesny. –

2

The new iOS 5 APIs zapewniają doskonałą możliwość odczytu/zapisu JSON. Są to w zasadzie powtórka z TouchJSON library, której możesz użyć w iOS 4. Chociaż nie widziałem zbyt wiele, które wygeneruje obiekty POCO z przykładowego ładunku, możesz utworzyć klasy, które są tylko fasadą dla instancji NSDictionary, którą wspomniane biblioteki powrócą.

Na przykład:

@interface PBPhoto : NSObject { 
    NSDictionary* data_; 
} 

@property (nonatomic, retain, readonly) NSDictionary *data; 

- (NSString*) photoId; 
- (NSString*) userId; 
- (NSString*) user; 
- (NSString*) title; 
- (id) initWithData:(NSDictionary*)data; 


@end 

Realizacja:

#import "PBPhoto.h" 

#define PHOTO_ID @"id" 
#define USER_ID @"user_id" 
#define USER @"user" 
#define TITLE @"title" 

@implementation PBPhoto 
@synthesize data = data_; 

- (id) initWithData:(NSDictionary*)data { 
    if ((self = [super init])) { 
     self.data = data; 
    } 

    return self; 
} 

- (NSString*) photoId { 
    return [super.data objectForKey:PHOTO_ID]; 
} 

- (NSString*) userId { 
    return [self.data objectForKey:USER_ID]; 
} 

- (NSString*) user { 
    return [self.data objectForKey:USER]; 
} 

- (NSString*) title { 
    return [self.data objectForKey:TITLE]; 
} 

- (void) dealloc { 
    [data_ release]; 
    [super dealloc]; 
} 

@end 
+1

Byłoby użyteczne, gdyby nie trzeba było implementować modułów pobierających dla każdej własności każdej klasy. Tam refleksja może być przydatna. –

1

To Objective-C zapewnia odbicie może być mało roku, ale wiele rzeczy jest narażony jedynie niskim poziomie C runtime i dlatego jest trochę tępy.

Zakładając chcesz wziąć dowolny obiekt i przekształcić go w JSON, chyba mądrą rzeczą jest stworzenie NSDictionary jako pośrednik, a następnie przekazać go do NSJSONSerialization (albo skonstruować ciąg siebie, ponieważ wszystkie osoby trzeciej biblioteki są dość ciężkie ze względu na ciężar możliwości deserializacji).

Tak więc, na przykład:

- (NSDictionary *)dictionaryOfPropertiesForObject:(id)object 
{ 
    // somewhere to store the results 
    NSMutableDictionary *result = [NSMutableDictionary dictionary]; 

    // we'll grab properties for this class and every superclass 
    // other than NSObject 
    Class classOfObject = [object class]; 
    while(![classOfObject isEqual:[NSObject class]]) 
    { 
     // ask the runtime to give us a C array of the properties defined 
     // for this class (which doesn't include those for the superclass) 
     unsigned int numberOfProperties; 
     objc_property_t *properties = 
        class_copyPropertyList(classOfObject, &numberOfProperties); 

     // go through each property in turn... 
     for(
       int propertyNumber = 0; 
       propertyNumber < numberOfProperties; 
       propertyNumber++) 
     { 
      // get the name and convert it to an NSString 
      NSString *nameOfProperty = [NSString stringWithUTF8String: 
            property_getName(properties[propertyNumber])]; 

      // use key-value coding to get the property value 
      id propertyValue = [object valueForKey:nameOfProperty]; 

      // add the value to the dictionary — 
      // we'll want to transmit NULLs, even though an NSDictionary 
      // can't store nils 
      [result 
        setObject:propertyValue ? propertyValue : [NSNull null] 
        forKey:nameOfProperty]; 
     } 

     // we took a copy of the property list, so... 
     free(properties); 

     // we'll want to consider the superclass too 
     classOfObject = [classOfObject superclass]; 
    } 

    // return the dictionary 
    return result; 
} 

Następnie można użyć + dataWithJSONObject:options:error: na NSJSONSerialization ze zwróconego słownika.

Aby przejść w drugą stronę, myślę, że użyłbyś metody kodowania klucz-wartość setValue:forKey:, pobierając klucze i wartości ze słownika za pośrednictwem allKeys i valueForKey:.

+0

Dzięki, tak, to też miałem na myśli, ale miałem nadzieję, że ktoś wykonał dla mnie ciężką pracę. Myślę, że użyję twojego przykładu jako podstawy i podniosę coś do siebie. –