Mapping RestKit Relationships with a Primary Key

I am having problems displaying relationships when the JSON response contains only the primary key and not a fully nested array to create a new object.

I have 2 classes - Shop and Item, and, as you expect, Shop-> Item is one-to-many.

I have a local data store for stores (and items), each of which has a primary key. Then I want to load the list of elements in the form of JSON and map the kernel objects to the data, but include only the primary key in the store, and not all the store details in the form of a nested array - this will be a huge waste of network traffic, as I load the details of 500+ elements.

Here is the JSON of two requests:

/the shops

{ "id" : 1, "shop" : "Shop A", "city" : "New York" }, { "id" : 2, "shop" : "Shop B", "city" : "London" }, ... 

/ elements

 { "id" : 1, "name" : "Shoes", "manufacturer" : "Vans", "shopId" : 1 }, { "id" : 2, "name" : "T-shirt", "manufacturer" : "Animal", "shopId" : 2 }, { "id" : 3, "name" : "Scarf", "manufacturer" : "Ted Baker", "shopId" : 1 }, { "id" : 4, "name" : "Sunglasses", "manufacturer" : "Ray-Ban", "shopId" : 3 }, ... 

Here is my code for now.

AppDelegate.m

 ... NSURL *baseURL = [NSURL URLWithString:@"http://localhost/company/API"]; RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL]; [AFNetworkActivityIndicatorManager sharedManager].enabled = YES; [objectManager.HTTPClient setDefaultHeader:@"Accept" value:@"application/json"]; NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; objectManager.managedObjectStore = managedObjectStore; // Shop Mapping RKEntityMapping *shopMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Shop class]) inManagedObjectStore:objectManager.managedObjectStore]; NSDictionary *shopMappingAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"objectId",@"id",@"name",@"shop",@"city",@"city",nil]; shopMapping.identificationAttributes = @[@"objectId"]; [shopMapping addAttributeMappingsFromDictionary:shopMappingAttributes]; [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:shopMapping pathPattern:@"/shops" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; // Item Mapping RKEntityMapping *itemMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Item class]) inManagedObjectStore:objectManager.managedObjectStore]; NSDictionary *itemMappingAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"objectId",@"id",@"name", @"name",@"manufacturer",@"manufacturer",nil]; itemMapping.identificationAttributes = @[@"objectId"]; [itemMapping addAttributeMappingsFromDictionary:itemMappingAttributes]; // Define the relationship mapping [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:itemMapping pathPattern:@"/items" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; ... 

ItemsTableViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; // Update Shops [[RKObjectManager sharedManager] getObjectsAtPath:@"/shops" parameters:nil success:nil failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(@"Error: %@",error); }]; // Update/Get Items NSDictionary *parameters = @{ @"username": self.username, @"password": self.password, @"API_key": @"abc123", }; NSMutableURLRequest *request = [[RKObjectManager sharedManager] requestWithObject:nil method:RKRequestMethodPOST path:@"/items" parameters:parameters]; RKManagedObjectRequestOperation *operation = [[RKObjectManager sharedManager] managedObjectRequestOperationWithRequest:request managedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { Item *item = [mappingResult firstObject]; NSLog(@"Mapped the Item: %@", item); } failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(@"Error: %@",error); }]; NSOperationQueue *operationQueue = [NSOperationQueue new]; [operationQueue addOperation:operation]; } 

EDIT: Wain, I have this in the appropriate place in the application’s directory, but I get an NSException

 NSEntityDescription *itemEntity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext]; NSRelationshipDescription *shopRelationship = [itemEntity relationshipsByName][@"shop"]; RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:shopRelationship attributes:@{ @"shopId": @"objectId" }]; [itemMapping addConnection:connection]; 

Nsexception

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Item'' 

What did I miss?

+8
ios restkit
source share
1 answer

You need to add the transition attribute to the element (called shopId ) and the associated mapping.

Configure the relationship using foreign key mapping, like:

 NSEntityDescription *itemEntity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectContext]; NSRelationshipDescription *shopRelationship = [itemEntity relationshipsByName][@"shop"]; RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:shopRelationship attributes:@{ @"shopId": @"id" }]; 

Then use addConnection: to add it to your mapping.

+5
source share

All Articles