我正在尝试构建一个解析器/objectMapper,它将为我从 REST 服务使用的 JSON 构建 Objective C 对象。
我从 RestKit 中获得了一些灵感,让我的实体都拥有一个“解码列表”,它告诉映射器哪些 JSON 键与哪些对象相关。像这样:
//ObjectEntity implementation
+ (NSDictionary*) mapProperties {
/*
localPropertiy - JSONProperty
*/
return @{
@"name": @"name",
@"category": @"category",
@"possible_scopes": @"possibleScopes",
@"possible_descriptions": @"possibleDescriptions",
@"key": @"keys"
};
}
+ (NSDictionary*) mapRelations {
return [NSDictionary dictionary];
}
我这样做是因为我喜欢将这些可变值封装在它们引用的对象中。让 Mapper 知道的越少越好。
映射器做这样的事情:
+ (NSArray*) parseData:(NSData*) jsonData intoObjectsOfType:(Class) objectClass {
//Parser result from web service
NSError *error = nil;
CJSONDeserializer *deserializer = [CJSONDeserializer deserializer];
[deserializer setNullObject:nil];
NSArray *objects = [deserializer deserializeAsArray:jsonData error:&error];
NSMutableArray *result = [NSMutableArray array];
for (NSDictionary *o in objects) {
id <EntityProtocol> entity = [[objectClass alloc] init];
NSDictionary *jsonKeys = objectClass.mapProperties;
for (NSString *key in jsonKeys.allKeys) {
NSString *objectProperty = jsonKeys[key];
NSString *value = o[key];
if (value)
[entity setValue:value forKey:objectProperty];
}
[result addObject:entity];
}
return (NSArray*)result;
}
所以我像这样向解析器/映射器发送消息:
NSArray *objects = [ObjectParser parseData:self.responseData intoObjectsOfType:ObjectEntity.class];
这意味着解析器必须知道我的根对象是什么,这很好,因为从 Web 服务检索它的对象当然知道这一点。
以上仅适用于没有嵌套对象的 JSON,我一直在尝试构建解析器以便它也将关系考虑在内,构建所需的对象并将它们插入到根对象中,这需要递归而且我不断陷入死胡同。
我想要一些帮助,以了解我如何处理这个问题或任何见解,就好像这样的东西作为一个图书馆存在一样。也许是为了使用,也许只是为了解决我遇到问题的部分。
提前谢谢你。
最佳答案
考虑使用 RestKit:http://restkit.org
这个框架拥有您需要的一切——REST 和 JSON 抽象、对象映射、甚至 Core Data 支持和许多非常有用的东西,所有这些都以可定制和优雅的方式实现。
更新: 好的,在编写另一种映射方法时,我决定不能再这样做了,于是做了一个小框架。它内省(introspection)对象的属性,稍加调整即可为您提供免费的漂亮描述、isEqual/hashCode、免费的 NSCoding 支持,并允许生成到/从 JSON 映射器(好吧,实际上是 NSDictionary,但谁会用它做别的事情)。所有 NSNull 检查、JSON 中缺失的字段、JSON 中新的意外字段都得到妥善处理并正确报告。
如果有人希望将此分享给公众,您可以给我一些赞或评论。我最终会这样做,但我可能会考虑更快地分享它。
关于objective-c - 从 JSON 到 NSObjects 的对象映射库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6137030/