
さよなら、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
  
  
  
  

コメント