Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested to-many relationships with RestKit

I'm trying to map relationships for the following JSON to a CoreData backed model.

Here's the JSON:

{
    "photos": [
        {
            "id": 1,
            "thumb": "http://localhost/test_1_thumb.png",
            "image": "http://localhost/test_1.png",
            "date": "2011-07-02T06:06:16Z",
            "likes": 0,
            "user": {
                "id": 1,
                "username": "User1",
                "avatar": "http://cdn.domain.com/avatar.jpg"
            },
            "comments": [
                {
                    "date": "2011-07-02T06:06:16Z",
                    "text": "This is the only comment",
                    "id": 1,
                    "author": {
                        "username": "User1",
                        "id": 1,
                        "avatar": "http://cdn.domain.com/avatar.jpg"
                    }
                }
            ]
        }
    ]
}

My CoreData models which I've mapped with RestKit's OM2 classes.

CoreData Entities

The Photo class.

@interface Photo : NSManagedObject

@property (nonatomic, retain) NSString * thumbnailUrl;
@property (nonatomic, retain) NSString * imageUrl;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSNumber * likes;
@property (nonatomic, retain) NSNumber * photoID;
@property (nonatomic, retain) User *owner;
@property (nonatomic, retain) NSSet *comments;

@end

@interface Photo (CoreDataGeneratedAccessors)

- (void)addCommentsObject:(Comment *)value;
- (void)removeCommentsObject:(Comment *)value;
- (void)addComments:(NSSet *)values;
- (void)removeComments:(NSSet *)values;

@end

@implementation Photo

@dynamic thumbnailUrl;
@dynamic imageUrl;
@dynamic date;
@dynamic likes;
@dynamic photoID;
@dynamic owner;
@dynamic comments;

@end

Now the part I'm not completely sure on is the relationships:

// Map relationships between entities.
[commentMapping mapKeyPath:@"author" toRelationship:@"author" withMapping:userMapping];
[photoMapping mapKeyPath:@"user" toRelationship:@"owner" withMapping:userMapping];
[photoMapping mapKeyPath:@"comments" toRelationship:@"comments" withMapping:commentMapping];

With this I'm able to access all but the comments attribute of a photo, with this error: Comments = Relationship 'comments' fault on managed object. I have a feeling this is to do with the Photo model having comments defined as an NSSet or I'm doing something wrong with the relationship mapping but I'm not sure.

like image 1000
Soliah Avatar asked Aug 07 '11 07:08

Soliah


2 Answers

So turns out that the problem was nothing to do with RestKit or the mapping but my understanding of how CoreData functions.

I was accessing the mapped JSON objects in my delgate as follows:

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
    NSLog(@"Loaded photos: %@", objects);

    for (id object in objects) {
        Photo *photo = object;
        // Print other photo attributes...

        NSLog(@"Comments = %@", photo.comments );
    }
}

The problem was in trying to print the collection object directly. CoreData would not fire a fault on the data store. Simply replacing with a fast iteration as follows and accessing the properties allowed me to access the comments object.

for (Photo *photo in objects) {
    for (Comment *comment in photo.comments) NSLog(@"Comment = %@", comment.text);
}
like image 150
Soliah Avatar answered Oct 24 '22 15:10

Soliah


You need something like:

[objectManager.mappingProvider setMapping:commentMapping forKeyPath:@"comments"];

Also checkout https://github.com/RestKit/RestKit/wiki/Object-mapping

like image 43
Will Johnston Avatar answered Oct 24 '22 17:10

Will Johnston