さよなら、NSURLConnection第2弾は、NSURLSessionで”PUT”or”POST”です。
ファイルをアップロードするとなると、 最低限 IDとPasswordぐらいのBASIC認証はつきものBASIC認証の機能もつけちゃいます。
Xcode 7 beta5
iOS9 Beta5
Objective-C (swiftは体が拒絶反応中)
通信の準備
今回のソースコードは、アプリのtmpディレクトリー内にある test.zipを読み込みサーバーへ”PUT”です。
test.zipファイルの読み込み
tmpディレクトリーからファイル”test.zip”をNSDataで読み込み長さを取得
// tmpディレクトリ取得 NSString *tmpPath = NSTemporaryDirectory(); // 読み込みファイルフルパス作成 NSString *fileFullPath = [tmpPath stringByAppendingPathComponent:@"test.zip"]; // zipファイル読み込み NSData *zipData = [NSData dataWithContentsOfFile:fileFullPath]; // zipファイルの長さ NSString *zipLength = [NSString stringWithFormat:@"%zd",[zipData length]]; // アップッロード先のフルパスを作成 NSString *serverAddressWithFileName = [@"https://xxx.testServer.com/" stringByAppendingPathComponent:@"test.zip"];
BASIC認証部作成
BASIC認証の部分を作成
// Basic認証 (base64版) NSString *usrPass = @"LoginID:Password"; NSData *poolData = [usrPass dataUsingEncoding:NSUTF8StringEncoding]; NSString *enc64Pass = [poolData base64EncodedStringWithOptions:0]; NSString *basicWithEnc64Pass = [NSString stringWithFormat:@"Basic %@",enc64Pass];
Header部作成
「test.zip読み込み」と「BASIC認証作成」を使用してHeaderを作る
“GET”と違うのは、Headerに”PUT”するデータを仕込みます。
// Header 作成 NSMutableURLRequest *request = [NSMutableURLRequest new]; [request setURL :[NSURL URLWithString:serverAddressWithFileName]]; [request setCachePolicy :NSURLRequestReloadIgnoringLocalCacheData]; [request setHTTPMethod:@"PUT"]; [request setValue:@"zip" forHTTPHeaderField:@"Content-Encoding"]; [request setValue:@"f" forHTTPHeaderField:@"Translate"]; [request setValue:basicWithEnc64Pass forHTTPHeaderField:@"Authorization"]; [request setValue:zipLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody:zipData];
SessionConfigでTime Outの設定
RequestとResoruceのタイムアウト設定
// セッションコンフィグ作成 NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; sessionConfig.timeoutIntervalForRequest = 10; sessionConfig.timeoutIntervalForResource = 30;
NSURLSession設定
NSURLsessionの設定内容
1.sessionWithConfiguration(time out)
2.delegate
3.delegateQueue
// 通信設定 self.sessionConnect = [NSURLSession sessionWithConfiguration: sessionConfig delegate: self delegateQueue: [NSOperationQueue mainQueue]];
dataTaskの設定
今まで作成したものをまとめ
// データタスク作成 NSURLSessionDataTask *dataTask = [self.sessionConnect dataTaskWithRequest:request];
通信開始
NSURLSessionはこれ”resume”で通信開始
// アップロード開始 [dataTask resume];
delegate methodの設定
設定meshodは2つ
– (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^ (NSURLSessionResponseDispositiondisposition))completionHandler
– (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
– (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^ (NSURLSessionResponseDispositiondisposition))completionHandler
いつみてもこのメソッド長すぎです。
サーバーからのレスポンス結果が返ってくるメソッドです。
今回は、response codeに”201″が帰ってくれば成功処理です。
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSLog(@"Response Code : %zd",httpResponse.statusCode); // レスポンスコード [201]で通常処理で終了する。 if (httpResponse.statusCode == 201) { completionHandler(NSURLSessionResponseAllow); // 通信を続ける } else { completionHandler(NSURLSessionResponseCancel); // 通信を止める } }
– (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
“通信成功” “通信失敗” “タイムアウト”するとこのメソッドが呼ばれます
error.codeが”0″以外は失敗扱いで処理
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (error.code == 0) { // アップロード成功処理 } else { // アップロード失敗処理 } // 終わりにする [session invalidateAndCancel]; }
まとめ
今回も駆け足で説明してきました。
これで、NSURLSessionマスターですね(笑)
と言ってもNSURLSessionの一部の機能です。
その他バックグラウンドで動作したりダウンロードの進行状況を取得できたりとNSURLConnectionに無い機能が盛り沢山です。
私もまだまだですがiOSの進化に負けずに頑張ってついていきたいと思います。
ソースコード
#import "testNSURLSession.h" #define UPLOAD_SERVERADDRESS @"https://xxx.xxx.testServer.com/" #define TIME_OUT_REQUEST 10 #define TIME_OUT_RESOURCE 30 @interface testNSURLSession ()<NSURLSessionDataDelegate> @property (nonatomic) NSURLSession *sessionConnect; @end @implementation testNSURLSession #pragma mark - 準備 - (void)uploadFileName:(NSString *)fileName { // tmpディレクトリ取得 NSString *tmpPath = NSTemporaryDirectory(); // 読み込みファイルフルパス作成 NSString *fileFullPath = [tmpPath stringByAppendingPathComponent:fileName]; // zipファイル読み込み NSData *zipData = [NSData dataWithContentsOfFile:fileFullPath]; if (zipData.length == 0) { return; } // zipファイルの長さ NSString *zipLength = [NSString stringWithFormat:@"%zd",[zipData length]]; // アップッロード先のフルパスを作成 NSString *serverAddressWithFileName = [UPLOAD_SERVERADDRESS stringByAppendingPathComponent:fileName]; // Basic認証 (base64版) NSString *usrPass = @"LoginID:Password"; NSData *poolData = [usrPass dataUsingEncoding:NSUTF8StringEncoding]; NSString *enc64Pass = [poolData base64EncodedStringWithOptions:0]; NSString *basicWithEnc64Pass = [NSString stringWithFormat:@"Basic %@",enc64Pass]; // Header 作成 NSMutableURLRequest *request = [NSMutableURLRequest new]; [request setURL :[NSURL URLWithString:serverAddressWithFileName]]; [request setCachePolicy :NSURLRequestReloadIgnoringLocalCacheData]; [request setHTTPMethod:@"PUT"]; [request setValue:@"zip" forHTTPHeaderField:@"Content-Encoding"]; [request setValue:@"f" forHTTPHeaderField:@"Translate"]; [request setValue:basicWithEnc64Pass forHTTPHeaderField:@"Authorization"]; [request setValue:zipLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody:zipData]; // セッションコンフィグ作成 NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; sessionConfig.timeoutIntervalForRequest = TIME_OUT_REQUEST; sessionConfig.timeoutIntervalForResource = TIME_OUT_RESOURCE; self.sessionConnect = [NSURLSession sessionWithConfiguration: sessionConfig delegate: self delegateQueue: [NSOperationQueue mainQueue]]; // データタスク作成 NSURLSessionDataTask *dataTask = [self.sessionConnect dataTaskWithRequest:request]; // アップロード開始 [dataTask resume]; } #pragma mark - NSURLSessin delegate // // レスポンス処理 - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSLog(@"Response Code : %zd",httpResponse.statusCode); // レスポンスコード [201]で通常処理で終了する。 if (httpResponse.statusCode == 201) { completionHandler(NSURLSessionResponseAllow); // 通信を続ける } else { completionHandler(NSURLSessionResponseCancel); // 通信を止める } } // // 通信成功、通信失敗の時呼ばれるメソッド - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (error.code == 0) { // アップロード成功を通知する } else { // アップロード失敗を通知する } // 終わりにする [session invalidateAndCancel]; } @end
コメント