2015-01-08 59 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))) 
);