我有一个方法,用于授权用户。我需要基本授权。
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文本没有以数组或 允许片段未设置的对象和选项。)
我应该如何捕获错误类型?
答案 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序列化程序失败,请求将传递给AFHTTPResponseSerializer
,AFHTTPResponseSerializer
应使用适当的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"
}