Подтвердить что ты не робот

Сериализация и десериализация объектов Objective-C в JSON

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

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

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

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

4b9b3361

Ответ 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/

Ответ 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;

}