エラー処理
エラー処理は、プログラムのエラー状態に応答し、エラー状態から回復するプロセスのことである!
アプリ操作が失敗してエラーになった場合、コードがそれに応じて応答できるようにすることで、失敗の原因を確認、エラー復旧することが可能になる!
エラーの表現
エラーはError
プロトコルに準拠した型によって表される!
enum APIClientError: Error {
case networkError
}
throw文
エラーを投げるには、throw文
を使用する!
throw文は、任意のタイミングでエラーを発生させるときに使用する!throw文でエラーを投げるためには、Errorプロトコルに準拠させる必要がる!
switch (response as? HTTPURLResponse)?.statusCode {
case 200:
let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
let description = weatherData.weather[0].main
let cityName = weatherData.name
return (description, cityName)
default:
throw APIClientError.networkError
}
上記はAPI通信の結果であるresponse
が200 OK
じゃなければエラーを投げる処理。
throwsキーワードを使用した関数によるエラー処理
関数・メソッド・イニシャライザがエラーを投げる可能性があることを示すには、関数の宣言のパラメータの後にthrows
キーワードを記述する。
throws
でマークされた関数は、スロー関数と呼ばれる。
関数が戻り値の型を指定する戻り矢印(->)の前にthrowsキーワード
を記述する。
そうすると、Stringのタプル
or Error
を返す関数になる!
func getWeather(latitude: String, longitude: String) async throws -> (String, String) {
let urlString = "https://api.openweathermap.org/data/2.5/weather?lat=\(latitude)&lon=\(longitude)&appid=\(Constants.apiKey)"
let url = URL(string: urlString)
let urlRequest = URLRequest(url: url!)
let (data, response) = try await URLSession.shared.data(for: urlRequest)
switch (response as? HTTPURLResponse)?.statusCode {
case 200:
let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
let description = weatherData.weather[0].main
let cityName = weatherData.name
return (description, cityName)
default:
throw APIClientError.networkError
}
}
do-catch文を使用したエラー処理
do-catch文
は、次のようにdo
を宣言し、正常時に実行したいコードを記述する。catch
には、エラー時に実行したいコードを記述する。do節の実行中にエラーが発生すると、catch節に実行が移る。
呼び出す側はエラーを返す可能性のあるメソッドをtryキーワード
を使用し、呼び出す!
private func showWeatherView() {
let (latitude, longitude) = PrefectureLatLon().fetchLatLon(weatherPrefecture: prefecture)
Task { @MainActor in
do {
let (description, cityName) = try await WeatherAPIClient().getWeather(latitude: latitude, longitude: longitude)
self.weatherLabel.text = description
self.prefectureLabel.text = cityName
} catch {
let alert = AlertMaker().make(didTapRetry: {
self.showWeatherView()
})
self.present(alert, animated: true, completion: nil)
}
}
}
正常にAPI通信が実行できるとdo{}
内の処理が実行され、ViewにAPIから取得した天気と地域を表示する!
エラーが発生するとcatch{}
内の処理が実行され、アラートを表示する!
おまけ: async/awaitについて知りたい方はこちら
参考文献