2011-11-21 43 views
6

我在服務器端廣泛地使用了Jackson將POJO轉換爲JSON,並想知道Objective C/iPhone SDK是否有類似的庫,反之亦然。 Objective C確實提供了反思,所以應該可以做出類似於Jackson的東西。傑克遜等同於iPhone?

+0

只是要清楚,因爲這裏可能有語言障礙;您希望代碼根據其聲明的屬性自動將對象序列化爲JSON? – Tommy

+0

是的,反過來也是有用的,因爲我們的服務器發送JSON編碼響應。 –

回答

4

您可以嘗試GoldenFleece,它使用靈感來自Jackson的約定優先配置模式在JSON和Objective-C對象之間進行轉換。

+0

這對我來說已經過了一年太晚了,我注意到了自我推銷,但是我很欣賞你寫這個圖書館的努力。目前的藝術狀況是痛苦的。 –

2

new iOS 5 APIs在閱讀/編寫JSON時提供了很棒的功能。這些實質上是您可以在iOS 4中使用的TouchJSON library的重映射。雖然我沒有在那裏看到那些將從示例有效內容生成POCO對象,但您可以創建只是NSDictionary實例的外觀的類,上述庫將返回。

例如:

@interface PBPhoto : NSObject { 
    NSDictionary* data_; 
} 

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

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


@end 

實現:

#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

不必爲每個類的每個屬性都實現getter。這就是反思可能有用的地方。 –

1

這一目標-C提供反射可能是今年的輕描淡寫,但很多東西是由低層次的只露C運行時間,因此是一點點鈍。

假設你想利用任意對象,並把它變成JSON,可能是聰明的做法是創建一個NSDictionary作爲中介,然後自己將其傳遞給NSJSONSerialization(或者構建字符串,因爲所有的第三方由於能夠反序列化的負擔,圖書館相當重量級)。

因此,舉例來說:

- (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; 
} 

然後你就可以在NSJSONSerialization使用+ dataWithJSONObject:options:error:與返回的字典。

換個角度來說,我想你會使用鍵值編碼setValue:forKey:方法,通過allKeysvalueForKey:從字典中獲取鍵和值。

+0

謝謝,是的,這也是我的想法,但希望有人爲我做了艱苦的工作。我想我會用你的例子作爲基礎,鞭打自己 –