[отредактировано, чтобы предоставить дополнительную информацию]
(Я не использую AFNetworking для этого проекта. Я могу сделать это в будущем, но хочу сначала решить эту проблему/недоразумение.)
НАСТРОЙКА СЕРВЕРОВ
Я не могу предоставить реальную услугу здесь, но это простая и надежная служба, которая возвращает XML в соответствии с URL-адресом, например:
https://username:[email protected]/webservice
Я хочу подключиться к URL-адресу через HTTPS с помощью GET и определить любые ошибки аутентификации (код состояния http 401).
Я подтвердил, что веб-сервис доступен, и что я могу успешно (http status code 200) захватить XML из URL с использованием указанного имени пользователя и пароля. Я сделал это с помощью веб-браузера и с AFNetworking 2.0.3 и с помощью NSURLConnection.
Я также подтвердил, что использую правильные учетные данные на всех этапах.
Учитывая правильные учетные данные и следующий код:
// Note: NO delegate provided here.
self.sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig
delegate:nil
delegateQueue:nil];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithURL:self.requestURL completionHandler: ...
Приведенный выше код будет работать. Он успешно подключится к серверу, получит код состояния http 200 и вернет данные (XML).
ПРОБЛЕМА 1
Этот простой подход не выполняется в случаях, когда учетные данные недействительны. В этом случае блок завершения никогда не вызывается, код статуса (401) не предоставляется и, в конечном итоге, время выполнения задачи.
ПОСЛЕДУЮЩЕЕ РЕШЕНИЕ
Я назначил делегата NSURLSession и обрабатываю следующие обратные вызовы:
-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
if (_sessionFailureCount == 0) {
NSURLCredential *cred = [NSURLCredential credentialWithUser:self.userName password:self.password persistence:NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
_sessionFailureCount++;
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
if (_taskFailureCount == 0) {
NSURLCredential *cred = [NSURLCredential credentialWithUser:self.userName password:self.password persistence:NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
_taskFailureCount++;
}
ПРОБЛЕМА 1 ПРИ ИСПОЛЬЗОВАНИИ ПОСЛЕДУЮЩЕГО РЕШЕНИЯ
Обратите внимание на использование ivars _sessionFailureCount и _taskFailureCount. Я использую их, потому что свойство object объекта @previousFailureCount никогда не продвигается! Он всегда остается равным нулю, независимо от того, сколько раз вызываются эти методы обратного вызова.
ПРОБЛЕМА 2 ПРИ ИСПОЛЬЗОВАНИИ ПОСЛЕДНЕГО РЕШЕНИЯ
Несмотря на использование правильных учетных данных (как доказано их успешное использование с делегатом nil), аутентификация не выполняется.
Возникают следующие обратные вызовы:
URLSession:didReceiveChallenge:completionHandler:
(challenge @ previousFailureCount reports as zero)
(_sessionFailureCount reports as zero)
(completion handler is called with correct credentials)
(there is no challenge @error provided)
(there is no challenge @failureResponse provided)
URLSession:didReceiveChallenge:completionHandler:
(challenge @ previousFailureCount reports as **zero**!!)
(_sessionFailureCount reports as one)
(completion handler is called with request to cancel challenge)
(there is no challenge @error provided)
(there is no challenge @failureResponse provided)
// Finally, the Data Task completion handler is then called on us.
(the http status code is reported as zero)
(the NSError is reported as NSURLErrorDomain Code=-999 "cancelled")
(NSError также предоставляет NSErrorFailingURLKey, который показывает мне, что URL и учетные данные верны.)
Любые предложения приветствуются!