【问题标题】:Restkit json error response msg from server来自服务器的 Restkit json 错误响应消息
【发布时间】:2012-04-08 03:09:03
【问题描述】:

我花了很多时间来解决这个问题。我使用带有对象映射 2.0 的 Restkit 0.9.3。所有数据都采用 JSON 格式。我可以正确地进行 GET、POST、PUT 和 DELETE 操作,这是我没有正确捕获和映射的响应体..

所以我的问题是,当出现问题时,我的 restful api 会返回错误。我想用restkit映射那些错误,fx这个错误被返回:

{ “代码”:“401”, “消息”:“未经授权” }

我如何正确映射这个 json?我已经尝试了很多东西并且可以使用一些指导 - 或者请举个例子。

【问题讨论】:

    标签: ios json api response restkit


    【解决方案1】:

    如果返回一个对象,您的委托应调用此方法:

    - (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {}
    

    在此方法中,您应该调用“错误”类的实例并根据需要映射“代码”和“消息”。

    处理错误的更简单方法是使用:

    - (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
    
    if(objectLoader.response.statusCode == 401)
    { ...
    

    并在该方法中显示必要的错误消息。

    【讨论】:

      【解决方案2】:

      对于版本 0.10.0,此响应错误可以映射如下:

      RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
      [errorMapping mapKeyPath:@"message" toAttribute:@"errorMessage"];
      [[[RKObjectManager sharedManager] mappingProvider] setErrorMapping:errorMapping];
      

      返回错误的请求将调用以下委托方法:

      - (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
          NSArray *errorMessages = [[error userInfo] objectForKey:RKObjectMapperErrorObjectsKey];
          RKErrorMessage *errorMessage = [errorMessages objectAtIndex:0]; // First and only object in your case.
          NSString *message = [errorMessage errorMessage];
          NSInteger code = [[objectLoader response] statusCode];
          NSLog(@"ERROR: [%d] %@", code, message); // => ERROR: [401] Unauthorized
      }
      

      【讨论】:

      • 知道如何在 v.20 中执行此操作吗?
      • 在下面查看我对 v0.20 的回答
      • 如果 JSON 响应格式如下:{ "message": "Unauthorized", "critical":true } 怎么办?我在哪里可以获得“关键”键的值?
      【解决方案3】:

      适用于 RestKit v0.20

      假设您的 HTTP 正文是:

      {"error": "..."}
      

      您创建一个映射和描述符:

      RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
      
      [errorMapping addPropertyMapping: [RKAttributeMapping attributeMappingFromKeyPath:@"error" toKeyPath:@"errorMessage"]];
      RKResponseDescriptor *errorResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
      [objectManager addResponseDescriptor:errorResponseDescriptor];
      

      然后你可以从你的失败块中访问它:

      failure:^(RKObjectRequestOperation *operation, NSError *error) {
                      NSLog(@"errorMessage: %@", [[error userInfo] objectForKey:RKObjectMapperErrorObjectsKey]);
                  }
      

      这使用了内置的 RKErrorMessage 类,不过您可以使用其他字段创建自己的自定义类。

      【讨论】:

      • 这不起作用。错误返回 null。 NSLOG 显示 errorMessage: (null) stackoverflow.com/questions/19736408/…
      • 对我和其他人都很好。您是否为您的班级使用了正确的映射?
      • @jgervin 你愿意分享你的 JSON 吗?我希望 -1 变成 +1 :]
      【解决方案4】:

      使用 Restkit v0.2x,您可以以这种 [Swift] 的方式将您想要的所有 JSON 属性映射到现有的 RKErrorMessage.userInfo Dictionary 属性:

      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", //or nil, according to your json response
          statusCodes: RKStatusCodeIndexSetForClass(UInt(RKStatusCodeClassClientError)))
      );
      

      因此,您可以像这样映射错误 JSON 响应:

      {
          "error": {
              "message": "Error message",
              "cause": "...",
              "code": "my_error_code",
              "url": "..."
              ...
          }
      }
      

      并在failure 闭包中检索具有所有属性的RKErrorMessage,如下所示:

      failure: { (operation, error) -> Void in
          if let errorMessage = error.userInfo?[RKObjectMapperErrorObjectsKey]?.firstObject as? RKErrorMessage{
              let message = errorMessage.userInfo["message"] as! String;
              let code = errorMessage.userInfo["code"] as! String;
              ...
          }
      }
      

      我希望这对某人有帮助!

      【讨论】:

      • 你也可以用statusCodes: RKStatusCodeIndexSetForClass(UInt(RKStatusCodeClassClientError))代替statusCodes: RKStatusCodeIndexSetForClass(.ClientError)
      猜你喜欢
      • 1970-01-01
      • 2016-03-12
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 2011-11-23
      • 1970-01-01
      • 2020-09-22
      相关资源
      最近更新 更多