iOS: сериализация / десериализация сложного JSON в общем виде из класса NSObject

кто-нибудь знает, как сериализовать вложенный JSON на основе класса NSObject? Существует обсуждение для сериализации простого JSON здесь, но он недостаточно общий для обслуживания сложного вложенного JSON.

представьте, что это результат JSON:

{ "accounting" : [{ "firstName" : "John",  
                    "lastName"  : "Doe",
                    "age"       : 23 },

                  { "firstName" : "Mary",  
                    "lastName"  : "Smith",
                    "age"       : 32 }
                              ],                            
  "sales"      : [{ "firstName" : "Sally", 
                    "lastName"  : "Green",
                    "age"       : 27 },

                  { "firstName" : "Jim",   
                    "lastName"  : "Galley",
                    "age"       : 41 }
                  ]}

из этого класса:

@interface Person : NSObject{}
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@end

@interface Department : NSObject{}
@property (nonatomic, strong) NSMutableArray *accounting; //contain Person class
@property (nonatomic, strong) NSMutableArray *sales; //contain Person class
@end

как сериализовать / десериализовать их на основе класса в целом?

редактировать

В настоящее время я могу генерировать полезную нагрузку как это основано на любом классе:

NSMutableDictionary *Payload = [self serialize:objClass];

но он не обслуживает вложенный сложный JSON. Кто-нибудь есть лучшее решение для этого? библиотека для C# cater serialize/deserialze на основе класса объектов. Я хочу воспроизвести что-то такое же на основе NSObject

3 ответов


наконец, мы можем легко решить эту проблему, используя JSONModel. Это пока лучший метод. Jsonmodel-это библиотека, которая в целом сериализует / десериализует ваш объект на основе класса. Вы даже можете использовать не-nsobject на основе свойства, как int, short и float. Он также может обслуживать вложенный комплекс JSON.

1) десериализовать пример. Ссылаясь на приведенный выше пример, в заголовочном файле:

#import "JSONModel.h"

@interface Person : JSONModel 
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@end

@protocol Person;

@interface Department : JSONModel
@property (nonatomic, strong) NSMutableArray<Person> *accounting;
@property (nonatomic, strong) NSMutableArray<Person> *sales;
@end

в реализации файл:

#import "JSONModelLib.h"
#import "myJSONClass.h"

NSString *responseJSON = /*from example*/;
Department *department = [[Department alloc] initWithString:responseJSON error:&err];
if (!err)
{
    for (Person *person in department.accounting) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }

    for (Person *person in department.sales) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }
}

2) Пример Сериализации. В файле реализации:

#import "JSONModelLib.h"
#import "myJSONClass.h"

Department *department = [[Department alloc] init];

Person *personAcc1 = [[Person alloc] init];
personAcc1.firstName = @"Uee";
personAcc1.lastName = @"Bae";
personAcc1.age = [NSNumber numberWithInt:22];
[department.accounting addOject:personAcc1];

Person *personSales1 = [[Person alloc] init];
personSales1.firstName = @"Sara";
personSales1.lastName = @"Jung";
personSales1.age = [NSNumber numberWithInt:20];
[department.sales addOject:personSales1];

NSLog(@"%@", [department toJSONString]);

и это результат NSLog из примера сериализации:

{ "accounting" : [{ "firstName" : "Uee",  
                    "lastName"  : "Bae",
                    "age"       : 22 }
                 ],                            
  "sales"      : [{ "firstName" : "Sara", 
                    "lastName"  : "Jung",
                    "age"       : 20 }
                  ]}

вы должны знать заранее, какой объект вы будете десериализации. В этом случае вы собираетесь десериализоваться в NSDictionary имеет два свойства: "учет " и"продажи". Каждое из этих свойств будет экземпляром NSArray. Массивы будут иметь экземпляры NSDictionary.

поскольку вы знаете, что каждый из этих объектов действительно после десериализации JSON в собственные объекты вы можете создавать новые экземпляры своих классов из десериализованный объект. Например:

JSONDecoder decoder = [[JSONDecoder alloc] init];
NSObject notJSON = [decoder objectWithData:jsonData];
// where jsonData is an NSData representation of your JSON
[decoder release];

Person person1 = (Person)[notJSON objectForKey:@"accounting"][0];

учитывая этот пример, вы должны иметь возможность экстраполировать на более общий десериализатор. То есть вы хотите перебрать свои данные, чтобы создать глубокую копию вашего "неизвестного" универсального объекта в "известный" конкретный объект.


может быть, это может помочь BWJSONMatcher. Это поможет вам легко сопоставить строку JSON или объект JSON с вашей моделью данных с одной строкой кода.

...
NSString *jsonString = @"{your-json-string}";
YourValueObject *dataModel = [YourValueObject fromJSONString:jsonString];

NSDictionary *jsonObject = @{your-json-object};
YourValueObject *dataModel = [YourValueObject fromJSONObject:jsonObject];
...
YourValueObject *dataModel = instance-of-your-value-object;
NSString *jsonString = [dataModel toJSONString];
NSDictionary *jsonObject = [dataModel toJSONObject];
...