我需要将objective-c对象序列化和反序列化为JSON以存储在CouchDB中。人们是否有任何示例代码用于一般解决方案的最佳实践?我查看了一些JSON框架,它们在NSDictionary / NSArray级别停止。即很多框架会将NSDictionary / NSArray序列化和反序列化为JSON。但我仍然需要将NSDictionary转换为Objective-C对象。
为了使事情变得更复杂,我的对象A可以引用对象B的NSArray / NSDictionary。
我的问题与此问题非常相似,并且增加了收集要求。
答案 0 :(得分:35)
最后,我们可以使用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]);
这是来自Serialize示例的NSLog结果:
{ "accounting" : [{ "firstName" : "Uee",
"lastName" : "Bae",
"age" : 22 }
],
"sales" : [{ "firstName" : "Sara",
"lastName" : "Jung",
"age" : 20 }
]}
答案 1 :(得分:10)
听起来您正在寻找一个序列化库,它可以让您将自己的自定义类的对象转换为JSON,然后重新构建它们。属性列表类型的序列化(NSArray,NSNumber等)已存在于第三方库中,甚至内置于OS X 10.7和iOS 5中。
所以,我认为答案基本上是“不”。我在一个或两个月之前在cocoa-dev邮件列表上问过这个确切的问题,而我最接近的是来自Mike Abdullah,他指着他写的一个实验性图书馆:
https://github.com/mikeabdullah/KSPropertyListEncoder
这会将对象归档到内存中的属性列表,但正如我所说,已有用于将这些对象转换为JSON的API。
还有一款名为Objectify的商业应用声称可以做类似的事情:
http://tigerbears.com/objectify/
我可能会最终实现你所要求的作为我的CouchCocoa库的一部分,但我还没有潜入这项任务。
答案 2 :(得分:7)
借助 NSDictionary,NSArray和NSJSONSerialization
,您可以轻松地将JSON功能添加到NSObject类中只要看一下这个例子就很容易理解。
将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,然后将其分配给类属性。
我确信使用上面使用的方法和想法可以序列化&amp;轻松地对复杂的json进行反序列化。
答案 3 :(得分:4)
您可以尝试JTObjectMapping。他们的描述:
JTObjectMapping - 受RestKit的启发。一个非常简单的objective-c框架,它将来自NSDictionary或NSArray的JSON响应映射到iOS的NSObject子类。
它非常小(与RestKit不同)并且效果很好。
答案 4 :(得分:2)
使用RestKit库的对象映射系统可以实现这一点。
答案 5 :(得分:2)
我有一个简单的模型类,我想把它变成一个JSON-Object。
为此,我在模型类中添加了一个“jsonData”方法: 该方法将模型属性转换为基础对象(int数字转换为NSNumber对象等) 然后使用这些对象和相应的键(以及后面的JSON键)填充字典。 在(可选)检查有效性之后,使用NSJSONSerialization创建JSON数据对象 类“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;
}
答案 6 :(得分:1)