NSURLConnection重试401状态

时间:2012-12-19 02:02:18

标签: ios nsurlconnection nsurlconnectiondelegate

我正在与验证密码的服务器进行通信,并在无效密码上返回401错误,以及指定失败尝试次数的json正文。服务器在每次失败的验证时都会增加该数字。

我面临的问题是,当NSURLConnection获得401响应时,它会启动涉及这些委托方法的身份验证机制:

  

连接:canAuthenticateAgainstProtectionSpace:

     

连接:didReceiveAuthenticationChallenge:

如果我在 canAuthenticate 方法中返回NO,则会发出新的相同请求。这将导致服务器第二次递增失败的尝试(这显然是不希望的),我将得到401响应( connection:didReceiveResponse:

如果我在 canAuthenticate 方法中返回YES,则会调用 didReceiveAuthenticationChallenge 方法。如果我想停止第二个请求,我可以调用 [challenge.sender cancelAuthenticationChallenge:challenge] 。但如果我这样做,我不会得到401响应,但是错误。

我发现无法捕获第一个401响应。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

1)对于没有客户证书的普通香蕉SSL,您不需要实现这两种方法

2)如果你还想,你应该检查[challenge failureResponse]对象中的HTTP响应代码:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSURLCredential *urlCredential = [challenge proposedCredential];
    NSURLResponse *response = [challenge failureResponse];
    int httpStatusCode = -1;
    if(response != nil) {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        httpStatusCode = [httpResponse statusCode];
    }    
    if(urlCredential != nil || httpStatusCode == 401) {
        //wrong username or more precisely password, call this to create 401 error
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
    else {
        //go ahead, load SSL client certificate or do other things to proceed
    }    
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{       

 return YES;
}

答案 1 :(得分:0)

如果所有其他方法都失败了,请尝试以下方法:一个名为AFNetworking的精彩图书馆,非常容易实现。

它使用块,它极大地简化了类之间的数据通信(取消了委托),并且是异步的。

示例用法如下:

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:"www.yourwebsite.com/api"]];

NSDictionary *params = @{
    @"position": [NSString stringWithFormat:@"%g", position]
};

[client postPath:@"/api" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

}];

就这么简单!结果可直接在调用HTTP Post或Get方法的类中使用。

它甚至包括图像和JSON请求,JSON反序列化,带进度回调的文件下载等等。