enab
enab

Reputation: 73

RestKit Nested Object of Same Type -- JSON Collection Error

I'm using RestKit to pull in comments which may have child comments (and those children may have children, etc).

I am able to pull in depth 0 comments without a problem. I have an array of comment objects for each depth 0 comment. Each parent comment is getting populated with the correct amount of child comments, but all of the properties within the children are nil (only the depth 0 parent is filled in with real data). RestKit gives me the warning:

W restkit.object_mapping:RKMappingOperation.m:645 WARNING: Detected a relationship mapping for a collection containing another collection. This is probably not what you want. Consider using a KVC collection operator (such as @unionOfArrays) to flatten your mappable collection.
W restkit.object_mapping:RKMappingOperation.m:646 Key path 'comments.comments' yielded collection containing another collection rather than a collection of objects:

Also, for each property I'm trying to map in a child, I receive this message (changes by property type)

E restkit.object_mapping:RKMappingOperation.m:440 Failed transformation of value at keyPath 'vote_count' to representation of type 'NSNumber': Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 "Failed transformation of value '( )' to NSNumber: none of the 2 value transformers consulted were successful." UserInfo=0x8e68280 {detailedErrors=( "Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 \"The given value is not already an instance of 'NSNumber'\" UserInfo=0x8e681e0 {NSLocalizedDescription=The given value is not already an instance of 'NSNumber'}", "Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3000 \"Expected an inputValue of type NSNull, but got a __NSArrayI.\" UserInfo=0x8e68210 {NSLocalizedDescription=Expected an inputValue of type NSNull, but got a __NSArrayI.}" ), NSLocalizedDescription=Failed transformation of value '( )' to NSNumber: none of the 2 value transformers consulted were successful.}

Despite the warning, I believe it is what I want -- but its struggling with mapping the child objects. It's complaining that it "got an NSArray" when it expected the property type, so I assume I'm doing my property mapping incorrectly.

This is my mapping:

+ (RKMapping *) dnCommentMapping {
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[DNComment class]];
[mapping addAttributeMappingsFromDictionary:@{
                                              @"id": @"commentId",
                                              @"body": @"body",
                                              @"body_html": @"bodyHTML",
                                              @"created_at": @"createdAt",
                                              @"depth": @"depth",
                                              @"vote_count": @"voteCount",
                                              @"user_id": @"userID",
                                              @"user_display_name": @"userDisplayName",
                                              }];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"comments.comments"
                                                                        toKeyPath:@"comments"
                                                                      withMapping:mapping]];

return mapping;
}

Here is my object

@interface DNComment : NSObject
@property (nonatomic, assign) NSInteger commentId;
@property (nonatomic, copy) NSString *body;
@property (nonatomic, copy) NSString *bodyHTML;
@property (nonatomic, copy) NSDate *created_at;
@property (nonatomic, assign) NSInteger depth;
@property (nonatomic, assign) NSInteger voteCount;
@property (nonatomic, copy) NSDate *createdAt;
@property (nonatomic, assign) NSInteger userID;
@property (nonatomic, copy) NSString *userDisplayName;
@property (nonatomic, strong) NSArray *comments;
@end

My RKResponseDescriptor

RKMapping *mapping = [DNAMappingProvidor dnCommentMapping];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping
                                                                                        method:RKRequestMethodGET
                                                                                   pathPattern:/api/v1/stories/1
                                                                                       keyPath:@"story.comments"
                                                                                   statusCodes:statusCodeSet];

You can see in the image that depth 0 comment is populated, it creates the correct amount of children (and their children count is correct), but they are not populated.

enter image description here

Here is an example of the JSON I'm trying to map

{
"story": {
"badge": "discussion",
"comment": "THE STORY",
"comments": [
  {
    "body": "THIS IS MY COMMENT - I GET MAPPED FINE",
    "body_html": "<p>THIS IS MY COMMENT - I GET MAPPED FINE</p>\n",
    "comments": [
      {
        "body": "THIS IS MY CHILD RESPONSE - NONE OF MY PROPERTIES GET SET",
        "body_html": "<p>THIS IS MY CHILD RESPONSE - NONE OF MY PROPERTIES GET SET</p>\n",
        "comments": [
          {
            "body": "THIS IS MY CHILD'S CHILD RESPONSE - NONE OF MY PROPERTIES GET SET",
            "body_html": "<p>THIS IS MY CHILD'S CHILD RESPONSE - NONE OF MY PROPERTIES GET SET </p>\n",
            "comments": [

            ],
            "created_at": "2014-02-17T21:07:13Z",
            "depth": 2,
            "id": 41665,
            "url": "https://www.www.com",
            "user_display_name": "A M.",
            "user_id": 201,
            "user_job": "Job Title",
            "user_portrait_url": "image.png",
            "user_url": "user.com",
            "vote_count": 1
          }
        ],
        "created_at": "2014-02-17T20:50:05Z",
        "depth": 1,
        "id": 41655,
        "url": "https://www.www.com",
        "user_display_name": "M K.",
        "user_id": 3517,
        "user_job": "Job Title",
        "user_portrait_url": "image.png",
        "user_url": "user.com",
        "vote_count": 2
      }
    ],
    "created_at": "2014-02-17T20:14:47Z",
    "depth": 0,
    "id": 41649,
    "url": "www.www.com",
    "user_display_name": "A M.",
    "user_id": 201,
    "user_job": "Job Title",
    "user_portrait_url": "image.com",
    "user_url": "user.com",
    "vote_count": 32
  },

Thank you

Upvotes: 3

Views: 901

Answers (1)

Wain
Wain

Reputation: 119041

It looks like you issue is just this part:

[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"comments.comments"

As the from key path should just be @"comments". You don't need to drill down through the structure, RestKit will do that for you as it navigates the JSON applying the mapping.

Upvotes: 3

Related Questions