前節で, リストのデータをJSONファイルに書き出す・読み込む・削除することができるようになりました. またファイルがない場合の初期化処理も取り扱いました. 一方, 昨今のAppではデータをストレージに保存する以外のパターンが多くなりました。つまりネットワークを介してサーバにアクセスし, JSONといったデータを受け取るという方法です. 今回はJSONを返してくれるサーバにデータをリクエストする例を紹介します.
- SFSwiftUI03-4.swiftpm を開く
(サンプルコード)
- 3-2-5を完了したコードと同様
- photos配列は空っぽ
- Resources/photos.json も存在しない
- また簡単のため,3-3で作成した追加や削除の機能も省いている
- 3-2-5を完了したコードと同様
コード1
|
|
実行結果
何もない状況なので, リストが空っぽになります. 今回は読み込めるJSONファイルもないのでサーバにデータをリクエストする処理を追加します.
- APIAccessor.swiftを新規作成し, サーバにアクセスするコードを記述する
- static func requestPhotos() async関数 を作る
- 戻り値は**[PhotoData]** とする
- async : 非同期であること示す
- サーバアクセスは並列に処理するので非同期にする
- APIの場所は, https://archive.wdkk.co.jp/sf-swiftui/api/photos/
- リクエストに成功するとJSONデータが得られる
- URLRequest( url: ) でアクセスするための情報を用意する
- URLSession.shared.data( for: ) でサーバにリクエストを送る
- 例外を扱う try! と, また非同期関数であるので処理完了を待つ await をつける
- サーバから結果(レスポンス)を得られた場合, result.0 に結果が入っている
- JSONDecoder().decode( … ) で result.0 を [PhotoData] に変換する.
- 変換結果をreturnで返す
コード2
|
|
これで指定したサーバにリクエストする処理ができました. 作成した APIAccessor.requestPhotos() をContentViewで使ってみます. こ注意点はrequestPhotos()は async(非同期)関数 であることです. 非同期ですので他の処理と独立したタスクであることを示す必要があります.
- ContentView.swiftを開く
- .onAppear { … } を追加し, 画面表示時にAPIアクセスを試みる (※ネット接続が必須)
- Task { … } を追加. Task内は独立した非同期処理となる
- APIAccessor.requestPhotos() を使うとき await をつける
- サーバへリクエストしつつ, 処理が終わるまで待機する
- データが得られ次第処理を再開, 結果をphotosへ代入する
- APIAccessor.requestPhotos() を使うとき await をつける
- 実行し, サーバからの結果がリスト化されたら成功
コード3
|
|
結果
今回App内にはリストに表示されたデータはないはずです. それでもリストが表示されたということは外部からデータをとってくることに成功したためです. サーバを利用した多くのソフトウェアサービスはこのように動作していることがわかります. なお,サーバからかえってきた結果を確認したい場合, .onAppear内で print( photos ) を書き, コンソールに出してみてください.