VesselWheel

[ReFactoring]Weather777(URLSession -> async/await) 본문

Xcode Study

[ReFactoring]Weather777(URLSession -> async/await)

JasonYang 2024. 4. 27. 10:53

Swift의 async/await 패턴을 사용하여 비동기 처리 부분을 변경하려면 기존의 performRequestForecast 메서드와 getForecastWeather 메서드를 수정해야 합니다. 다음은 async/await를 사용하여 코드를 수정한 예시

먼저, performRequestForecast 함수를 async/await를 사용하도록 변경

 

private func performRequestForecast(with url: URL?) async throws -> WeatherData {
    guard let url = url else {
        throw NetworkError.badUrl
    }

    let (data, _) = try await URLSession.shared.data(from: url)
    do {
        let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
        return weatherData
    } catch {
        throw NetworkError.decodingError
    }
}

 

그 다음, getForecastWeather 메서드를 async/await 패턴으로 업데이트합니다. 이 메서드는 이제 async 함수가 되고, 외부에서 호출할 때 await를 사용해야 합니다. 또한, completion 핸들러 대신 throws를 사용하여 에러를 처리

public func getForecastWeather(latitude: Double, longitude: Double) async throws -> [(cityname: String, time: String, weatherIcon: String, weatherdescription: String, temperature: Double, wind: String, humidity: Int, tempMin: Double, tempMax: Double, feelsLike: Double, rainfall: Double)] {
    LocationManager.shared.setLocation(latitude: latitude, longitude: longitude)
    guard let currentLocation = LocationManager.shared.currentLocation else {
        throw NetworkError.badLocation
    }

    guard let url = URL.urlForForecastForLocation(currentLocation, apiKey: apiKey) else {
        throw NetworkError.badUrl
    }

    let weatherData = try await performRequestForecast(with: url)
    let processor = WeatherDataProcessor()
    let forecastData = processor.process(weatherData: weatherData)

    return forecastData
}

이제 getForecastWeather 메서드는 비동기 함수로 작동하며, 이를 호출할 때는 await 키워드를 사용해야 하며, 호출하는 측에서 에러 핸들링을 위해 do-catch 블록을 사용하거나 에러를 전파해야 합니다.

변경된 메서드를 사용하는 예시

func someFunction() async {
    do {
        let forecastData = try await WeatherManager.shared.getForecastWeather(latitude: xx.xxxx, longitude: yy.yyyy)
        // 여기에서 forecastData 사용
    } catch {
        // 에러 처리
    }
}