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



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

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

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

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

141   7  

7 ответов:

Похоже, вы ищете библиотеку сериализации, которая позволит вам конвертировать объекты ваших собственных пользовательских классов в 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

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

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

Вы можете легко добавить возможность 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 *arrEmps_Json=@[emp1.GetJsonDict,emp2.GetJsonDict];

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

}

Ссылка

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

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

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

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

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

Он очень маленький (в отличие от RestKit) и отлично работает.

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

Http://restkit.org/

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

Для этой цели я добавил"jsonData" -метод в мой класс модели: Метод превращает свойства модели в базовые объекты (int numbers в NSN number objects и т. д.) Затем словарь заполняется этими объектами и соответствующими ключами (также более поздними ключами 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;

}

    Ничего не найдено.

Добавить ответ:
Отменить.