VesselWheel

[trouble Shooting]지원하지 않는 5일 단위 OpenWeatherMap API call 본문

Xcode Study

[trouble Shooting]지원하지 않는 5일 단위 OpenWeatherMap API call

JasonYang 2024. 2. 12. 23:48

결론부터 말하자면, 별도의 API를 불러와야 한다. 

https://vesselwheel.tistory.com/187

 

 


현재 문제점

https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}

상기의 API call 주소의 구성요소를 변경하여 5일 단위 혹은 3시간 단위로 데이터를 배열에 넣어보고자 했다. 

더보기

이 API 호출 URL은 OpenWeatherMap의 날씨 정보를 얻기 위한 것입니다. 각 구성 요소는 다음과 같습니다:

1. "https://api.openweathermap.org/data/2.5/weather": 이 부분은 OpenWeatherMap API의 기본 URL입니다. 이 URL을 통해 OpenWeatherMap의 날씨 데이터에 접근할 수 있습니다.

2. "?lat={lat}&lon={lon}": 이 부분은 위도와 경도를 지정하는 쿼리 매개변수입니다. {lat}에는 위도 값을, {lon}에는 경도 값을 입력합니다. 이렇게 설정하면 해당 위치의 날씨 정보를 얻을 수 있습니다.

3. "&appid={API key}": 이 부분은 OpenWeatherMap API의 인증 키를 지정하는 매개변수입니다. {API key}에는 사용자의 API 키를 입력합니다. 이 키는 OpenWeatherMap에서 발급받는 것이며, API를 사용하기 위해 필요합니다.

따라서 이 URL을 사용하려면 {lat}, {lon}, {API key} 부분을 실제 값으로 대체해야 합니다. 이렇게 하면 특정 위치의 날씨 정보를 얻을 수 있습니다.

프로토콜, 도메인은 동일하고 쿼리 매개변수를 매소드의 파라미터로 받아, 해당 위도와 경도의 날씨데이터를 요청했다.

3시간 단위나 5일치 일기예보를 받기 위해 도메인의 세부 주소를 변경하면 될 것이라 생각했다. 

우선 3시간 단위와 5일치 단위 예보 데이터를 저장할 배열을 초기화한 뒤, 

//    // 3시간 단위 예보 데이터를 저장할 배열
//    var threeHourForecastData: [WeatherData] = []
//    
//    // 5일치 일간 예보 데이터를 저장할 배열
//    var fiveDayForecastData: [WeatherData] = []

OpenWeatherMap API call에서 도메인 부분을 우선, 5일치 데이터로만 데이터를 호출하기 위해서 /forcast/daily?를 추가하면 일일 단위 기준으로 데이터가 호출될 것이라 판단했지만, API test를 해보니 error401 으로 에러가 난다.

https://api.openweathermap.org/data/2.5/forecast/daily?lat=\(currentLocation.latitude)&lon=\(currentLocation.longitude)&appid=\(apiKey)"

https://openweathermap.org/faq#error401

 

Frequently Asked Questions - OpenWeatherMap

We provide data for any coordinates by utilising our proprietary OpenWeather Weather model. OpenWeather’s advanced ML-based numerical weather model performs at up to 500 m resolution and allows its users to consider highly local nuances of climate and bu

openweathermap.org

 


잘못된 API로 호출된 getFiveDayForecast 매소드와 코드

    "https://api.openweathermap.org/data/2.5/forecast/daily?lat=37.565534&lon=126.977895&appid=3a33f61058f414d02d09e88bfa83117c")
     {"cod":401, "message": "Invalid API key. Please see https://openweathermap.org/faq#error401 for more info."} url 실행되지 않음
     데일리로 실행하는 API call이 없음
    public func getFiveDayForecast(latitude: Double, longitude: Double, completion: @escaping(Result<WeatherData, NetworkError>) -> Void) {
        LocationManager.shared.setLocation(latitude: latitude, longitude: longitude)
        guard let currentLocation = LocationManager.shared.currentLocation else {
            return completion(.failure(.badLocation))
        }
        let url = URL(string: "https://api.openweathermap.org/data/2.5/forecast/daily?lat=\(currentLocation.latitude)&lon=\(currentLocation.longitude)&appid=\(apiKey)")
        performRequest(with: url) { result in
            switch result {
            case .success(let data):
                self.fiveDayForecastData.append(data)
                completion(.success(data))
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }

 

        LocationManager.shared.onLocationUpdate = { [weak self] location in
            WeatherManager.shared.getFiveDayForecast(latitude: location.latitude, longitude: location.longitude) { result in
                switch result {
                case .success(let weatherResponse) :
                    DispatchQueue.main.async {
                        self?.weather = weatherResponse.weather.first
                        self?.main = weatherResponse.main
                        self?.updateWeather()
                    }
                case .failure(let error ):
                    print("Error: \(error)")
                }
            }
        }
        // LocationManager Test
        let testLocation = CLLocationCoordinate2D(latitude: 37.565534, longitude: 126.977895)
        LocationManager.shared.setLocation(latitude: testLocation.latitude, longitude: testLocation.longitude)

        LocationManager.shared.onLocationUpdate = { location in
            print("Updated location: \(location)")
            assert(location.latitude == testLocation.latitude && location.longitude == testLocation.longitude)
        }