ios 如何在 AFNetworking 中获取状态代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20566194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:45:58  来源:igfitidea点击:

How to get status code in AFNetworking

iosafnetworkingafnetworking-2

提问by abekenza

I have a method, for authorizing user. I need Basic authorization.

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

    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);
    }];

The main problem here is determining error type. I may have error for authorization and error for network connection problem (host is not reachable). When login and password don't match criteria, failure block runs. For example, If I put wrong password and login I take this error message.:

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

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.)

错误域=NSCocoaErrorDomain 代码=3840 “操作无法完成。(Cocoa 错误 3840。)”(JSON 文本没有以数组或对象开头,并且没有设置允许片段的选项。)

How should i catch error types?

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

回答by abekenza

Finally found answer, may be it will be helpful for someone. I just needed to use:

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

NSInteger statusCode = operation.response.statusCode;

And i can catch it like:

我可以抓住它:

    [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) {
        }
    }];

回答by webstersx

In AFNetworking 3.0+ and in the case of an error, you can access the status code in the failure block's error.userInfo object:

在 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
}];

回答by alok srivastava

you can give a try to get code from error and then show messages accordingly.

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

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

similarly you can check for other code.

同样,您可以检查其他代码。

回答by JohnVanDijk

Here's how I do it.

这是我如何做到的。

[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;
               }
             }];

回答by solven

Improved response of alok srivastava by using NSURLError enum:

通过使用 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
}}];

回答by Penkey Suresh

Here is how to do it in Swift

以下是如何在 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;
    }
}

回答by Aaron Brager

It looks like your server might respond with HTML, or it might respond with JSON. But when you type:

看起来您的服务器可能以 HTML 响应,也可能以 JSON 响应。但是当你输入:

[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];

You're telling AFNetworking to expect JSON.

您告诉 AFNetworking 期待 JSON。

Instead, try telling it to handle a regular HTTP response if it's not JSON:

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

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

Now, if the JSON serializer fails, the request will be passed to the AFHTTPResponseSerializer, which should call your failure block with the appropriate HTTP error code instead of the JSON parsing error.

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

Incidentally, AFHTTPResponseSerializeris subclass-able, so feel free to take a look at that option if you want more specific behavior.

顺便说一句,AFHTTPResponseSerializer是子类化的,所以如果你想要更具体的行为,请随意查看该选项。

回答by CouchDeveloper

It happens frequently, that servers may send a response in a different content type than requested IF they are sending an error.

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

For example when sending a request with JSON as Content-Type and expecting a JSON response from the server, one would specify the following request headers:

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

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

When the request fails due to an authentication error, the server may send you a status code of 401 (Unauthorized)plus an optional response which contains relevant diagnostic information.

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

Strictly, web servers should respect the Accept header, but unfortunately, some don't and will send a "standard" error response in text/htmlfor example. The details should be specified in the API, though.

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

Your implementation should handle that case gracefully. That is, your response handler must encode (or parse) the response data according the Content-Typeof the response, say text/htmlor ignore it if suitable. More precisely, you always should query the HTTP status code AND the content type and then make an informed decision how you want to treat the response.

您的实现应该优雅地处理这种情况。也就是说,您的响应处理程序必须根据响应的 编码(或解析)响应数据Content-Typetext/html如果合适,可以说或忽略它。更准确地说,您应该始终查询 HTTP 状态代码和内容类型,然后做出您希望如何处理响应的明智决定。

See Aron Brager's answer how to solve that issue with AFN.

请参阅 Aron Brager 的回答如何使用 AFN 解决该问题。

回答by Dimentar

your Json must be:

你的 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"
}