Search code examples
iosobjective-cjsongenericsjsonkit

iOS: Serialize/Deserialize complex JSON generically from NSObject class


Anyone have idea how to serialize nested JSON based on NSObject class? There is a discussion to serialize simple JSON here , but it is not generic enough to cater complex nested JSON.

Imagine this is the result of 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 }
                  ]}

From this class:

@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

How to serialize/deserialize them based on class generically?

EDIT

Currently i'm able to generate payload like this based on any class:

NSMutableDictionary *Payload = [self serialize:objClass];

But it does not cater nested complex JSON. Anyone have better solution for this? This library for C# cater serialize/deserialze based on object class. I want to reproduce something the same based on NSObject


Solution

  • Finally we can solve this problem easily using JSONModel. This is the best method so far. JSONModel is a library that generically serialize/deserialize your object based on Class. You can even use non-nsobject based for property like int, short and float. It can also cater nested-complex JSON.

    1) Deserialize example. By referring to above example, in header file:

    #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
    

    in implementation file:

    #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) Serialize Example. In implementation file:

    #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]);
    

    And this is NSLog result from Serialize example:

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