【问题标题】:Mapping nested objects with RestKit in Xcode using Objective-C使用 Objective-C 在 Xcode 中使用 RestKit 映射嵌套对象
【发布时间】:2011-12-09 23:20:33
【问题描述】:

在 mja 的帮助下,我成功地使用 RestKit 和 Objective-C 设置了简单的对象映射。请看我之前的问题here。

我的下一步是尝试以同样的方式处理嵌套的 JSON。

我的 JSON 看起来像这样,外部是带有一些嵌套“投票”的 CandidatePhrase:

{ "Id":33696,
"Phrase": "phrase",
"BadCount":0,
"Votes":[{"Id":447,"OriginalId":33696,"Votes":2,"Translation":"translation 1"},
{"Id":746,"OriginalId":33696,"Votes":1,"Translation":"translation 2"},
{"Id":747,"OriginalId":33696,"Votes":1,"Translation":"translation 3"}
]}

我在 AppDelegate 中创建了如下关系:

[candidatePhraseMapping mapKeyPath:@"votes" toRelationship:@"vote" withMapping:voteMapping];

当我在控制器中调用 make 我的请求时,我可以处理 CandidatePhrase 的其余部分,但我不确定如何将嵌套的“投票”对象映射到一个数组中,以便我可以在其中使用它们一个表格视图

(类似这样的伪代码...)

// Store the votes in an array
_votes = [[NSArray alloc] initWithObjects:myCandidatePhrase.votes, nil];

这是我的 CandidatePhrase 对象

@interface CandidatePhrase : NSObject

@property (nonatomic, retain) NSNumber* ident;
@property (nonatomic, retain) NSNumber* badcount;
@property (nonatomic, retain) NSString* phrase;
@property (nonatomic, retain) NSArray* votes;

@end

和我的投票对象

@interface Vote : NSObject

@property (nonatomic, retain) NSNumber* ident;
@property (nonatomic, retain) NSNumber* originalId;
@property (nonatomic, retain) NSNumber* votecount;
@property (nonatomic, retain) NSString* translation;

+ (id)voteWithTranslationId:(NSNumber *)ident translation:(NSString *)translation;

@end

任何帮助将不胜感激。

编辑

下面是我的映射代码

// Votes Mapping

RKObjectMapping* voteMapping = [RKObjectMapping mappingForClass:[Vote class]];
[voteMapping mapKeyPath:@"Id" toAttribute:@"ident"];
[voteMapping mapKeyPath:@"OriginalId" toAttribute:@"originalId"];
[voteMapping mapKeyPath:@"Votes" toAttribute:@"votecount"];
[voteMapping mapKeyPath:@"Translation" toAttribute:@"translation"];

[[manager mappingProvider] addObjectMapping:voteMapping];

// Candidate Phrase Mapping
RKObjectMapping *candidatePhraseMapping = [RKObjectMapping mappingForClass:[CandidatePhrase class]];

[candidatePhraseMapping mapKeyPath:@"Id" toAttribute:@"ident"];
[candidatePhraseMapping mapKeyPath:@"Phrase" toAttribute:@"phrase"];
[candidatePhraseMapping mapKeyPath:@"BadCount" toAttribute:@"badcount"];

[candidatePhraseMapping mapKeyPath:@"Votes" toRelationship:@"votes" withMapping:voteMapping];

[[manager mappingProvider] addObjectMapping:candidatePhraseMapping];

为了清楚起见,下面是我尝试访问控制器上的投票项的方式

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object 
{ 
    CandidatePhrase *myCandidatePhrase = (CandidatePhrase*)object;
    self.candidateText.text = myCandidatePhrase.phrase; <-- works fine

    _votes = [[NSArray alloc] initWithObjects:myCandidatePhrase.votes, nil];
    for (id o2 in _votes) { 
        //Vote *vote = o2; 
        NSLog(@"Item name: %@", o2); <-- sees object but crashes
    }

    NSLog(@"Votes: %@", myCandidatePhrase.votes); 
    _votes = [[NSArray alloc] initWithObjects:myCandidatePhrase.votes, nil];
     [_votesTableView reloadData];
 } 

我的表绑定了

Vote *vote = [_votes objectAtIndex:indexPath.row];
cell.textLabel.text = vote.translation;

【问题讨论】:

    标签: objective-c xcode restkit


    【解决方案1】:

    您不需要手动管理嵌套的 NSArray。我相信问题可能只是一个简单的拼写错误,因为您将 keyPath 映射为“votes”,但您的 json 包含带有大写“V”的“Votes”。

    [candidatePhraseMapping mapKeyPath:@"Votes" toRelationship:@"votes" withMapping:voteMapping];
    

    如果这没有帮助,请随时发表评论并通过voteMapping 更新您的问题。

    另外,didLoadObject 的内容也可以简化:

    //in .h file
    @property (nonatomic, retain) NSArray* votes;
    
    // in implementation
    @synthesize votes;
    
    ...
    - (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object 
    { 
        CandidatePhrase *myCandidatePhrase = (CandidatePhrase*)object;
        self.candidateText.text = myCandidatePhrase.phrase;
        self.votes = myCandidatePhrase.votes;
    }
    

    【讨论】:

    • 谢谢。我更新了上面的代码并收到错误“NSUnknownKeyException”,原因:“[ valueForUndefinedKey:]:此类不符合键值编码的键投票。”
    • 如果有帮助,我还更新了用于访问另一端的投票属性的代码。
    • 嗨,我认为这行是问题所在... _votes = [[NSArray alloc] initWithObjects:myCandidatePhrase.votes, nil]; myCandidatePhrase.votes 本身就是一个数组。您是否想要一个只有一个对象的数组 - 作为投票数组?
    • 阅读您的最后一次编辑,显然不是。为什么不只保留整个 (CandidatePhrase*) 对象;在一个属性? self.candidateText 属性是什么类型的?
    • 不客气。我还根据评论中的提示更新了我的答案。
    猜你喜欢
    • 2014-12-30
    • 2014-02-25
    • 2012-01-09
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 2014-09-01
    相关资源
    最近更新 更多