【SwiftUI】外部サイトからデータを取得する

(2021/04/03 更新)

外部サイトからJSON形式のデータを取得する方法を解説します。

スポンサーリンク

環境

この記事の情報は次のバージョンで動作確認しています。

【Xcode】12.4
【Swift】5.3.2
【iOS】14.4
【macOS】Big Sur バージョン 11.1
スポンサーリンク

やりたい事

Appleが提供するiTunes APIにアクセスして、次のように「SwiftUI」のキーワードを含む書籍の一覧を取得し表示します。

実行例

iTunes APIの仕様

AppleのiTunes APIのサーチ機能は次のようなURLで呼び出します。

各引数の意味は次の通りです。

引数 説明
term 検索キーワード
country 対象となる国コード。日本はjp
media 取得する商品の種類を指定。電子書籍はebook。



結果は次のようなJSON形式で取得されます。

スポンサーリンク

全体ソース

はじめに全体ソースをお見せします。
次章以降で各処理の解説をします。

スポンサーリンク

データを格納する構造体の定義

次の箇所が、データを格納する構造体の定義部分です。

ResponseはAPIから取得したJSONデータを変換して格納する構造体、Resultは個々の書籍情報が格納される構造体です。
JSON→オブジェクト変換を行う為、どちらの構造体もCodableプロトコルに準拠させます。
Codableについて知りたい場合は、別の記事「【Swift】Codableを使ったJSON変換」を参照して下さい。
いずれもAPIからの戻り値の中で、今回のアプリに必要な項目のみ定義しています。
ここに定義されていない項目は、JSON→オブジェクト変換の際に切り捨てられます。

Result構造体で、trackId以外の3プロパティは必ずしも存在していない可能性があるので、オプショナル型としています。

スポンサーリンク

検索結果表示(UI)の定義

検索結果をリスト形式で表示するUI定義部です。

検索結果を格納する空の配列(results)を生成し、バインドしています。
.onAppearモディファイアで、NavigationViewが表示された際に、loadData()メソッドを呼び出し、バインドされた配列に検索結果をロードします。

スポンサーリンク

リクエストURL(URLRequest)の生成

次がリクエストURLの生成部です。

まずURL文字列からURLクラスを生成し、それを使ってURLリクエストにします。
URLクラスは引数に指定した文字列が有効なURLで無い場合はnilを返すので、guard文を使ってエラー時の処理を記述します。

URLRequestは、URLの読み込み方法を制御する為に様々なカスタマイズが可能です(例えばGETではなくPOSTを使う等)が、今回はデフォルトのまま使います。

スポンサーリンク

リクエストの実行

前章で生成したURLリクエストを実行する部分です。

URLSessionは、ネットワーク要求の管理を担当するiOSクラスです。
必要に応じて独自のセッションも作成できますが、sharedプロパティを使うとiOSが使用するために作成した共有セッションが使用できます。この共有セッションは基本的なリクエストを実行するのに適した標準セッションです。

dataTaskメソッドは、URLコンテンツの取得タスクを作成します。引数にはURLRequest、タスク完了時の処理をクロージャーで指定します。
クロージャーには次の3つのパラメーターが渡ります。

data
サーバーから返されたデータ

response
URLアクセスのレスポンス情報を格納したURLResponseオブジェクト

error
リクエストが失敗した理由を示すエラーオブジェクト。リクエストが成功した場合はnil。

リクエストが正常に完了すると、dataにリソースデータが返され、errorはnilになります。
リクエストが失敗した場合は、dataはnil、errorには失敗に関する情報が返されます。
responseには、リクエストが成功したか失敗したかに関係なく、レスポンス情報が含まれます。

重要ポイント

URLSessionオブジェクトによって生成されたタスクは自動的にバックグラウンドスレッドで実行されます。
これによりUIのインタラクティブ性を損なわずに、ネットワークリクエストの実行が可能となります。
なお、新しく初期化されたタスクは一時停止状態で開始されるため、必ず最後にresume()メソッドを呼び出してタスクを開始する必要があります。

スポンサーリンク

リクエストタスク完了時の処理

URLリクエスト実行後の処理です。

「①データ取得チェック」
サーバーからデータが取得できたか否かをチェックします。
"if let"は対象プロパティのnil判定とアンラップ処理を同時に行う、Swiftの特徴的な記述方法です。

「②JSON→Responseオブジェクト変換」
取得したJSONデータをSwiftのオブジェクトに変換します。
詳しい解説が必要な方は、別の記事「【Swift】Codableを使ったJSON変換」を参照して下さい。

「③書籍情報をUIに適用」
UIにバインドされたresultsプロパティに取得したデータを適用します。
iOSではUI関連の作業はすべてメインスレッドで行うようにして、不要な衝突を避けるのがセオリーです。
その為の仕組みが、DispatchQueue.main.asyncです。
このメソッドは、処理をクロージャーとして指定すると、メインスレッドの処理キューに追加され、現在実行中のUI処理が完了後に処理されます。
バックグラウンドスレッド側は、クロージャーの実行を待たずに、次の処理に移れます。

「④データが取得できなかった場合の処理
サーバーからデータが取得できなかった場合の処理を記述する箇所です。
エラーオブジェクトが存在する場合はエラーメッセージを、そうでない場合は固定メッセージを出力しています。

スポンサーリンク

あわせて読みたい記事

【Swift】Codableを使ったJSON変換
Codableを使ったJSON変換について解説します。
【SwiftUI】@ObservedObjectをCodable変換する方法
@ObservedObjectをCodable変換する方法について解説します。