我有一个像这样的JSON结构:
{
id:100
contactInfo: {
name: John Doe
city: New York
}
}
以及具有以下属性的相应Customer类,包括嵌套的contactInfo类。
Customer.id
Customer.contactInfo.name
Customer.contactInfo.city
是否可以将JSON数据直接转换为Customer类的实例?
我知道如何获取NSDictionary对象,但这非常麻烦且使用起来很冗长,而是希望将数据直接转换/反序列化到Customer类。
已获编辑附加信息:
在我使用过的其他语言中,内置支持将JSON反序列化为自定义对象。您所要做的就是将类标记为“Serializable”,并且无需在每个类中编写自定义代码即可反序列化JSON。
如果类具有嵌套类,则NSDictionary对象可能变得非常麻烦。使用像这样的自定义对象属性会更容易
Customer.contactInfo.name
而不是
[(NSDictionary*)[customerDict objectForKey:@"contactInfo"] objectForKey:@"name"]
因此我的问题是关于Objective-C中的标准内置反序列化器。
答案 0 :(得分:1)
我不知道为什么你认为这很麻烦。一种简单的方法是为客户对象创建一个初始化者,将字典作为参数。
通过这种方式,您可以将下载的数据作为JSON,将其反序列化为字典,然后将其传递给初始化程序,以便从字典中创建对象。
答案 1 :(得分:1)
许多JSON库中的任何一个都将解析您的JSON字符串并将其转换为NSDictionary。如果您不想自己编写解析器,则必须处理中间格式。但是,一旦拥有了NSDictionary,就可以使用键值编码(KVC)来设置对象的属性:
for (NSString *key in jsonDictionary) {
[customer setValue:[jsonDictionary objectForKey] forKey:key];
}
KVC内置于Cocoa中,并为所有对象定义setValue:forKey:
,因此您可以按名称设置属性,无论它们是如何定义的。
你必须做一些比上面循环更聪明的事情来处理你的内部ContactInfo类,但是你应该能够解决这个问题。为了安全起见(因为JSON可能来自网络),您可能希望制作密钥的白名单并循环使用,并使用valueForKeyPath:
/ setValue:forKeyPath:
来处理嵌套对象。
答案 2 :(得分:1)
从iOS5开始,如果官方支持JSON https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html
答案 3 :(得分:0)
考虑使用RestKit api(http://restkit.org/)及其对象映射系统......
以下是一些维基:https://github.com/RestKit/RestKit/wiki/Object-mapping
答案 4 :(得分:0)
为Customer类编写一个初始化程序,它将JSON数据作为参数,如:
-(id)initWithJSONData:(NSData*)data;
您可以实现该方法来执行Abizern建议的操作:将数据读入字典,然后从字典中提取所需的任何值。
如果你想获得想象力,另一种方法是在你的Customer类中采用NSCoding,然后创建一个反序列化JSON数据的NSCoder子类。这可能非常像NSKeyedUnarchiver。看起来似乎并不值得,除非你打算采用与你的一些课程相同的方法。
答案 5 :(得分:0)
使用此library,您可以执行以下操作:
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *customer = [parser objectWithString:jsonString];
然后,您可以使用以下方式访问您的媒体资源:
[customer objectForKey:@"id"];
[[customer objectForKey:@"contactInfo"] objectForKey:@"name"];
[[customer objectForKey:@"contactInfo"] objectForKey:@"city"];
然后,您可以在Customer类的init函数中使用此代码。例如:
- (id)initWithJSON:(NSString *)jsonString {
self = [super init]; // or whatever you need here
if (self) {
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *customer = [parser objectWithString:jsonString];
self.id = [customer objectForKey:@"id"];
self.contactInfo = [[NSDictionary alloc] initWithObjectsAndKeys:[[customer objectforKey:@"contactInfo"] objectForKey:@"name"], @"name", [[customer objectforKey:@"contactInfo"] objectForKey:@"city"], @"city"]
}
return self;
}