Сериализация и десериализация объектов Objective C в JSON - PullRequest
32 голосов
/ 24 августа 2011

Мне нужно сериализовать и десериализовать объекты target-c в JSON для хранения в CouchDB. Есть ли у людей примеры кода для лучшей практики для общего решения? Я посмотрел на несколько JSON-фреймворков, и они остановились на уровне NSDictionary / NSArray. то есть многие фреймворки будут сериализовать и десериализовать NSDictionary / NSArray в JSON. Но мне все еще нужно выполнить работу по преобразованию NSDictionary в объекты Objective-C.

Чтобы сделать вещи более сложными, мой объект A может иметь ссылку на NSArray / NSDictionary объекта B.

Мой вопрос очень похож на этот вопрос с добавлением требования о сборе.

Создание пользовательского класса из NSDictionary

Ответы [ 7 ]

35 голосов
/ 27 мая 2013

Наконец, мы можем легко решить эту проблему, используя JSONModel .Это лучший метод на данный момент.JSONModel - это библиотека, которая обобщенно сериализует / десериализует ваш объект на основе Class.Вы даже можете использовать не-nsobject для таких свойств, как int, short и float.Он также может обслуживать вложенный комплекс 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 }
                  ]}

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 из примера Serialize:

{ "accounting" : [{ "firstName" : "Uee",  
                    "lastName"  : "Bae",
                    "age"       : 22 }
                 ],                            
  "sales"      : [{ "firstName" : "Sara", 
                    "lastName"  : "Jung",
                    "age"       : 20 }
                  ]}
10 голосов
/ 25 августа 2011

Похоже, вы ищете библиотеку сериализации, которая может позволить вам конвертировать объекты ваших собственных пользовательских классов в JSON, а затем восстанавливать их обратно.Сериализация типов списка свойств (NSArray, NSNumber и т. Д.) Уже существует в сторонних библиотеках и даже встроена в OS X 10.7 и iOS 5.

Итак, я думаю, что ответ в основном "нет",Я задал этот точный вопрос месяц или два назад в списке рассылки «Какао-разработчик», и ближе всего к нему попал Майк Майкл Абдулла, который указал на экспериментальную библиотеку, которую он написал:

https://github.com/mikeabdullah/KSPropertyListEncoder

Это архивирует объекты в списках свойств в памяти, но, как я уже сказал, уже есть API для их преобразования в JSON.

Есть также коммерческое приложение под названием Objectify, которое утверждает, что может делатьчто-то похожее:

http://tigerbears.com/objectify/

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

https://github.com/couchbaselabs/CouchCocoa

7 голосов
/ 08 января 2014

Вы можете легко добавить возможность JSON в класс NSObject с помощью NSDictionary, NSArray и NSJSONSerialization

Сериализация:

Просто посмотрите на пример, это будет очень легкочтобы понять.

Добавление возможности JSON в класс NSObject: -

@interface JsonClassEmp : NSObject

@property(strong,nonatomic)NSString *EmpName,*EmpCode;

-(NSDictionary*)GetJsonDict;

@end

@implementation JsonClassEmp

@synthesize EmpName,EmpCode;

//Add all the properties of the class in it.
-(NSDictionary*)GetJsonDict
{
    return [NSDictionary dictionaryWithObjectsAndKeys:EmpName,@"EmpName",EmpCode,@"EmpCode", nil];
}

@end

Генератор строк JSON: -

IniOS 5, Apple представила NSJSONSerialization для анализа строк JSON, поэтому с помощью этого мы сгенерируем строку JSON.

-(NSString*)GetJSON:(id)object
{
    NSError *writeError = nil;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&writeError];

    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    return jsonString;
}

Переход к реализации Apple всегда безопаснее, поскольку у вас есть гарантия, что она будет поддерживаться ив курсе.

Способ использования: -

- (void)viewDidLoad
{
    [super viewDidLoad];

    JsonClassEmp *emp1=[[JsonClassEmp alloc]init];

    [emp1 setEmpName:@"Name1"];

    [emp1 setEmpCode:@"1"];

    JsonClassEmp *emp2=[[JsonClassEmp alloc]init];

    [emp2 setEmpName:@"Name2"];

    [emp2 setEmpCode:@"2"];

    //Add the NSDictionaries of the instances in NSArray
    NSArray *arrEmps_Json=@[emp1.GetJsonDict,emp2.GetJsonDict];

    NSLog(@"JSON Output: %@", [self GetJSON:arrEmps_Json]);

}

Ссылка

Десериализация:

Это обычный способ передачи десериализованных данных в NSDictionary или NSArray с последующим назначением их свойствам класса.

Я уверен, что с помощью методов и идей, использованных выше, вы можете легко сериализовать и десериализовать сложные json.

4 голосов
/ 08 июня 2012

Вы можете попробовать JTObjectMapping .Их описание:

JTObjectMapping - по мотивам RestKit.Очень простая библиотека target-c, которая отображает ответ JSON от NSDictionary или NSArray на подклассы NSObject для iOS.

Это очень мало (в отличие от RestKit) и прекрасно работает.

2 голосов
/ 05 сентября 2015

У меня есть простой класс модели, который я хотел превратить в JSON-объект.

Для этого я добавил метод «jsonData» в свой класс модели: метод превращает свойства модели вфундаментальные объекты (целые числа в NSNumber объектах и ​​т. д.) Затем в словарь добавляются эти объекты и соответствующие ключи (также более поздние ключи JSON).После (необязательной) проверки на достоверность объект данных JSON создается с помощью метода класса NSJSONSerialization „dataWithJSONObject“ и возвращается.

- (NSData *)jsonData {

NSDictionary *root = @{@"Sport" : @(_sportID),          // I´m using literals here for brevity’s sake
                       @"Skill" : @(_skillLevel),
                       @"Visibility" : @(_visibility),
                       @"NotificationRange" : @(_notificationRange)};

if ([NSJSONSerialization isValidJSONObject:root]) {
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:root
                                    options:0
                                      error:nil];
    return jsonData;
}
return nil;

}

2 голосов
/ 24 февраля 2012

Это возможно при использовании системы отображения объектов библиотеки RestKit.

http://restkit.org/

1 голос
/ 11 ноября 2011
...