2014-01-24 5 views
9

사용자 정의 개체에있는 NSDictionary 변환하는 방법 :내가 JSON 개체가

@interface Order : NSObject 

@property (nonatomic, retain) NSString *OrderId; 
@property (nonatomic, retain) NSString *Title; 
@property (nonatomic, retain) NSString *Weight; 

- (NSMutableDictionary *)toNSDictionary; 
... 

- (NSMutableDictionary *)toNSDictionary 
{ 

    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 
    [dictionary setValue:self.OrderId forKey:@"OrderId"]; 
    [dictionary setValue:self.Title forKey:@"Title"]; 
    [dictionary setValue:self.Weight forKey:@"Weight"]; 

    return dictionary; 
} 

문자열 이것은이다 :

{ 
    "Title" : "test", 
    "Weight" : "32", 
    "OrderId" : "55" 
} 

내가 코드를 문자열 JSON을 얻을 :

NSMutableDictionary* str = [o toNSDictionary]; 

    NSError *writeError = nil; 

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:str options:NSJSONWritingPrettyPrinted error:&writeError]; 
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 

지금을 JSON 문자열에서 객체를 만들고 맵핑해야합니다. :

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
    NSError *e; 
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e]; 

이렇게하면 NSDictionary로 채워집니다. 이 사전에서 객체를 가져 오려면 어떻게해야합니까?

답변

18

추가 새로운 initWithDictionary: 방법 Order에 :

- (instancetype)initWithDictionary:(NSDictionary*)dictionary { 
    if (self = [super init]) { 
     self.OrderId = dictionary[@"OrderId"]; 
     self.Title = dictionary[@"Title"]; 
     self.Weight = dictionary[@"Weight"];  
    } 
    return self;  
} 

당신이 JSON 얻을 어디 방법 Order.h 파일

initWithDictionary의 서명을 추가하는 것을 잊지 마세요 :

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
NSError *e; 
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e]; 
Order *order = [[Order alloc] initWithDictionary:dict]; 
+1

, 당신은 하나 initWithDictionay 하나를 구현해야합니다 ... 좀 더 유연한 솔루션이 예 : HTTPS : //github.com/Infusion-apps/IAModelBase – ingaham

+0

또한 https://github.com/oarrabi/IAModelBase/issues 문제를 참조하십시오.하지만이를 관리 할 수 ​​있습니다. 예, 좋습니다. 어떤 질문이라도 저에게 연락하십시오. –

11

개체의 속성 이름이 JSON 문자열의 키와 일치하는 경우 다음을 수행 할 수 있습니다.

개체에 JSON 문자열을 매핑하려면 먼저 문자열을 NSDictionary로 변환 한 다음 키 - 값 코딩을 사용하여 각 속성을 설정하는 NSObject에서 메서드를 사용할 수 있습니다.

NSError *error = nil; 
NSData *jsonData = ...; // e.g. [myJSONString dataUsingEncoding:NSUTF8Encoding]; 
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingOptionsAllowFragments error:&error]; 

MyObject *object = [[MyObject alloc] init]; 
[object setValuesForKeysWithDictionary:jsonDictionary]; 

키가 일치하지 않으면 개체 클래스에서 NSObject -[NSObject valueForUndefinedKey:]의 인스턴스 메서드를 재정의 할 수 있습니다.

Object를 JSON에 매핑하려면 Objective-C 런타임을 사용하여 자동으로 수행하십시오. 어떤 NSObject의 서브 클래스에 다음 작품 :

#import <objc/runtime.h> 

- (NSDictionary *)dictionaryValue 
{ 
    NSMutableArray *propertyKeys = [NSMutableArray array]; 
    Class currentClass = self.class; 

    while ([currentClass superclass]) { // avoid printing NSObject's attributes 
     unsigned int outCount, i; 
     objc_property_t *properties = class_copyPropertyList(currentClass, &outCount); 
     for (i = 0; i < outCount; i++) { 
      objc_property_t property = properties[i]; 
      const char *propName = property_getName(property); 
      if (propName) { 
       NSString *propertyName = [NSString stringWithUTF8String:propName]; 
       [propertyKeys addObject:propertyName]; 
      } 
     } 
     free(properties); 
     currentClass = [currentClass superclass]; 
    } 

    return [self dictionaryWithValuesForKeys:propertyKeys]; 
} 
0

이 작업을 수행 할 수있는 완벽한 방법은 직렬화 라이브러리를 사용하는 것입니다은/직렬화 많은 라이브러리를 사용할 수 있지만 내가 좋아하는 사람은 https://github.com/jagill/JAGPropertyConverter

가 할 수 JagPropertyConverter 입니다 사용자 지정 개체를 NSDictionary로 변환하거나 그 반대로
심지어 사전이나 배열 또는 개체 (예 : 합성) 내의 모든 사용자 지정 개체를 변환 할 수 있습니다 (예 : 구성)

JAGPropertyConverter *converter = [[JAGPropertyConverter alloc]init]; 
converter.classesToConvert = [NSSet setWithObjects:[Order class], nil]; 

@interface Order : NSObject 

@property (nonatomic, retain) NSString *OrderId; 
@property (nonatomic, retain) NSString *Title; 
@property (nonatomic, retain) NSString *Weight; 
@end 



//For Dictionary to Object (AS IN YOUR CASE) 

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 
[dictionary setValue:self.OrderId forKey:@"OrderId"]; 
[dictionary setValue:self.Title forKey:@"Title"]; 
[dictionary setValue:self.Weight forKey:@"Weight"]; 

Order *order = [[Order alloc]init]; 
[converter setPropertiesOf:order fromDictionary:dictionary]; 


//For Object to Dictionary 

Order *order = [[Order alloc]init]; 
order.OrderId = @"10"; 
order.Title = @"Title; 
order.Weight = @"Weight"; 

NSDictionary *dictPerson = [converter convertToDictionary:person]; 
4

당신의 속성 이름과 사전 키가 동일하다고 가정하면, 당신이 당신을 위해 더 편리 할 것입니다

- (void) setObject:(id) object ValuesFromDictionary:(NSDictionary *) dictionary 
{ 
    for (NSString *fieldName in dictionary) { 
     [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName]; 
    } 
} 
+1

필드가 누락 된 경우 충돌이 발생합니다. –

+0

도움이됩니다. 값을 설정하기 전에 object에서 fieldName을 확인하십시오. if ([object respondsToSelector : NSSelectorFromString (fieldName)]) { [개체 집합 값 : [dictionary objectForKey : fieldName] forKey : fieldName]; } } } –

+0

나에게 잘 맞습니다. 감사! –

3

모든 객체 변환하려면이 기능을 사용할 수 있습니다 :

- (instancetype)initWithDictionary:(NSDictionary*)dictionary { 
     if (self = [super init]) { 
      [self setValuesForKeysWithDictionary:dictionary];} 
     return self; 
    } 
0

정의 귀하 사용자 정의 클래스는 "AutoBindObject"에서 상속됩니다. NSDictionary에있는 키와 이름이 같은 속성을 선언하십시오.그런 다음 메서드 호출 :

[customObject loadFromDictionary:dic]; 

실제로 우리는 사전에 키에 다른 속성 이름을 매핑하도록 클래스를 사용자 정의 할 수 있습니다. 그 외에도 중첩 된 객체를 바인딩 할 수 있습니다.
이 데모를보십시오. 사용법은 간단합니다 : 당신은 많은 개체가있는 경우
https://github.com/caohuuloc/AutoBindObject