Сериализация и десериализация объектов Objective-C в JSON
Мне нужно сериализовать и десериализовать объекты objective-c в JSON для хранения в CouchDB. У людей есть какой-нибудь примерный код для лучшей практики для общего решения? Я посмотрел на несколько JSON-фреймворков, и они остановились на уровне NSDictionary/NSArray. т.е. множество фреймворков будет сериализовать и десериализовать NSDictionary/NSArray в JSON. Но мне все же приходится выполнять работу по преобразованию NSDictionary в объекты objective-c.
Чтобы сделать вещи более сложными, мой объект А может иметь ссылку на NSArray/NSDictionary Object Bs.
Мой вопрос очень похож на этот вопрос с добавлением требования к коллекции.
Создание пользовательского класса из NSDictionary
Ответы
Ответ 1
Похоже, вы ищете библиотеку сериализации, которая позволяет конвертировать объекты ваших собственных пользовательских классов в JSON, а затем восстанавливать их обратно. Сериализация типов списка свойств (NSArray, NSNumber и т.д.) Уже существует в сторонних библиотеках и даже встроена в OS X 10.7 и iOS 5.
Итак, я думаю, что ответ в основном "нет". Я задал этот точный вопрос месяц или два назад в списке рассылки cocoa -dev, и ближайший я попал в хит от Майка Абдуллы, указав на экспериментальную библиотеку, которую он написал:
https://github.com/mikeabdullah/KSPropertyListEncoder
Этот архив хранит объекты в списках свойств в памяти, но, как я уже сказал, уже есть API-интерфейсы для их преобразования в JSON.
Также есть коммерческое приложение под названием Objectify, которое утверждает, что может сделать что-то подобное:
http://tigerbears.com/objectify/
Возможно, я в конечном итоге реализую то, что вы просите, как часть моей библиотеки CouchCocoa, но я еще не нырнул в эту задачу.
https://github.com/couchbaselabs/CouchCocoa
Ответ 2
Наконец, мы сможем легко решить эту проблему, используя JSONModel. Это лучший метод. JSONModel - это библиотека, которая в общем случае сериализует/десериализует ваш объект на основе класса. Вы даже можете использовать не-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 }
]}
Ответ 3
Вы можете легко добавить 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: -
В iOS 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 *[email protected][emp1.GetJsonDict,emp2.GetJsonDict];
NSLog(@"JSON Output: %@", [self GetJSON:arrEmps_Json]);
}
Ссылка
Десериализация:
Обычный способ получения десериализованных данных в NSDictionary или NSArray затем присваивает его свойствам класса.
Я уверен, что используя описанные выше методы и идеи, вы можете легко сериализовать и десериализовать сложный json.
Ответ 4
Вы можете попробовать JTObjectMapping. Их описание:
JTObjectMapping - вдохновлен RestKit. Очень простая инфраструктура objective-c, которая отображает ответ JSON из NSDictionary или NSArray в подклассы NSObject для iOS.
Он очень маленький (в отличие от RestKit) и отлично работает.
Ответ 5
Это возможно с помощью системы отображения объектов библиотеки RestKit.
http://restkit.org/
Ответ 6
Вы имели в виду это?;)
http://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40010946
Ответ 7
У меня есть простой класс модели, который я хотел бы превратить в JSON-Object.
С этой целью я добавил метод jsonData в класс модели:
Метод превращает свойства модели в объекты основы (int numbers в объекты 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;
}