我有两个EndPoints:
http://rest.domain.com/template
根据用户选择的选项,我需要能够PUT
,POST
和&两个EndPoints上都有Delete
。
所有三种方法的映射略有不同。每个EndPoint的映射也不同。
设置映射的最佳方法是将它们加载一次,并且可以针对每个EndPoint多次使用,具体取决于用户的选项(PUT
,POST
或Delete
)选择?我必须在一个故事板场景中完成这个!
目前,下面是POST
/invite
EndPoint时使用的代码(在第一次POST后我崩溃了,我正在重新映射):
- (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;
}
}
我为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) {
}];
}
请求&响应描述符:
- (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];
}
我知道上面的方法不正确,因为在POST或PUT后Xcode崩溃了。我还没有实现删除b / c我不知道如何正确设置。
我是否在viewDidLoad
中加载映射ONCE?我是否要创建PUT, POST, DELETE
x 2 EndPoints
= 6 RKEntityMappings
?
需要一些关于最佳实践的指导。代码示例或一些分步说明会很棒!
答案 0 :(得分:1)
您需要创建许多不同的映射,因为您对进程有不同的结构响应。如果一个实体类型的响应是某些常见超集的所有子集,那么您只能使用一个(用于映射响应而另一个用于请求)。你没有说出预期的JSON,所以我不知道。
在您的代码中,我看到2个请求描述符和1个响应描述符。请求与任何方法匹配,因此将始终使用。响应描述符仅匹配GET响应,因此不适用于任何事情。每个方法的每个端点应该有一个响应描述符(正如你所说,它们需要应用不同的映射)。
viewDidLoad
不一定是配置它的正确位置。看起来你有一个对象管理器,这个配置代码应该在创建时运行(而不是在使用它时,因为视图可以多次加载,配置会重复)。