hogeViewController.h
<変更前>
@interface hogeViewController : UIViewController <NSURLConnectionDelegate>
<変更後>
@interface hogeViewController : UIViewController <NSURLSessionDelegate, NSURLSessionTaskDelegate>
hogeViewController.m
<変更前>
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge proposedCredential]) {
[connection cancel];
} else {
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"hoge" password:@"Fuga" persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
<変更後その1>
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
NSURL *url = task.originalRequest.URL;
// 認証情報ストレージを取得
NSURLCredentialStorage *storage = [NSURLCredentialStorage sharedCredentialStorage];
// 認証情報ストレージのキーとなるNSURLProtectionSpaceを作成
NSURLProtectionSpace *ps = [[NSURLProtectionSpace alloc] initWithHost:url.host
port:[url.port integerValue]
protocol:url.scheme
realm:@"Please input user name and password."
authenticationMethod:NSURLAuthenticationMethodDefault];
// 認証情報を取得
NSURLCredential *credential = [storage defaultCredentialForProtectionSpace:ps];
if (!credential) {
// 認証情報を作成、保存する
credential = [[NSURLCredential alloc] initWithUser:@"Hoge"
password:@"Fuga"
persistence:NSURLCredentialPersistenceForSession];
[storage setCredential:credential forProtectionSpace:ps];
}
if ([challenge previousFailureCount]>0) {
// 1度でも認証失敗している場合はキャンセルする
[task cancel];
[session invalidateAndCancel];
}
else {
// 認証リクエスト
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengeUseCredential;
completionHandler(disposition, credential);
}
}
<変更後その2>
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
if ([challenge previousFailureCount] > 0) { // 1度でも認証失敗している場合
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); // キャンセルする
} else {
NSString *authMethod = challenge.protectionSpace.authenticationMethod;
if ([authMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) { // BASIC認証の場合
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"Hoge"
password:@"Fuga"
persistence:NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else { // BASIC認証以外の場合
// completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); // デフォルト処理にして認証を無効扱いにする
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); // キャンセルする
}
}
}
BASIC認証の場合、<変更後その1><変更後その2>のどちらでも通信できる。
<変更後その1>の場合の、NSURLProtectionSpaceのプロパティ"realm"は、ターミナルから下記コマンドにより取得できる。
curl -Iv 'http://hoge.com/'
...
# WWW-Authenticate: Basic realm="Please input user name and password."
...
<変更後その2>の場合の、デリゲートメソッドで受け取った認証方法がBASIC認証以外の場合は、処理をキャンセルするか、デフォルト処理にするかは任意(機能に応じて適宜変更する)。
参考記事:
http://www.slideshare.net/msyknii/cocoa62nsurlsession
http://blog.ikenie3.org/nsurlsessionde/
http://iphone-dev.g.hatena.ne.jp/laiso/20120301/1330611905
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLProtectionSpace_Class/#//apple_ref/doc/constant_group/NSURLProtectionSpace_Authentication_Methods
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionDelegate_protocol/#//apple_ref/c/tdef/NSURLSessionAuthChallengeDisposition
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLAuthenticationChallenge_Class/
【NSURLSessionの最新記事】