샘성의 iOS 개발 일지

OpenWeather API로 도시별 날씨 불러오기 본문

iOS/Swift

OpenWeather API로 도시별 날씨 불러오기

SamusesApple 2023. 3. 24. 14:36
728x90

* 목표 : OpenWeatherMap으로 현재 기온, 날씨 불러오기

 

 

 

Current weather data - OpenWeatherMap

Access current weather data for any location on Earth including over 200,000 cities! We collect and process weather data from different sources such as global and local weather models, satellites, radars and a vast network of weather stations. Data is avai

openweathermap.org

 

API 요청서 작성 방식

 

<1. 데이터 요청서 만들기>

 

 

1. 서버 요청 api 주소 - (필수) : https://api.openweathermap.org/data/2.5/weather?

2. 개인 키값 - (필수) : OpenWeather 회원가입 -> My API Keys 에서 확인 가능

                                                              (키 발급 받은 후, 바로는 이용 불가능하고 몇시간 후에 사용 가능하다던데.. 난 하루동안 안됨..)

3. 위도, 경도 (latitude, longtitude) - (필수) :

                                          https://openweathermap.org/api/geocoding-api 에서 요청해서 확인 가능

                                         

     - 참고: 위도 경도 대신에 도시 이름을 넣어서 해당 도시의 날씨를 얻어오기도 가능!

                 lat, lon 넣지말고 q=Seoul 처럼 q=원하는도시이름 넣으면 됨

 

4. 언어 - (선택) : lang=kr     

                        기본 언어는 영어로 제공됨. 한국어로 받고 싶으면 kr 쓰면 가능

 

                              *요청 파라미터 사이에 &로 파라미터 구분짓기 필수*

 

 

 

** 최종 api요청서 : https://api.openweathermap.org/data/2.5/weather?q=Seoul&units=metric&appid=개인키값

    >>  서울의 날씨를 metric(미터법 - 우리가 사용하는 셀시어스 형태로 온도 받으려면 metric으로 해야함) 형태로 알려줘 <<

 

 

 

<2. 요청보내기>

상단의 최종 api요청서를 브라우저에 넣어서 엔터 친다. (검색할 때처럼)

그럼 창이 뜬다 (402 error~~ 가 안 뜨면 됨!)

 

 

 

 

<3. 요청에 대한 JSON 응답 편식(Parsing)할 깔떼기 만들기>

 

요청보내면, JSON형태의 응답이 온다.

JSON 형태의 응답

이 많은 정보 중, 내가 필요한 '현재 기온, 날씨' 정보만 골라야 한다

 

 

 

weather의 .description과  main의 .temp만 받아오면 될 것 같다!

 

 

 

 

 

 

 

이제 JSON 응답 전체를 ctrl-C 해서

하단 사이트에 ctrl-V 한다. ( = 복붙한다)

 

Instantly parse JSON in any language | quicktype

 

app.quicktype.io

 

 

 

 

JSON -> Swift

복붙하면, JSON형태의 데이터가 Swift 형태로 바뀐 것을 볼 수 있다.

(오른쪽 상단의 Language - Swift로 설정 필수)

 

 

이제 Swift 형태로 바뀐 데이터를 X-Code에 복붙한다.

 

 

정리하기 전

뭐가 많으니.... 필요한 데이터만 받을 수 있도록 정리한다.

(필요한 것 : weather의 .description과  main의 .temp)

 

 

 

 

정리 후

필요한 것만 남기고 정리하니 깔-끔해졌다!

 

깔떼기 만들기 끝.

 

 

 

 

 

<4. 실제 요청 넣기>

요청 넣으면 콘솔창에 잘 받아온 것을 확인 할 수 있다. (코드는 밑에 첨부했습니다)

 

 

요청 과정 설명 :

    1. String 형태의 요청서(url)을 구조체 형태로 바꾸기

    2. URLSession.shared.dataTask에 구조체 형태로 바뀐 요청서(structURL) 넣어서 서버에 데이터 요청하기

    3. error != nil 인지 확인하기 (=에러 유무 확인)

    4. 데이터 if let 바인딩 되는지 확인하기 (= 데이터 유무 확인)

    5. 데이터 읽을 수 있게 문자열 형태로 바꿔서 출력하기

    6. .resume() 로 1~5 과정을 실행시키기

 

 

 

let url = "https://api.openweathermap.org/data/2.5/weather?q=도시명&appid=개인키&lang=kr"

// 상위의 url을 구조체 형태로 바꾸기 
let structURL = URL(string: url)!

// 구조체 형태의 url로 서버에 데이터 요청하기
URLSession.shared.dataTask(with: structURL) { data, response, error in
    if error != nil {
        print(error!)
        return
    }
    
    if let data = data {
        print(String(decoding: data, as: UTF8.self))
    } else {
        print("data error")
    }
}.resume()

 

 

 

 

 

 

<5. 실제 요청 넣기 + Parsing>

 

요청에서 온 응답을 받아서 만들어놓은 깔떼기대로 Parsing(편식)해보자!

 

1. 파싱하는 함수 만들기 

func parseJSON(_ data: Data) -> SeoulWeather? {
    do {
        let decoder = JSONDecoder()

        let decodedData = try decoder.decode(SeoulWeather.self, from: data)
        return decodedData
    }
    catch {
        print("error")
        return nil
    }
}

 

2. URLSession으로 서버에 데이터 요청할 때, 에러 없고 데이터 if let 바인딩 되면 파싱하기

파싱 성공! (근데 파라미터에 units=metric 빠트려서 temp 이상한 형태로 나옴..)

 

 

 

let url = "https://api.openweathermap.org/data/2.5/weather?q=도시명&appid=개인키&lang=kr"

// 상위의 url을 구조체 형태로 바꾸기 
let structURL = URL(string: url)!

// 구조체 형태의 url로 서버에 데이터 요청하기
URLSession.shared.dataTask(with: structURL) { data, response, error in
    if error != nil {
        print(error!)
        return
    }
    // 데이터 바인딩 잘 되면, 
    if let data = data {
    	// parseJSON() 에 바인딩 된 data 넣어서 파싱하기
        dump(parseJSON(data)!)     // 데이터 받은거 출력하기 위해 dump() 안에 넣음 (선택)
    } else {
        print("data error")
    }
}.resume()

 

 

 

그래서 다시 쿼리파라미터 추가하고 파싱하면,

셀씨어스 형태로 잘 나온다!

units=metric 잊지말자...!

 

 

 

 

728x90