如何在AFNetworking中获取状态代码

时间:2013-12-13 12:09:45

标签: ios afnetworking afnetworking-2

我有一个方法,用于授权用户。我需要基本授权。

    NSString *url = [NSString stringWithFormat:@"%@/rest/api/person/auth", host];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
    [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:_loginField.text password:_passwordField.text];
    [manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        [self parseResponseForUser:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error %@ ",error);
    }];

这里的主要问题是确定错误类型。我可能有授权错误和网络连接问题错误(主机无法访问)。 当登录名和密码与条件不匹配时,将运行故障块。例如,如果我输错密码并登录,则会收到此错误消息。:

  

错误域= NSCocoaErrorDomain代码= 3840“操作不能   完成。 (可可错误3840.)“(JSON文本没有以数组或   允许片段未设置的对象和选项。)

我应该如何捕获错误类型?

9 个答案:

答案 0 :(得分:30)

终于找到答案,可能会对某人有所帮助。我只需要使用:

NSInteger statusCode = operation.response.statusCode;

我可以抓住它:

    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"response:%@", responseObject);
        [self parseResponseForUser:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSInteger statusCode = operation.response.statusCode;
        if(statusCode == 401) {
        } else if (statusCode == 404) {
        }
    }];

答案 1 :(得分:19)

在AFNetworking 3.0+中,如果出现错误,您可以访问故障块的error.userInfo对象中的状态代码:

failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    NSHTTPURLResponse *response = error.userInfo[AFNetworkingOperationFailingURLResponseErrorKey];

    NSInteger statusCode = response.statusCode;

    // Do something with the status code
}];

答案 2 :(得分:6)

  

您可以尝试从错误中获取代码,然后相应地显示消息。

failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSInteger statusCode = error.code;
    if(statusCode == -1001) {
      // request timed out
    } else if (statusCode == -1009 || statusCode || -1004) {
      // no internet connectivity
    }
}];

同样可以检查其他代码。

答案 3 :(得分:6)

这是我如何做的。

[self.httpClient GET:@"someAPI"
          parameters:parametersDictionary
             success:^(NSURLSessionDataTask *task, id responseObject) {
             } failure:^(NSURLSessionDataTask *task, NSError *error) {
               NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
               NSInteger statusCode = [response statusCode];
               switch (statusCode) {
                 case 404:
                   break;
                 default:
                   break;
               }
             }];

答案 4 :(得分:1)

使用NSURLError枚举改进了alok srivastava的响应:

failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSInteger statusCode = error.code;
if(statusCode == NSURLErrorTimedOut) {
  // request timed out
} else if (statusCode == NSURLErrorNotConnectedToInternet || statusCode || NSURLErrorCannotConnectToHost) {
  // no internet connectivity
}}];

答案 5 :(得分:1)

以下是如何在Swift中执行此操作

((NSURLSessionDataTask, NSError) -> Void) = { (sessionDataTask :NSURLSessionDataTask, responseError : NSError) -> Void in
    let response  = sessionDataTask.response as! NSHTTPURLResponse
    switch (statusCode) {
      case 404:
        // do stuff
      case 401:
        // do stuff
      default:
        break;
    }
}

答案 6 :(得分:0)

看起来您的服务器可能会使用HTML响应,或者它可能会使用JSON进行响应。但是当你输入:

[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];

你告诉AFNetworking期待JSON。

相反,如果它不是JSON,请尝试告诉它处理常规HTTP响应:

NSArray *serializers = @[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]];
AFCompoundSerializer *compoundResponseSerializer = [AFCompoundSerializer compoundSerializerWithResponseSerializers:serializers];
[manager setResponseSerializer:compoundResponseSerializer];

现在,如果JSON序列化程序失败,请求将传递给AFHTTPResponseSerializerAFHTTPResponseSerializer应使用适当的HTTP错误代码而不是JSON解析错误调用您的失败块。

顺便说一下,{{1}}是子类,所以如果你想要更具体的行为,请随时查看该选项。

答案 7 :(得分:0)

经常发生的情况是,如果服务器发送错误,服务器可能会以不同的内容类型发送响应。

例如,当使用JSON作为Content-Type发送请求并期望来自服务器的JSON响应时,可以指定以下请求标头:

Content-Type: application/json
Accept: application/json

当请求因身份验证错误而失败时,服务器可能会向您发送状态代码401 (Unauthorized)以及包含相关诊断信息的可选响应。

严格来说,Web服务器应该尊重Accept标头,但不幸的是,有些不会,并且会在text/html中发送“标准”错误响应。但是,应在API中指定详细信息。

您的实施应优雅地处理该案例。也就是说,您的响应处理程序必须根据响应的Content-Type编码(或解析)响应数据,比如text/html,或者如果合适,则忽略它。更准确地说,您始终应查询HTTP状态代码和内容类型,然后根据您的意愿处理响应。

见Aron Brager的回答如何用AFN解决这个问题。

答案 8 :(得分:-1)

你的Json必须是:

{
    "access" : "1",
    "admin" : "0",
    "code" : "constantine2",

    ...

    "positions" : [
                {
            "departmentID" : "992c93ee-2fa7-4e53-be5f-4e32a45ba5e6",
            "departmentName" : "Dev-C++ resources page (libraries, sources, updates...)",
            ....
        }
    ],
    "userid" : "3b660c13-b856-41fa-a386-814a7b43bacc"
}