2015-01-08 19 views
1

当用户在我们的服务器上签约成功,它以200状态码和JSON有效载荷这样的回应:如何在Restkit中映射自定义错误键?

{ 
    "error": null, 
    "result": { 
     "auth": { 
      "created_utc": 1420740197, 
      "device_token": "rQZJddrbD5tyEpznb8bVKeGlHqRNGyvOgDR;tQJBkpkfAXO6DQ4lNiG17lzu6IDc0hVBfR3RrN9o0txRQIYAa6fnf5d9LNaSRDMk9LrplgkITuMC37v;;;rvG35CJvV7dWZ5TQVYUWeHwAABvKvzTRpSDw5Qg9jQrmiUHLZptegFY=76421420740197" 
     }, 
     "display_name": "a", 
     "email": "[email protected]", 
     "user_id": 7642, 
     "username": "a" 
    } 
} 

但如果[email protected]尝试重新注册时,其与响应400状态码和有效载荷JSON这样的:

{ 
    "error": { 
     "code": 805, 
     "message": "there is another user with that username" 
    }, 
    "result": null 
} 

我试图映射误差,这样,当Restkit返回一个错误,我得到的消息,以及该代码。这些都是我想做到这一点的方法:

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]]; 
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"error.message" toKeyPath:@"errorMessage"]]; 

RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)]; 

[self.objectManager addResponseDescriptor:errorDescriptor]; 

这其中显然只得到了错误的消息部分与该输出返回:

Error Domain=org.restkit.RestKit.ErrorDomain Code=1004 "there is another user with that username" UserInfo=0x7feefcf8a730 {RKObjectMapperErrorObjectsKey=(
"there is another user with that username" 
), NSLocalizedDescription=there is another user with that username} 

于是我试图使RKErrorMessage的子类:

#import "RKErrorMessage.h" 

@interface TAG_RKErrorMessage : RKErrorMessage 

@property (strong, nonatomic) NSNumber *errorCode; 

@end 

,改变了映射到这一点:

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[TAG_RKErrorMessage class]]; 
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"error.message" toKeyPath:@"errorMessage"]]; 
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"error.code" toKeyPath:@"errorCode"]]; 

并导致完全相同的输出:

Error Domain=org.restkit.RestKit.ErrorDomain Code=1004 "there is another user with that username" UserInfo=0x7fa16c627ce0 {RKObjectMapperErrorObjectsKey=(
"there is another user with that username" 
), NSLocalizedDescription=there is another user with that username} 

所以最后我想这映射到至少尝试获得字典显示为的RKObjectMapperErrorObjectsKeyNSErroruserInfo

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]]; 
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"error" toKeyPath:@"errorMessage"]]; 

而导致这种输出:

Error Domain=org.restkit.RestKit.ErrorDomain Code=1004 "<null>" UserInfo=0x7ff8abe678e0 {RKObjectMapperErrorObjectsKey=(
(null) 
), NSLocalizedDescription=<null>} 

现在我被困在这一点上。如何映射服务器错误响应的密钥,以便我可以访问返回的code以及message作为两个单独的值?

回答

3

您可能已正确映射了您的TAG_RKErrorMessage实例。你有没有试图从你得到的NSError中提取它?您可以使用RKObjectMapperErrorObjectsKey作为对NSError的用户信息词典一键搞定所有映射的错误消息的数组:

NSArray* objectMapperErrorObjectsArray = [error.userInfo objectForKey:RKObjectMapperErrorObjectsKey]; 

然后,您可以遍历数组检查每个错误要回应的条件,例如,如果你想与错误信息“无效令牌” 403响应代码作出反应,你可以这样做:

NSArray* objectMapperErrorObjectsArray = [error.userInfo objectForKey:RKObjectMapperErrorObjectsKey]; 
for (RKErrorMessage* objectMapperErrorObject in objectMapperErrorObjectsArray) 
{ 
    if ([objectMapperErrorObject.errorMessage isEqual:@"Invalid token"]) 
    { 
     if (operation.HTTPRequestOperation.response.statusCode == 403) 
     { 
      //Code to handle a 403 response status code when error message is "Invalid token". 
     } 
    } 
} 
+1

完美!要做一个改变,并为'(TAG_RKErrorMessage * objectMapperErrorObjectsArray中的objectMapperErrorObject)'执行''所以我可以访问errorCode。谢谢您的帮助! –

1

只是一个提示:如果你想使用内置的RKErrorMessage而无需创建任何子类,都可以将所有错误的JSON属性映射到RKErrorMessage.userInfo这样:

Objective-C的

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]]; 
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"userInfo"]]; 

RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping method:RKRequestMethodAny pathPattern:nil keyPath:"error" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)]; 

斯威夫特

let errorMapping = RKObjectMapping(forClass: RKErrorMessage.self); 
errorMapping.addPropertyMapping(RKAttributeMapping(fromKeyPath: nil, toKeyPath: "userInfo")); 

let errorResponseDescriptor = RKResponseDescriptor(
    mapping: errorMapping, 
    method: RKRequestMethod.Any, 
    pathPattern: nil, 
    keyPath: "error", 
    statusCodes: RKStatusCodeIndexSetForClass(UInt(RKStatusCodeClassClientError))) 
);