I have two EndPoints:
http://rest.domain.com/invite
http://rest.domain.com/template
Depending on what options the User selects, I need to able to PUT
, POST
, & Delete
on both EndPoints.
Mapping for all three methods is slightly different. Mapping for each EndPoint is also different.
What's the best way to setup mappings so they are loaded once and can be used multiple times for each EndPoint depending upon what option (PUT
, POST
, or Delete
) the User selects? I have to accomplish this on one storyboard Scene!
Currently, below is the code that I use when POST
ing to the /invite
EndPoint (it crashes after the first POST b/c I'm remapping):
- (void)sendInvite:(NSInteger)methodType
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.objectManager = [self getObjectManager];
self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
RKEntityMapping *invitationMapping = [RKEntityMapping mappingForEntityForName:kInvite
inManagedObjectStore:self.objectManager.managedObjectStore];
RKEntityMapping *activityMapping = [RKEntityMapping mappingForEntityForName:kActivity
inManagedObjectStore:self.objectManager.managedObjectStore];
Invite *invitation;
switch (methodType) {
case POST:
{
invitationMapping = [RESTMappingProvider invitionPostMapping:invitationMapping];
activityMapping = [RESTMappingProvider activityPostMapping:activityMapping];
[invitationMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kActivitiesRelationship
toKeyPath:kActivitiesRelationship
withMapping:activityMapping]];
invitation = [self inviteForMethod:POST]; //This method just assigns values to the attributes
[self setupDescriptors:invitationMapping forKeyPath:kMeetupKeyPath descriptorClassIsTemplate:NO];
[self.objectManager.HTTPClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[self.objectManager.managedObjectStore.mainQueueManagedObjectContext saveToPersistentStore:NO];
[self.objectManager postObject:invitation path:kMeetupKeyPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self removeDuplicateObjects]; //After removing relationship Dups, I save to persistent store
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
}
break;
case PUTACCEPT:
case PUTDECLINE:
case PUTEDIT:
{
invitationMapping = [RESTMappingProvider invitionPutMapping:invitationMapping];
activityMapping = [RESTMappingProvider activityPutMapping:activityMapping];
[invitationMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kActivitiesRelationship
toKeyPath:kActivitiesRelationship
withMapping:activityMapping]];
invitation = [self inviteForMethod:methodType]; //This method just assigns values to the attributes
[self setupDescriptors:invitationMapping forKeyPath:kMeetupKeyPath descriptorClassIsTemplate:NO];
[self.objectManager.HTTPClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[self.objectManager putObject:invitation path:kMeetupKeyPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failure in PUT");
}];
}
break;
}
}
I do something similar for the Templates EndPoint
- (void)saveAsTemplate
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.objectManager = [self getObjectManager];
self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
RKEntityMapping *invitationMapping = [RKEntityMapping mappingForEntityForName:kInviteTemplates
inManagedObjectStore:self.objectManager.managedObjectStore];
invitationMapping = [RESTMappingProvider invitionTemplateMapping:invitationMapping];
RKEntityMapping *activityMapping = [RKEntityMapping mappingForEntityForName:kActivityTemplates
inManagedObjectStore:self.objectManager.managedObjectStore];
activityMapping = [RESTMappingProvider activityTemplateMapping:activityMapping];
[invitationMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:kTemplateActivitiesRelationship
toKeyPath:kTemplateActivitiesRelationship
withMapping:activityMapping]];
STInvitesTemplate *invitation = [self templateForInvite];//this method assigns values to the attributes
[self setupDescriptors:invitationMapping forKeyPath:kTemplatesKeyPath descriptorClassIsTemplate:YES];
[self.objectManager.HTTPClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[self.objectManager postObject:invitation path:kTemplatesKeyPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
}
Request & Response Descriptor:
- (void)setupDescriptors:(RKEntityMapping *)invitationMapping forKeyPath:(NSString *)keyPath descriptorClassIsTemplate:(BOOL)isTemplate
{
RKRequestDescriptor *requestDescriptor;
if (isTemplate)
{
requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[invitationMapping inverseMapping] objectClass:[Template class] rootKeyPath:nil method:RKRequestMethodAny];
}
else
{
requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[invitationMapping inverseMapping] objectClass:[Invite class] rootKeyPath:nil method:RKRequestMethodAny];
}
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:invitationMapping
method:RKRequestMethodGET
pathPattern:keyPath
keyPath:nil
statusCodes:statusCodeSet];
self.objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[self.objectManager addRequestDescriptor:requestDescriptor];
[self.objectManager addResponseDescriptor:responseDescriptor];
}
I know the approach above is incorrect as Xcode crashes after I POST or PUT. I haven't implemented Delete yet b/c I'm not sure how to set this up correctly.
Do I load the mappings ONCE in viewDidLoad
? Do I create PUT, POST, DELETE
x 2 EndPoints
= 6 RKEntityMappings
?
Need some guidance on best practice. Code sample or some step-by-step instructions would be great!