К сожалению, похоже, нет решения этой проблемы.
Вы можете использовать NSURLCredentialPersistenceNone или трюк #, или вы можете определить метод делегата connectionShouldUseCredentialStorage, чтобы возвратить NO. Если вы делаете это каждый раз, и ваше приложение никогда не сохраняет учетные данные для сеанса, это заставит вызов выполняться при каждом запросе.
Для приложений, выполняющих только минимальные запросы или использующих cookie-файл сеанса для проверки подлинности, это может работать нормально.
Для приложений, отправляющих большое количество запросов, все эти решения приводят к ответу 401 на каждый отдельный запрос, и этот дополнительный запрос-ответ может складываться с точки зрения данных и производительности.
Было бы неплохо, если бы вы могли сохранить хранилище учетных данных для сеанса до тех пор, пока вам не потребуется выйти из системы, а затем переключиться на один из обходных путей, но это невозможно.
Как только вы сохраняете учетные данные один раз для сеанса, они кэшируются для всего сеанса TLS. Это приводит к необходимости подождать около 10 минут, пока этот сеанс не закончится.
Подробнее об этом можно прочитать по адресу: http://developer.apple.com/library/ios/qa/qa1727/_index.html
В этом документе упоминается ограниченный обходной путь, который включает добавление "." в конце имени сервера. Однако я не смог заставить это работать.
Кроме этого, я могу подумать о следующих решениях:
1) Всегда используйте обходной путь NSURLCredentialPersistenceNone & connectionShouldUseCredentialStorage, который должен генерировать 401. Добавьте заголовок Basic аутентификации в запрос самостоятельно. Это должно предотвратить лишние 401, а также обход хранилища учетных данных. Код для добавления этой авторизации выглядит примерно так:
NSString *s ;
NSString *authStr ;
s = [NSString stringWithFormat:@"%@:%@",user,password] ;
s = [YourBase64Encoder base64EncodingForData:[NSData dataWithBytes:[s UTF8String] length:strlen([s UTF8String])]];
authStr = [NSString stringWithFormat:@"Basic %@",s] ;
[request setValue:authStr forHTTPHeaderField:@"Authorization"] ;
Я не знаю, как это будет реализовано для других методов аутентификации, но я предполагаю, что это возможно.
2) Сообщите пользователю о проблеме и попросите перезапустить приложение
3) Внедрите свой собственный низкоуровневый механизм поиска http на основе сокетов, который полностью обходит CFNetwork. Удачи в этом:>)