Swift3でHTTPリクエストを試してみる

HTTPリクエストはインターネット上で相互に、Webサーバーとユーザーが通信するための仕組みです。Swift3では、HTTPリクエストを簡単に実装することができます。ここではSwift3のHTTPリクエストの実装/エラーの回避方法について解説していきます。

01: ソースコード

Swift


/*! HTTPリクエスト結果を表示する。
 * @param[out] url HTTPリクエスト先のURL
 */
func getAsync(url :String) {
    let config  = URLSessionConfiguration.default;
    let session = URLSession(configuration: config, delegate: nil, delegateQueue: OperationQueue.main);
    let request = URLRequest(url: URL(string: url)!);

    let task = session.dataTask(with: request) {
        (data, response, error) in
        if ((error) == nil) {
            print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!);
        } else {
            print("AsyncGetHttpRequest:Error");
        }
    };
    
    task.resume();
}

NSURLSessionConfiguration

NSURLオブジェクトを使用してデータをアップロード及びダウンロードするときに使用する動作とポリシーを定義する。データをアップロードまたはダウンロードする時は、必ず設定オブジェクトを作成する必要がある。このオブジェクトを使用してタイムアウト値、キャッシュポリシー、接続要件、及びNSURLSessionオブジェクトで使用する他の種類の情報を構成する。 NSURLSessionオブジェクトは指定した構成設定のコピーを作成し、これらの設定を使用してセッションを構成する。設定が完了すると、NSURLSessionオブジェクトはNSURLSessionConfigurationオブジェクトに対する変更をすべて無視する。

NSURLSession

NSURLSessionクラス及び関連するクラスはコンテンツをダウンロードするためのAPIを提供する。このAPIは、認証をサポートするデリゲートメソッドの豊富なセットを提供し、アプリが実行されていないとき、またはiOSでアプリが中断されているときにバックグラウンドダウンロードを実行できるようにする。NSURLSessionクラスはFTP、HTTP(HTTP/1.1、SPDY、HTTP/2)、HTTPSのプロトコルをネイティブにサポートしている。

NSURLRequest

NSURLRequestクラスは、URLリクエストに関する情報をカプセル化するためだけに使用される。これらのリクエストをサーバーに送信するためには、NSURLSessionやNSURLConnectionなどの他のクラスを使用する必要がある。 NSURLRequestは独自のプロトコル固有のプロパティ用のアクセサメソッドを提供するカテゴリを追加することによって、追加のプロトコルをサポートするように拡張されている。

dataTask(with:completionHandler:)

指定されたURLリクエストオブジェクトに基づいてURLの内容を取得し、完了時にハンドラを呼び出すタスクを作成する。このタスクは、応答及びデータ配信のためにメソッドを委譲するための呼び出しをバイパスし、代わりに、結果のNSData、NSURLResponse、及びNSErrorオブジェクトをクロージャ内に提供する。ただし、認証の問題を処理する代理メソッドは引き続き呼び出される。

NSString

NSStringクラスとその可変サブクラスNSMultableStringクラスは文字列を比較、検索、及び変更するメソッドを含む、文字列を操作するための広範なAPIセットを提供する。Object-Cで使用されていたが、Swiftからは新たに追加されたString型の利用が推奨されている。

Closureとは

{(引数:引数の型) -> 戻り値の型 in
    ステートメント
    return 戻り値
}

Trailing Closureとは

関数の引数の末尾がClosureを受け取る場合、処理部分を外に配置できる。これによってコードの可読性が上がり、見やすいコードになる。サンプルプログラムのdataTask部分はこのTrailing Closureを使用している。

?とか!とは

String?のように型の後ろに?を付けるとnilを代入できるOptional型にラップされる。String?はOptionalを簡単にした書き方である。この形はOptional型でラッピングされた状態なので、String型の値を入力できてもそのままメソッドや値の操作を実行できない。また!を付けることで無条件にアンラップすることができる。

そもそもNSプレフィクスとは

NSはNeXTSTEPという基本ソフト(OS)の名残。NEXTSTEPはmacOSやiOSの前身に当たる。 Objective-CではこのNSプレフィクスを付けることで名前の衝突を避けていましたが、 Swiftになってモジュールによって名前空間が分けられるようになったため、このNSプレフィクスを付ける必要が無くなった。
説明文として、クラスの表現ではNSプレフィクスが付き、実際のソースコード部分ではNSが付かないことが多い。

Swift3のFoundationとは

  • Objective-CのFoundation実装をそのまま利用している。
  • Objective-CのFoundationにある全ての機能があるわけではない。
  • NSプレフィクスの除去が一つの目的である。

02: エラー発生


2017-01-17 20:06:10.402410 restAPI[1236:360892] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

03: 解決策

ios9では、HTTP通信が許可されていないのでエラーが発生している。Info.plistに下記内容を追記し、HTTP通信を許可する。
ios9からはデフォルトの通信がHTTPS通信になっている。

Info.plist

  
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>zipaddress.net</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>