일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- CoreLocation
- Xcode
- font book
- swift
- Protocol
- dispatchsource
- MKMapItem
- Startign Assignments
- 서체관리자
- 영문 개인정보처리방침
- Required Reason API
- 러닝타이머
- AnyObject
- addannotation
- UIAlertAction
- SwiftUI Boolean 값
- 단일 책임원칙
- 클로저의 캡슐화
- xcode로 날씨앱 만들기
- App Store Connect
- RunningTimer
- weatherKit
- weak var
- MKMapViewDelegate
- Timer
- UICollectionViewFlowLayout
- WeatherManager
- 러닝기록앱
- CLLocationManagerDelegate
- 한국어 개인정보처리방침
Archives
- Today
- Total
VesselWheel
5일치 3시간 단위 날씨예보 배열에 넣기(with OpenWeatherMap) (1/2) 본문
https://vesselwheel.tistory.com/185
상기 주소의 이전글을 참고하여
//위치데이터
1. LocationMager 클래스에서 싱글톤으로 현재위치 혹은 지정위치를 호출하여 위경도를 받으면,
// API call
2. WeatherManager의 getForestWeather 매소드가 파라미터로 받은 위경도 기준 지역의, API에서 날씨 데이터를 호출(API call)한다.
이어서,
API call에서 받은 데이터를 forecastData의 빈배열에 넣어, 뷰계층에서 사용할 수 있도록 데이터를 가공해야한다.
-> ViewController에서 데이터를 가공하게되면, 코드단에서 길어지고, 복잡해지기 때문에 네트워크요청하는 WeatherManager에서 싱글톤 패턴의 하위에 있는 매소드에 넣었다.
// API call에서 데이터를 forecastData 배열에 넣기
3. API call에서 url이 정상적으로 주입되면 let weatherData에 data가 저장이 된다.
더보기
public func getForecastWeather(latitude: Double, longitude: Double, completion: @escaping(Result<[(time: String, weatherIcon: String, temperature: Int, wind: String)], NetworkError>) -> Void) {
// 위치데이터
LocationManager.shared.setLocation(latitude: latitude, longitude: longitude)
guard let currentLocation = LocationManager.shared.currentLocation else {
return completion(.failure(.badLocation))
}
//API call
guard let url = URL.urlForForecastForLocation(currentLocation, apiKey: apiKey) else {
return completion(.failure(.badUrl))
}
//API call에서 데이터를 forecastData 배열에 넣기
performRequestForecast(with: url) { result in
switch result {
case .success(let weatherData):
// 날씨 데이터를 성공적으로 받아왔을 때
var forecastData: [(time: String, weatherIcon: String, temperature: Int, wind: String)] = []
for list in weatherData.list {
let time = list.dtTxt
let weatherIcon = list.weather.first?.icon ?? ""
let temperature = Int(list.main.temp)
let windSpeed = list.wind.speed
let forecast = (time: time, weatherIcon: weatherIcon, temperature: temperature, wind: "\(windSpeed) m/s")
forecastData.append(forecast)
}
completion(.success(forecastData))
case .failure(let error):
// 날씨 데이터를 받아오는데 실패했을 때
completion(.failure(error))
}
}
}
3-1. getForestWeather 매소드에서 API call을 요청하면, 종속된 private performRequestForecast 매소드를 활용하여 주입된 데이터를 디코딩해준다.
해석
더보기
- performRequestForecast(with:completion:) 메소드는 URL을 인자로 받아, 이를 통해 HTTP 요청을 수행합니다. 이 메소드는 비동기적으로 동작하며, 요청이 완료되면 클로저를 통해 결과를 반환합니다.
- URLSession.shared.dataTask(with:completion:)를 사용하여 실제 HTTP 요청을 수행합니다. 이 함수는 비동기적으로 동작하며, 서버로부터 응답이 오면 클로저를 호출합니다.
- 클로저 내부에서는 먼저 에러가 있는지 확인합니다. 에러가 있거나 데이터가 없는 경우, .failure(.noData)를 반환해 에러를 알립니다.
- 그 다음으로, JSONDecoder를 사용해 서버로부터 받은 데이터를 디코딩합니다. 디코딩된 데이터는 WeatherData 타입의 인스턴스로 변환되며, 이는 .success(weatherData)를 통해 반환됩니다.
- 만약 디코딩 과정에서 에러가 발생하면, 에러 메시지를 출력하고 .failure(.decodingError)를 통해 에러를 반환합니다.
- 마지막으로, resume() 메소드를 호출하여 URLSession의 작업을 시작합니다. 이 메소드를 호출하지 않으면 네트워크 요청이 시작되지 않습니다.
이 코드는 Swift의 Result 타입을 사용하고 있습니다. Result 타입은 성공 또는 실패 두 가지 경우 중 하나를 나타내는 열거형으로, 성공한 경우에는 연관값으로 성공 결과를, 실패한 경우에는 연관값으로 에러를 가집니다. 이를 통해 비동기 작업의 결과를 표현하는 데 유용합니다.
더보기
// OpenWeatherMap의 API 요청시 5일치 3시간 단위 예보 날씨정보를 처리하는 메소드
private func performRequestForecast(with url: URL?, completion: @escaping (Result<WeatherData, NetworkError>) -> Void) {
guard let url = url else {
return completion(.failure(.badUrl))
}
URLSession.shared.dataTask(with: url) { data, Response, error in
// 응답과 에러,데이터 출력 : 정상출력됨
// print("ForecastData: \(String(describing: data))")
// print("ForecastResponse: \(String(describing: Response))")
// print("ForecastError: \(String(describing: error))")
guard let data = data, error == nil else {
return completion(.failure(.noData))
}
do {
let weatherData = try JSONDecoder().decode(WeatherData.self, from: data)
completion(.success(weatherData))
} catch {
print("Forecast Decoding error: \(error)")
completion(.failure(.decodingError))
}
}.resume()
}
4. ViewController ViewDidLoad()에서 테스트
- forecastData 빈 배열을 초기화하고, 싱글톤으로 WeatherManager의 getForecastWeather매소드를 통해 데이터를 호출한다.
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUI()
setAddSubView()
setLayout()
let latitude = 37.4536
let longitude = 126.7317
var forecastData: [(time: String, weatherIcon: String, temperature: Int, wind: String)] = []
WeatherManager.shared.getForecastWeather(latitude: latitude, longitude: longitude) { result in
switch result {
case .success(let data):
forecastData = data
// forecastData 배열에 데이터가 들어갔는지 확인
for forecast in forecastData {
print("Time: \(forecast.time)")
print("Weather Icon: \(forecast.weatherIcon)")
print("Temperature: \(forecast.temperature)°C")
print("Wind Speed: \(forecast.wind)")
print("----------")
}
case .failure(let error):
print("Error: \(error)")
}
}
// 3시간 뒤의 최고 온도와 최저 온도 업데이트
// updateForecastWeather()
// 위치정보를 가져오는 시간이 걸리더라도 날씨정보를 우선 업데이트해서 UI를 변경하여 viewDidLoad()에서 즉시 반환
// LocationManager.shared.requestLocation()
}
}
5. 콘솔창에 출력된 모습
더보기
Time: 2024-02-13 09:00:00
Weather Icon: 02d
Temperature: 286°C
Wind Speed: 4.46 m/s
----------
Time: 2024-02-13 12:00:00
Weather Icon: 02n
Temperature: 284°C
Wind Speed: 3.73 m/s
----------
Time: 2024-02-13 15:00:00
Weather Icon: 01n
Temperature: 282°C
Wind Speed: 2.69 m/s
----------
Time: 2024-02-13 18:00:00
Weather Icon: 03n
Temperature: 280°C
Wind Speed: 2.43 m/s
----------
Time: 2024-02-13 21:00:00
Weather Icon: 04n
Temperature: 280°C
Wind Speed: 2.46 m/s
----------
Time: 2024-02-14 00:00:00
Weather Icon: 04d
Temperature: 281°C
Wind Speed: 2.6 m/s
----------
Time: 2024-02-14 03:00:00
Weather Icon: 04d
Temperature: 283°C
Wind Speed: 3.21 m/s
----------
Time: 2024-02-14 06:00:00
Weather Icon: 04d
Temperature: 283°C
Wind Speed: 2.12 m/s
----------
Time: 2024-02-14 09:00:00
Weather Icon: 04d
Temperature: 281°C
Wind Speed: 1.28 m/s
----------
Time: 2024-02-14 12:00:00
Weather Icon: 04n
Temperature: 280°C
Wind Speed: 1.43 m/s
----------
Time: 2024-02-14 15:00:00
Weather Icon: 04n
Temperature: 280°C
Wind Speed: 1.6 m/s
----------
Time: 2024-02-14 18:00:00
Weather Icon: 04n
Temperature: 280°C
Wind Speed: 0.99 m/s
----------
Time: 2024-02-14 21:00:00
Weather Icon: 04n
Temperature: 279°C
Wind Speed: 2.5 m/s
----------
Time: 2024-02-15 00:00:00
Weather Icon: 10d
Temperature: 279°C
Wind Speed: 4.51 m/s
----------
Time: 2024-02-15 03:00:00
Weather Icon: 10d
Temperature: 278°C
Wind Speed: 6.52 m/s
----------
Time: 2024-02-15 06:00:00
Weather Icon: 10d
Temperature: 278°C
Wind Speed: 5.25 m/s
----------
Time: 2024-02-15 09:00:00
Weather Icon: 04d
Temperature: 277°C
Wind Speed: 5.48 m/s
----------
Time: 2024-02-15 12:00:00
Weather Icon: 04n
Temperature: 276°C
Wind Speed: 5.03 m/s
----------
Time: 2024-02-15 15:00:00
Weather Icon: 01n
Temperature: 274°C
Wind Speed: 3.16 m/s
----------
Time: 2024-02-15 18:00:00
Weather Icon: 01n
Temperature: 274°C
Wind Speed: 1.92 m/s
----------
Time: 2024-02-15 21:00:00
Weather Icon: 02n
Temperature: 274°C
Wind Speed: 1.19 m/s
----------
Time: 2024-02-16 00:00:00
Weather Icon: 02d
Temperature: 274°C
Wind Speed: 0.17 m/s
----------
Time: 2024-02-16 03:00:00
Weather Icon: 01d
Temperature: 277°C
Wind Speed: 2.02 m/s
----------
Time: 2024-02-16 06:00:00
Weather Icon: 01d
Temperature: 277°C
Wind Speed: 3.22 m/s
----------
Time: 2024-02-16 09:00:00
Weather Icon: 01d
Temperature: 276°C
Wind Speed: 2.66 m/s
----------
Time: 2024-02-16 12:00:00
Weather Icon: 01n
Temperature: 275°C
Wind Speed: 1.64 m/s
----------
Time: 2024-02-16 15:00:00
Weather Icon: 01n
Temperature: 275°C
Wind Speed: 1.2 m/s
----------
Time: 2024-02-16 18:00:00
Weather Icon: 01n
Temperature: 274°C
Wind Speed: 1.43 m/s
----------
Time: 2024-02-16 21:00:00
Weather Icon: 01n
Temperature: 274°C
Wind Speed: 1.48 m/s
----------
Time: 2024-02-17 00:00:00
Weather Icon: 03d
Temperature: 274°C
Wind Speed: 1.46 m/s
----------
Time: 2024-02-17 03:00:00
Weather Icon: 01d
Temperature: 278°C
Wind Speed: 2.19 m/s
----------
Time: 2024-02-17 06:00:00
Weather Icon: 01d
Temperature: 279°C
Wind Speed: 2.48 m/s
----------
Time: 2024-02-17 09:00:00
Weather Icon: 01d
Temperature: 278°C
Wind Speed: 1.28 m/s
----------
Time: 2024-02-17 12:00:00
Weather Icon: 01n
Temperature: 278°C
Wind Speed: 0.94 m/s
----------
Time: 2024-02-17 15:00:00
Weather Icon: 01n
Temperature: 277°C
Wind Speed: 1.64 m/s
----------
Time: 2024-02-17 18:00:00
Weather Icon: 02n
Temperature: 277°C
Wind Speed: 1.87 m/s
----------
Time: 2024-02-17 21:00:00
Weather Icon: 01n
Temperature: 277°C
Wind Speed: 2.22 m/s
----------
Time: 2024-02-18 00:00:00
Weather Icon: 01d
Temperature: 278°C
Wind Speed: 2.23 m/s
----------
Time: 2024-02-18 03:00:00
Weather Icon: 01d
Temperature: 282°C
Wind Speed: 3.2 m/s
----------
Time: 2024-02-18 06:00:00
Weather Icon: 02d
Temperature: 285°C
Wind Speed: 3.15 m/s
----------
'Xcode Study' 카테고리의 다른 글
DTO(Data Tranfer Object)란? (0) | 2024.02.15 |
---|---|
5일치 3시간 단위 날씨예보 배열에 넣기(with OpenWeatherMap) (2/2) (0) | 2024.02.15 |
3시간 단위 5일치 OpenWeatherMap API를 활용한 데이터 호출 (1) | 2024.02.13 |
[trouble Shooting]지원하지 않는 5일 단위 OpenWeatherMap API call (0) | 2024.02.12 |
싱글톤 패턴과 델리게이트 패턴 적용에 대한 고찰(with 날씨, 위치 데이터) (0) | 2024.02.09 |