我正在实施一个使用reddit Feed的简单iOS应用,我需要显示Feed评论。我正在使用RESTKit来执行ORM部分,我对映射注释感到烦恼。
Reddit评论可以有回复,回复可以有回复等等。这是一条评论树。这没什么大不了的。问题是在子节点中可能存在一个不同的节点(用于表示在该特定线程上有更多的注释要加载)。
这是一个JSON示例:
"replies":{
"data":
{
"after": null,
"before": null,
"children":
[
{
"data":
{
"approved_by": null,
"author": "InstaRamen",
"author_flair_css_class": null,
"author_flair_text": null,
"banned_by": null,
"body": "that or he counted it all wrong",
"body_html":"<div class=\"md\"><p>that or he counted it all wrong</p>\n</div>",
"controversiality": 0,
"created": 1405093511,
"created_utc": 1405064711,
"distinguished": null,
"downs": 0,
"edited": false,
"gilded": 0
"id": "ciubfdk",
"likes": null,
"link_id": "t3_2ae8oa",
"name": "t1_ciubfdk",
"num_reports": null,
"parent_id": "t1_ciuao19",
"replies":
{
"data":
{
"after": null,
"before": null,
"children":
[
{
"data":
{
"approved_by": null,
"author": "Everlasting",
"author_flair_css_class": null,
"author_flair_text": null,
"banned_by": null,
"body": "3, sir.",
"body_html":"<div class=\"md\"><p>3, sir.</p>\n</div>",
"controversiality": 0,
"created": 1405093986,
"created_utc": 1405065186,
"distinguished": null,
"downs": 0,
"edited": false,
"gilded": 0,
"id": "ciubj8h",
"likes": null,
"link_id": "t3_2ae8oa",
"name": "t1_ciubj8h",
"num_reports": null,
"parent_id": "t1_ciubfdk",
"replies":
{
"data":
{
"after": null,
"before": null,
"children":
[
{
"data":
{
"children":
[
"ciublgq"
],
"count": 0,
"id":"ciublgq",
"name":"t1_ciublgq",
"parent_id": "t1_ciubj8h"
},
"kind": "more"
}
],
"modhash": ""
},
"kind": "Listing"
},...
因此,您可以看到典型的评论回复具有
的结构replies
|-data
|-children
|-data
|- #comment key/values
但是“加载更多”项的结构为:
replies
|-data
|-children
|-data
|-children
|-more loading info...
我的DataObject是:
@interface RedditComment : NSObject
@property (nonatomic, copy) NSString *author;
@property (nonatomic, readwrite) NSInteger createdUTC;
@property (nonatomic, readwrite) NSInteger score;
@property (nonatomic, copy) NSString *subreddit;
@property (nonatomic, copy) NSString *subredditId;
@property (nonatomic, readwrite) NSInteger ups;
@property (nonatomic, copy) NSString *body;
@property (nonatomic, copy) NSArray *replies;
+ (RKObjectMapping*)restKitMapping;
@end
我的映射实现是:
@implementation RedditComment
+ (RKObjectMapping*)restKitMapping;
{
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[self class]];
[mapping addAttributeMappingsFromDictionary:@{
@"author": @"author",
@"created_utc": @"createdUTC",
@"score": @"score",
@"subreddit": @"subreddit",
@"subreddit_id": @"subredditId",
@"body": @"body",
@"ups": @"ups",
}];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"replies" toKeyPath:@"replies" withMapping:mapping]];
return mapping;
}
@end
这会产生错误:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0x1daa0d0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key body.'
这是因为“加载更多”节点没有正文密钥(它也缺少其他密钥,但这是RESTKit抱怨的第一个)。
我尝试使用动态映射块来更改运行时的映射,但无法弄清楚如何隔离有问题的节点(即“加载更多”)。
我的问题是如何区分“回复”JSON节点中的两个可能值?
对于相同的部分密钥,我可以有两个映射吗? 这是回复&gt;的映射。数据&gt;儿童&gt;数据和另一个回复&gt;数据&gt;儿童&gt;数据&gt;子的。如果是这样怎么办?
或者我的思路有什么不妥?
提前感谢所有能够帮助或只是花时间阅读的人...; - )
修改 包括响应描述符
根据评论的要求,这里是RKResponseDescriptor:
RKResponseDescriptor *commentResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[PPRedditComment restKitMapping]
method:RKRequestMethodAny
pathPattern:nil
keyPath:@"data"
statusCodes:nil];
编辑#2
包括一个“好评”节点,以显示我有兴趣映射到我的DO
"data":
{
"approved_by": null,
"author": "PerimeterBlue",
"author_flair_css_class":null,
"author_flair_text":null,
"banned_by":null,
"body": "This actually looks really cool.",
"body_html": "<div class=\"md\"><p>This actually looks really cool.</p>\n</div>",
"controversiality":0,
"created": 1405095679,
"created_utc": 1405066879,
"distinguished":null,
"downs": 0,
"edited": false,
"gilded": 0,
"id": "ciubwld",
"likes":null,
"link_id": "t3_2aelr4",
"name": "t1_ciubwld",
"num_reports": null,
"parent_id": "t3_2aelr4",
"replies": {...},
"saved": false,
"score": 48,
"score_hidden": false,
"subreddit": "gaming",
"subreddit_id": "t5_2qh03",
"ups": 48
}
答案 0 :(得分:0)
好的,显然有问题了。 Wain是对的:这是一个与道路相关的问题。
某些节点应该包含字典,有时包含字符串。在定义路径的方式中,这导致在NSString类上调用不存在的选择器(来自DO的属性)。因为它没有包含它,所以它就是BOOM!
映射已更正为:
+ (RKObjectMapping*)restKitMapping;
{
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[self class]];
[mapping addAttributeMappingsFromDictionary:@{
@"author": @"author",
@"created_utc": @"createdUTC",
@"score": @"score",
@"subreddit": @"subreddit",
@"subreddit_id": @"subredditId",
@"body": @"body",
@"ups": @"ups",
}];
RKDynamicMapping *dynamicMapping = [RKDynamicMapping new];
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
RKObjectMapping *result = mapping;
// When node is empty string don't map...
if([representation isKindOfClass:[NSString class]] && [representation isEqualToString:@""])
{
result = nil;
}
return result;
}];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"replies"
toKeyPath:@"replies"
withMapping:dynamicMapping]];
return mapping;
}
响应描述符更正为:
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[PPRedditFeedCollection restKitMapping]
method:RKRequestMethodAny
pathPattern:nil
keyPath:@"data"
statusCodes:nil];
希望这有助于某人! : - )