Aaron Vegh
Aaron Vegh

Reputation: 5217

AFIncrementalStore: Pulling a Related Entity with ID Only

I'm using the App.net messaging API in my Mac app, which uses Core Data with AFIncrementalStore. I have a Channel entity that a couple different ways of relating to the Users entity. There's an "owner" relation which is simple and working fine. But there's also two ACL entities: readers and writers to the Channel.

An ACL is just a key-value object that includes an array of User IDs, and this is the relation that I'm not sure how to deal with using AFIncrementalStore.

I'm pulling a Channel entity and it has an ACL object attached ("writers"), which contains an array of User IDs:

"writers": {
    "any_user": false,
    "immutable": true,
    "public": false,
    "user_ids": [
        "1",
    ],
    "you": true
},

I've setup my relationship in Core Data ("writerUsers" with a to-many relationship to Users) but I fall over in figuring out where to configure this in AFIS.

I've tried implementing - (NSDictionary *)representationsForRelationshipsFromRepresentation:(NSDictionary *)representation ofEntity:(NSEntityDescription *)entity fromResponse:(NSHTTPURLResponse *)response but this seems to only work if the server response includes the actual object value — the whole User entity, not just the ID.

I've also seen mention of using - (NSURLRequest *)requestWithMethod:(NSString *)method pathForRelationship:(NSRelationshipDescription *)relationship forObjectWithID:(NSManagedObjectID *)objectID withContext:(NSManagedObjectContext *)context to provide a URL request to fetch a user object... but that method never gets called out of my AFHTTPClient subclass.

So how can I teach AFIncrementalStore to pull in a user entity when I just have an ID?

Upvotes: 1

Views: 342

Answers (1)

lari
lari

Reputation: 752

I was able to get my problem fixed. The API should have this format in the json:

"users": [
    {"id":1},
    {"id":2}
]

Even though the API doesn't give the data in this format, you can "fake" it in a subclass of AFRESTClient.

- (NSDictionary *)representationsForRelationshipsFromRepresentation:(NSDictionary *)representation
                                                       ofEntity:(NSEntityDescription *)entity
                                                   fromResponse:(NSHTTPURLResponse *)response {

    NSMutableDictionary *mutableRelationshipRepresentations = [[super representationsForRelationshipsFromRepresentation:representation ofEntity:entity fromResponse:response] mutableCopy];
    if ([entity.name isEqualToString:@"writer"]) {
        NSArray *user_ids = [representation objectForKey:@"user_ids"];
        NSMutableArray *users = [[NSMutableArray alloc] init];
        for (NSNumber *id in user_ids) {
            [users addObject:@{@"id":id}];
        }
    }
    [mutableRelationshipRepresentations setObject:users forKey:@"users"];

    return mutableRelationshipRepresentations;
}

And of course you need to define "users" as a to-many relationship in the model.When there's only the id in the relationship objects, AFIncrementalStore will fetch the individual relationship objects automatically.

Upvotes: 0

Related Questions