[iOS]「API通信」

この記事では、APIに関する基礎知識、APIを利用する方法(URLの作成、セッションの作成、セッションにタスクの付与、タスクの開始)、JSONデータのデコーディング方法などについて解説します。

目次

APIの基本概念

APIとは何か?

API(Application Programming Interfaceの略)は、アプリ開発において外部の機能やデータにアクセスするためのインターフェースです。

外部リソースとの連携を実現するAPIの重要性

アプリ開発において、外部の機能やデータにアクセスすることは非常に重要です。

例)ウェザーアプリでは気象情報を取得するために、外部の天気予報サービスと連携する必要があります。そのためには、APIを利用してデータの送受信や操作を行うことが必要です。APIは、このような外部との接続を実現するための強力なツールです。

APIを利用する方法

具体的なコード例を交えながら、実際のアプリケーションでAPIを利用する手順を解説します。

STEP
URLの作成

まずは、APIリクエストを送信するために必要なURLを作成します。

URLは、APIエンドポイントのアドレスや必要なクエリパラメータで構成されます。

URLの作成
// APIエンドポイントとクエリパラメータを指定
let weatherURL =
        "https://api.openweathermap.org/data/2.5/weather?appid=取得ID"

// URLコンポーネントを作成
    func fetchWeather(cityName: String) {
        let urlString = "\(weatherURL)&q=\(cityName)"
        performRequest(with: urlString)
    }

// 作成したURLを取得
   func performRequest(with urlString: String) {
        if let url = URL(string: urlString) {
    }
}
STEP
URLセッションの作成

次に、APIリクエストを送信するためのURLセッションを作成します。

URLセッションは、API通信を管理するためのインターフェースです。

URLセッションの作成
// URLセッションの作成
let session = URLSession(configuration: .default)
STEP
セッションにタスクを付与

APIリクエストを送信するために、URLセッションタスクを付与します。

タスクは、リクエストを作成し、レスポンスを処理するための手続きです。

セッションにタスクを付与
// セッションにタスクを付与
let task = session.dataTask(with: url) { 
    (data, response, error) in

    if error != nil {
        self.delegate?.didFailWithError(error: error!)
        return
    }
                
    if let safeData = data {
        if let weather = self.parseJSON(safeData) {
        self.delegate?.didUpdateWeather(self, weather: weather)
        }
    }
}
STEP
タスクの開始

最後に、付与したタスクを開始します。
タスクが開始されると、APIリクエストが送信され、レスポンスが受け取られます

タスクの開始
// タスクを開始
task.resume()

実際にiOSアプリにAPIの呼び出しを実装した記事を紹介します。プログラムが記載されたページはこちらです。

JSONデータのデコーディング方法

APIからJSON形式で受け取ったデータをデコーディングする方法について解説します。

STEP
デコード用のデータモデルを作成する

データモデルは、JSONデータのキーと対応するプロパティを持つSwiftの構造体クラスです。

デコード用のデータモデルを作成する
struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
}

struct Main: Codable {
    let temp: Double
}

struct Weather: Codable {
    let description: String
    let id: Int
}
STEP
JSONデータをデコードする

次に、受け取ったJSONデータをデコードします。
decoderを使用して、JSONデータを指定したデータモデルのインスタンスに変換します。

JSONデータをデコードする
func parseJSON(_ weatherData: Data) -> WeatherModel? {
    let decoder = JSONDecoder()
    do {
        let decodedData = 
            try decoder.decode(WeatherData.self, 
            from: weatherData)
        let id = decodedData.weather[0].id
        let name = decodedData.name
        let temp = decodedData.main.temp
            
        let weather = WeatherModel(conditionID: id, 
            cityName: name, temperature: temp)
        return weather
    } catch {
        delegate?.didFailWithError(error: error)
        return nil
    }
}
  1. JSONDecoderクラスのインスタンスdecoderを作成します。
    JSONDecoderは、JSONデータをSwiftのデータモデルに変換するためのクラスです。
  2. do-catchブロック内で、decoderを使用してJSONデータをWeatherDataオブジェクトにデコードします。このデコード操作はtryキーワードを使用して行われます。もしデコードに失敗した場合、エラーをcatchブロックでキャッチして処理します。
  3. decodedData.weather[0].id
    デコードされたWeatherDataオブジェクトから天気情報のIDを取得します。
  4. decodedData.name
    デコードされたWeatherDataオブジェクトから都市名を取得します。
  5. decodedData.main.temp
    デコードされたWeatherDataオブジェクトから気温を取得します。
  6. WeatherModelというデータモデルを使って、上記で取得した天気情報ID、都市名、気温を含む新しいweatherオブジェクトを作成します。
  7. 最後に、delegate?.didFailWithError(error: error)を使用して、エラーハンドリングを行います。これにより、エラーが発生した場合にエラー情報を伝えることができます。
  8. エラーが発生した場合はnilを返し、正常にデータが作成された場合はweatherオブジェクトを返します。
STEP
デコードしたデータの利用

デコードが成功すると、JSONデータが指定したデータモデルのインスタンスに変換されます。デコードしたデータを利用して、画面出力や他の処理を行うことができます。

デコードしたデータの利用
extension WeatherViewController: WeatherManagerDelegate {
    func didUpdateWeather(_ weatherManager: WeatherManager, 
        weather: WeatherModel) {

        DispatchQueue.main.async {
            self.temperatureLabel.text = 
                weather.temperatureString
            self.cityLabel.text = 
                weather.cityName
            self.conditionImageView.image = 
                UIImage(systemName: weather.conditionName)
        }
    }
    
    func didFailWithError(error: Error) {
        print(error)
    }
}
  1. WeatherViewControllerWeatherManagerDelegateプロトコルを適用しています。これは、WeatherManagerからのデリゲートメソッドを受け取るためのものです。
  2. didUpdateWeatherメソッドは、WeatherManagerからの天気情報更新の通知を受け取ったときに呼び出されます。引数としてweatherManagerweather(更新された天気情報を含むWeatherModelオブジェクト)が渡されます。
  3. メソッド内部では、UIの更新操作を行うためにDispatchQueue.main.asyncを使用しています。これにより、UIの操作がメインスレッドで実行されることが保証されます。
  4. temperatureLabel.text
    WeatherModelから取得した気温情報を表示するUILabelのテキストを更新しています。
  5. cityLabel.text
    WeatherModelから取得した都市名情報を表示するUILabelのテキストを更新しています。
  6. conditionImageView.image
    WeatherModelから取得した天気のアイコン名を使って、対応するシステムアイコンを表示するUIImageViewのイメージを更新しています。
  7. ここで、UIImage(systemName: weather.conditionName)は、システムのアイコン名を使ってUIImageを生成しています。
  8. didFailWithErrorメソッドは、WeatherManagerからエラーが通知されたときに呼び出されます。引数として受け取ったエラー情報を単純にコンソールに出力しています。

実際にiOSアプリにAPIの呼び出しを実装した記事を紹介します。プログラムが記載されたページはこちらです。

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次