Copyright (C) iPhoneアプリ開発備忘録 All rights reserved.
ブログ内で記したコード、内容の正確性は保証いたしません。
記載内容を実装したことにより発生した不具合・損害等の責任は一切負いません。



2016年05月26日

BASIC認証で通信するNSURLConnectionをNSURLSessionに移行する



NSURLConnectionでBASIC認証を行っている通信を、NSURLSessionに移行する方法。

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/
タグ:Mac apple iPAD IOS iPhone
【NSURLSessionの最新記事】
posted by mobileDeveloper at 14:11 | Comment(0) | TrackBack(0) | NSURLSession はてなブックマーク - BASIC認証で通信するNSURLConnectionをNSURLSessionに移行する | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
Apple、Appleのロゴ、App Store、iPodのロゴ、iTunesは、米国および他国のApple Inc.の登録商標です。
iPhone、iPod touch、iPadはApple Inc.の商標です。
iPhone商標は、アイホン株式会社のライセンスに基づき使用されています。
その他、本ブログに記載されている製品名、会社名は、それぞれ各社の商標または登録商標です。