Webからファイルを取得して保存

URL指定でファイルを取得したい場合、従来は以下の方法で取得できたが NSURLConnectionは deprecated(非推奨) となった

//取得先のコンテンツのURLを設定
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/test/mydata.txt"];
];
    
//リクエストを作成
NSURLRequest *req = [NSURLRequest requestWithURL:url];
//レスポンスを作成
NSHTTPURLResponse *res;
NSData *contents = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:nil];

// ファイルへ書き出す
NSString *path = [NSString stringWithFormat:@"%@/mydata.txt", NSHomeDirectory()];
BOOL ret = [contents writeToFile:path atomically:YES];

NSURLSession dataTaskWithRequest:completionHandler に変更せよとのこと

// NSURLSession を使った方式

//NSURLSessionDataTaskは非同期タイプなので、待ち合わせを行う為に、セマホを使う
// 初期値 0で作成しているので、初回は必ず、待ち状態になる。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

//リクエストオブジェクトを作成
NSURL *url = [NSURL URLWithString:@"http://uid:password@localhost/test_login_basic/test.txt"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];


/*
    NSURLSessionConfiguration
    データをアップロードおよびダウンロードするときに使用する動作およびポリシーを定義します。
    データをアップロードまたはダウンロードするときは、常に設定オブジェクトを作成する必要があります。
    このオブジェクトを使用して、タイムアウト値、キャッシュポリシー、接続要件、
    およびNSURLSessionオブジェクトで使用する他の種類の情報を構成します。
    
    ephemeralSessionConfiguration
    エフェメラルセッション構成オブジェクト
    キャッシュ、Cookie、または資格情報に永続ストレージを使用しないセッション構成を返します。
 */
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];


NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

/*
 dataTaskWithRequest:completionHandler:
 指定されたURL要求オブジェクトに基づいてURLの内容を取得し、完了時にハンドラを呼び出すタスクを作成します。
 このタスクは、応答とデータ配信のためにメソッドを委譲するための呼び出しをバイパスし、
 代わりに結果のNSData、NSURLResponse、およびNSErrorオブジェクトを補完ハンドラ内に提供します。
 ただし、認証の問題を処理する代理メソッドは引き続き呼び出されます。
 引数
 completionHandler
 ロード要求が完了したときに呼び出す完了ハンドラ。
 このハンドラはデリゲートキューで実行されます。
 nilを渡すと、タスクが完了するとセッションデリゲートメソッドだけが呼び出され、
 このメソッドはdataTaskWithRequest:メソッドと同等になります。
 */

NSURLSessionDataTask *task = [session dataTaskWithRequest:urlRequest
                                        completionHandler:^(NSData * _Nullable data,
                                                            NSURLResponse * _Nullable response,
                                                            NSError * _Nullable error)
                              {
                                  
                                  NSLog(@"did finish download.\n%@", response.URL);
                                  
                                  if (error) {
                                      NSLog(@"%@", error);
                                      dispatch_semaphore_signal(semaphore);
                                      return;
                                  }
                                  
                                  NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                                  if (httpResponse.statusCode != 200) {
                                      dispatch_semaphore_signal(semaphore);
                                      return;
                                  }
                                  
                                  
                                  NSString *path = [NSString stringWithFormat:@"%@/mydata.txt", NSHomeDirectory()];
                                  BOOL ret = [data writeToFile:path atomically:YES];
                                  if ( ret == YES ) {
                                      NSLog(@"ファイルがダウンロードできました");
                                  } else {
                                      NSLog(@"ダウンロードに失敗しました");
                                  }

                                  /*セマホを+1する*/
                                  dispatch_semaphore_signal(semaphore);
                                  
                              }];

/*タスクが中断している場合は、タスクを再開します。*/
[task resume];

/*
    #define DISPATCH_TIME_FOREVER (~0ull)
    セマホが1になるまで待ち合わせをする。永遠に。
 */
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

NSLog(@"compliate");


参考

http://Cat.jp.as.criteo.com

NSURLConnection から NSURLSession への移行例 - Qiita

Blocksを活用する事例と小技 - Qiita