2011-11-21 44 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

谢谢,是的,这也是我的想法,但希望有人为我做了艰苦的工作。我想我会用你的例子作为基础,鞭打自己 –