RestKit响应无法反序列化为对象

时间:2012-12-17 20:48:04

标签: ios restkit restkit-0.20

在使用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>

非常感谢任何帮助!

3 个答案:

答案 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的作者自己做出这个改变(或接受我的改变:)。