2013-12-13 35 views
14

我有一个授权用户的方法。我需要基本授权。如何获取AFNetworking中的状态代码

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

你可以发布你试图得到的JSON吗? –

+0

我已经更新了我的问题,我发布了回复,我正在努力获取 – abekenza

回答

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

当我们移动到64位拱时,应该使用NSInteger。 – ryanconnellyatl

+4

这对使用任务的'AFURLSessionManager'无效,而不是'AFHTTPRequestOperation' –

-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" 
} 
+0

我相信JSON是正确的,因为我可以解析数据,当我输入正确的登录名和密码时。当我输入不正确的登录名或密码时会出现问题。服务器端向我发送html响应(错误401,用户未被授权)而不是json。我想捕捉错误,以便如果错误类型等于401,我想显示一个alertview,如“用户不被授权”,如果错误类型等于404,我想显示用户“不正确的URL消息”。任何帮助,将不胜感激。 – abekenza

+0

反而把-1正确地写你的问题。答案是:[self parseResponseForUser:responseObject];检查你的responceObject内容和类型,如果(是404?){alert} else {[self parseResponseForUser:responseObject];} – Dimentar

+0

我没有把-1给你。我只有13个声望,我甚至不能投票。我现在只能选择最好的答案 – abekenza

0

它看起来像你的服务器可能与HTML响应,或者它可能与JSON响应。但是当你输入:

[manager setResponseSerializer:[AFJSONResponseSerializer serializer]]; 

你告诉AFNetworking期望JSON。

相反,尝试告诉它来处理普通的HTTP响应,如果它不是JSON:现在

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

,如果JSON序列化失败,请求将被传递给AFHTTPResponseSerializer,应该打电话给你的不良区使用适当的HTTP错误代码而不是JSON解析错误。

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

+0

谢谢,AAron。今天,我尝试了这个解决方案,但是我从我应该导入AFCompoundSerializer的地方开始使用Stucked。阅读AFNetworking的文档我找到了获取statusCode的方法。 – abekenza

0

它经常发生,服务器可能会发送一个不同于请求的内容类型的响应,如果它们发送错误。当请求由于认证错误失败

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

,:

例如发送请求时使用JSON为Content-Type和期待来自服务器的JSON响应,一个将指定以下请求头服务器可能会向您发送状态码401 (Unauthorized)加上包含相关诊断信息的可选响应。

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

你的实现应该优雅地处理这种情况。也就是说,您的响应处理程序必须根据响应的Content-Type(如text/html)对响应数据进行编码(或解析),或者在适当的情况下忽略它。更确切地说,您总是应该查询HTTP状态码和内容类型,然后做出明智的决定,您要如何处理响应。

请参阅Aron Brager的答案如何解决AFN的问题。

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

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

5

下面是我如何做到这一点。

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

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

谢谢它的作品适合我 –

0
通过使用NSURLError枚举阿洛克塔瓦的

改进的响应:

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

这里是如何做到这一点的斯威夫特

((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; 
    } 
}