alert
로 표시되게 한다.특정한 url
을 이용하여 데이터를 다운로드하고 업로드하기 위한 API
Session Configuration
을 결정하고 Session
을 생성URL
과 Request
객체를 설정Task
를 결정하고 그에 맞는 Completion Handler
나 Delegate
메소드를 작성Task
를 실행Task
완료 후 Completion Handler
클로저 호출위의 사이트에서 제공하는 공공 API를 사용하여 특정 도시의 현재 날씨 정보를 불러올 수 있도록 구현
URLSession
을 사용하여 읽어온 JSON 데이터와 구조체를 매핑시키기 위해 Codable
프로토콜 사용CodingKey
프로토콜 사용WeatherInformation.swift
struct WeatherInformation: Codable {
let weather: [Weather]
let temp: Temp
let name: String
enum CodingKeys: String, CodingKey {
case weather
case temp = "main"
case name
}
}
struct Weather: Codable {
let id: Int
let main: String
let description: String
let icon: String
}
struct Temp: Codable {
let temp: Double
let feelsLike: Double
let minTemp: Double
let maxTemp: Double
enum CodingKeys: String, CodingKey {
case temp
case feelsLike = "feels_like"
case minTemp = "temp_min"
case maxTemp = "temp_max"
}
}
ErrorMessage.swift
struct ErrorMessage: Codable {
let message: String
}
ViewController
class ViewController: UIViewController {
@IBOutlet weak var cityNameTextField: UITextField!
@IBOutlet weak var cityNameLabel: UILabel!
@IBOutlet weak var weatherDescriptionLabel: UILabel!
@IBOutlet weak var tempLabel: UILabel!
@IBOutlet weak var maxTempLabel: UILabel!
@IBOutlet weak var minTempLabel: UILabel!
@IBOutlet weak var weatherStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func tapFetchWeatherButton(_ sender: UIButton) {
if let cityName = self.cityNameTextField.text {
self.getCurrentWeather(cityName: cityName)
self.view.endEditing(true)
}
}
func configureView(weatherInformation: WeatherInformation) {
self.cityNameLabel.text = weatherInformation.name
if let weather = weatherInformation.weather.first {
self.weatherDescriptionLabel.text = weather.description
}
self.tempLabel.text = "\(Int(weatherInformation.temp.temp - 273.15))°C"
self.minTempLabel.text = "최저: \(Int(weatherInformation.temp.minTemp - 273.15))°C"
self.maxTempLabel.text = "최고: \(Int(weatherInformation.temp.maxTemp - 273.15))°C"
}
func showAlert(message: String) {
let alert = UIAlertController(title: "에러", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func getCurrentWeather(cityName: String) {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&appid={api key}") else { return }
let session = URLSession(configuration: .default)
session.dataTask(with: url) { [weak self] data, response, error in
let successRange = (200..<300)
guard let data = data, error == nil else { return }
let decoder = JSONDecoder()
if let response = response as? HTTPURLResponse, successRange.contains(response.statusCode) {
guard let weatherInformation = try? decoder.decode(WeatherInformation.self, from: data) else { return }
DispatchQueue.main.async {
self?.weatherStackView.isHidden = false
self?.configureView(weatherInformation: weatherInformation)
}
} else {
guard let errorMessage = try? decoder.decode(ErrorMessage.self, from: data) else { return }
DispatchQueue.main.async {
self?.showAlert(message: errorMessage.message)
}
}
}.resume()
}
}