在使用RestKit发布请求期间,我无法将响应映射回对象。
以下是代码:
请求:
// mapping for the response. response is an object: {"response":"message","success":bool}
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[GenericResponse class]];
[responseMapping addAttributeMappingsFromArray:@[@"success",@"response"]];
responseMapping.setDefaultValueForMissingAttributes = YES;
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:@"/authenticate" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
// mapping for the request body
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromArray:@[@"username", @"password"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[LoginCriteria class] rootKeyPath:nil];
// set up the request
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://localhost:8080"]];
[manager addResponseDescriptor:responseDescriptor];
[manager addRequestDescriptor:requestDescriptor];
[manager setRequestSerializationMIMEType:@"application/json"];
// set up the LoginCriteria object
LoginCriteria* loginCriteria = [LoginCriteria new];
loginCriteria.password = @"test";
loginCriteria.username = @"test";
// make the request
[manager postObject:loginCriteria path:@"/authenticate" parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
GenericResponse *genericResponse = (GenericResponse*)mappingResult;
NSLog(@"logged in: %@", [mappingResult array]);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"login failed");
}];
GenericResponse.h:
@interface GenericResponse : NSObject
@property (nonatomic) Boolean* success;
@property (nonatomic, copy) NSString* response;
@end
日志:
2012-12-17 15:44:22.890 Radiuus[8221:1703] T restkit.network:RKHTTPRequestOperation.m:139 POST 'http://localhost:8080/authenticate':
request.headers={
Accept = "application/json";
"Accept-Language" = "en, fr, de, ja, nl, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl, tr, uk, ar, hr, cs, el, he, ro, sk, th, id, ms, en-GB, ca, hu, vi, en-us;q=0.8";
"Content-Type" = "application/json; charset=utf-8";
"User-Agent" = "Radiuus/1.0 (iPhone Simulator; iOS 6.0; Scale/1.00)";
}
request.body=(null)
2012-12-17 15:44:23.244 Radiuus[8221:5d0b] T restkit.network:RKHTTPRequestOperation.m:156 POST 'http://localhost:8080/authenticate' (200):
response.headers={
"Content-Type" = "application/json";
Date = "Mon, 17 Dec 2012 20:44:23 GMT";
Server = "Apache-Coyote/1.1";
"Transfer-Encoding" = Identity;
}
response.body={"response":"authentication succeeded","success":true}
2012-12-17 15:44:23.246 Radiuus[8221:4f03] W restkit.object_mapping:RKMapperOperation.m:76 Adding mapping error: Expected an object mapping for class of type 'LoginCriteria', provider returned one for 'GenericResponse'
从日志中,对我来说很奇怪的是,似乎RestKit期望反序列化对LoginCriteria对象的响应,但是当它正确获取GenericResponse对象时“失败”,这当然是正确的。 / p>
非常感谢任何帮助!
答案 0 :(得分:9)
感谢您对问题的回答,因为它引导我找到了如何使用RestKit的内置方法之一来解决此问题而不是修改核心代码的正确方向。
根据他的文档https://github.com/RestKit/RestKit/wiki/Object-mapping,在处理Core Data Post / Put中的多个根对象部分,他提到如果你想发布一种类型的对象,但是另一种在响应中,您必须nil
在请求操作中targetObject
。他的文档中缺少一个完整的示例,因此这里是我使用的代码块:
RKManagedObjectRequestOperation *operation = [RKObjectManager.sharedManager appropriateObjectRequestOperationWithObject: objectToBePOSTed method:RKRequestMethodPOST path: path parameters: params];
operation.targetObject = nil;
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
//handle success
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
//handle failure
}];
[RKObjectManager.sharedManager enqueueObjectRequestOperation:operation];
〜节日快乐
答案 1 :(得分:0)
我在使用RestKit时遇到了同样的问题。 解决方案是为我发布的对象添加映射作为响应。
答案 2 :(得分:0)
我挖掘了RestKit代码,在mapObject
的{{1}}函数中找到了以下代码段:
RKMapperOperation.m
第一个if (NO == [[self.targetObject class] isSubclassOfClass:objectMapping.objectClass]) {
if ([_mappingsDictionary count] == 1) {
NSString *errorMessage = [NSString stringWithFormat:
@"Expected an object mapping for class of type '%@', provider returned one for '%@'",
NSStringFromClass([self.targetObject class]), NSStringFromClass(objectMapping.objectClass)];
[self addErrorWithCode:RKMappingErrorTypeMismatch message:errorMessage keyPath:keyPath userInfo:nil];
return nil;
} else {
// There is more than one mapping present. We are likely mapping secondary key paths to new objects
destinationObject = [self objectWithMapping:mapping andData:mappableObject];
}
}
语句检查以确保if
(请求对象)具有targetObject
层次结构中的类类型(响应对象)。由于我的请求和响应对象不同,这当然会失败。我在那条线上设置了一个断点来证明这一点。这是我检查时打印的内容:
objectMapping.objectClass
正如您所看到的,它们具有不同的类型,因此如果成功并且函数返回nil,则响应未映射。我只是将(lldb) po self.targetObject
(id) $1 = 0x09fb54d0 <LoginCriteria: 0x9fb54d0>
(lldb) po objectMapping.objectClass
(Class) $2 = 0x00162c58 GenericResponse
替换为return nil;
,一切都按预期工作。
我对这个解决方案不满意,因为我觉得RestKit的作者并不打算发帖和接收不同的对象。因此,这是一个黑客。我要留下这个答案,直到a)我听到一个更好的解决方案,或者b)RestKit的作者自己做出这个改变(或接受我的改变:)。