JY-CONTENTS

JY

JY-CONTENTS
search

+

MENU

【Swift】APIクライアント

【Swift】APIクライアント

(DATE)

-

2018.09.03

(CATEGORY)

-

APIクライアントは、リクエストの情報をもとにWeb APIを呼び出し、そのレスポンスを呼び出し元に返します。
webAPIをアプリで利用するときにはURLSessionを使用しますが、URLRequestクラス、HTTPURLResponseクラスも使用するので、その説明もしています。

URLRequest

URLRequestクラスは通信のリクエストをカプセル化した型です。
HTTPリクエストのURL、HTTPヘッダ、HTTPメソッド、HTTPボディなどの情報を持つことができます。URLRequestクラスのインスタンスは、URLSessionクラスを通じて、最終的に次のようなHTTPリクエストとしてHTTPサーバに送信されます。

HTTPリクエストの例(中身)

GET /search/repositories HTTP/1.1
Host: api.github.com
Accept: application/json
Accept-Encoding: gzip, deflate
Accept-Language: ja-jp
Connection: keep-alive
User-Agent: Demo/1 CFNetwork/760.1.2 Darwin/15.0.0 (x86_64)

HTTPURLResponse

HTTPURLResponse型はHTTPレスポンスのメタデータをカプセル化したクラスで、HTTPステータスコードなどの情報を表します。

下記コードにて、受け取ったHTTPレスポンスのメタデータには、dataTask(with:completionHandler:)メソッドのコールバック関数の中でアクセスできます。
コールバック関数の第2引数の型はURLResponse型ですが、このURLResponse型はHTTPURLResponse型のスーパークラスです。
URLResponse型はHTTPレスポンスに限らない、より抽象的なレスポンスを表現するための型です。

import UIKit

//url生成
let url = URL(string: "https://api.github.com/search/repositories?q=swift")!
//httpリクエスト生成
let urlRequest = URLRequest(url: url)

//セッション情報取り出し
let session = URLSession.shared

//レスポンスを受け取る通信処理
let task = session.dataTask(with: urlRequest) {data, urlResponse, error in
    
    //コールバッククロージャの第2引数はURLResponse型なのでHTTPURLResponseにダウンキャスト
    if let urlResponse = urlResponse as? HTTPURLResponse {
        //----以下“HTTPレスポンスのメタデータ-------
        urlResponse.statusCode // 200
        // "Tue, 10 Nov 2015 19:23:13 GMT"
        urlResponse.allHeaderFields["Date"]
        // "application/json; charset=utf-8"
        urlResponse.allHeaderFields["Content-Type"]
    }
}

task.resume()

URLSession

webAPIをアプリで利用するときにはURLSessionを使用します。

URLSessionクラスは通信タスクを管理するためのクラスです。
HTTPリクエストを表すURLRequest型の情報をもとにHTTPサーバと通信し、その結果はHTTPレスポンスを表すHTTPURLResponse型とバイナリデータを表すData型のペアとして表現されます。
リクエストごとの通信タスクはURLSessionTaskクラスとして表現され、URLSessionクラスはそれぞれのタスクを管理します。

URLSessionTaskクラス

URLSessionTaskクラスには、用途ごとに

  • URLSessionDataTask
    JSONデータ等のデータの取得を行うには、URLSessionDataTaskクラスを利用します。
    サーバから取得したデータ結果をDataとしてメモリ上に保持します。
  • URLSessionUploadTask
    サーバにデータをアップロードするために使用する
  • URLSessionDownloadTask
    サーバからデータを取得し、ファイルに保存するために使用する

の3つのサブクラスがあります。

仕様

sharedクラスプロパティ

sharedクラスプロパティを利用することでURLSessionクラスのインスタンスを簡単に取得できますが、キャッシュやCookieの設定などを細かく設定したい場合は、URLSessionConfiguration型の値を引数に取るイニシャライザを使用して、URLSessionクラスのインスタンスを生成します。

dataTask(with:completionHandler:)メソッド

URLRequest型のインスタンスからURLSessionDataTask型の値を生成して通信を行うにはdataTask(with:completionHandler:)メソッドを呼び出します。

let session = URLSession.shared
let task = session.dataTask(with: URLRequest, completionHandler: (Data?, URLResponse?, Error?) -> Void)

第1引数にはURLRequest型の値を渡し、第2引数には通信の完了時に実行されるクロージャを渡します。dataTask(with:completionHandler:)メソッドの戻り値はURLSessionDataTask型です。
戻り値のURLSessionDataTaskクラスの値に対してresume()メソッドを実行すると、通信が開始されます。

import UIKit

//URLSessionクラスのインスタンスを取得
let session = URLSession.shared

let task = session.dataTask(with: urlRequest) {
    data, urlResponse, error in
    // 通信完了時に実行される
}

task.resume()

下記はヤフーのトップ画面の情報のリクエスト、レスポンスの簡単なやりとりになります。

import UIKit
import PlaygroundSupport

//非同期処理の実行許可
PlaygroundPage.current.needsIndefiniteExecution = true

//URLSessionのインスタンス取得
let session = URLSession.shared
    
//urlオブジェクト生成
let url = URL(string: "https://www.yahoo.co.jp")!
    
//リクエストオブジェクト生成
let request = URLRequest(url: url)

//httpリクエストを元に処理タスクを生成(レスポンスを受け取る通信処理)
let task = session.dataTask(with: request){(data, response, err) in
    //▼以下データ取得後の処理(コールバック)
    
    //エラーが返ってきた場合は処理を終(エラーでない時はerrはnil)
    if err != nil {
        return
    }
    
    //リクエストしたサーバ(ヤフー)からデータが返って来なかった場合はエラーを表示して処理を終了
    guard let data = data else {
        print("エラー!サーバから応答がありません。")
        return
    }
    
    //サーバから返ってきたデータ(レスポンスデータ(バイナリデータ))を文字列に変換して表示
    if let val = String(data: data, encoding: String.Encoding.utf8){
        print(val)
    }else {
        print("文字列に変換できませんでした。")
    }
}

//処理開始
task.resume()

定数valの表示結果

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="content-script-type" content="text/javascript">
<meta name="description" content="日本最大級のポータルサイト。検索、オークション、ニュース、メール、コミュニティ、ショッピング、など80以上のサービスを展開。あなたの生活をより豊かにする「ライフ・エンジン」を目指していきます。">
<meta name="robots" content="noodp">
<meta name="google-site-verification" content="fsLMOiigp5fIpCDMEVodQnQC7jIY1K3UXW5QkQcBmVs">
<link rel="canonical" href="https://www.yahoo.co.jp/" />
<link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.yahoo.co.jp/">
<link rel="alternate" href="android-app://jp.co.yahoo.android.yjtop/yahoojapan/home/top">
<title>Yahoo! JAPAN</title>
・・・・・・・・・・

NEW TOPICS

/ ニュー & アップデート

SEE ALSO

/ 似た記事を見る

JY CONTENTS UNIQUE BLOG

search-menu search-menu