티스토리 뷰
[SwiftUI] 날씨 어플 만들기 01 (OpenWeather API 사용하는 법 + CodingKey, URLSession)
말차프라푸치노 2021. 9. 2. 16:02날씨 어플 만들기 바로 시작하겠습니다 😄
날씨 어플을 만들려면 날씨 정보가 필요합니다!
전세계적으로 많이 쓰는 Open API 인 OpenWeatehr API를 사용해 날씨 정보를 받아 오겠습니다.
Сurrent weather and forecast - OpenWeatherMap
Access current weather data for any location on Earth including over 200,000 cities! The data is frequently updated based on the global and local weather models, satellites, radars and a vast network of weather stations. how to obtain APIs (subscriptions w
openweathermap.org
OpenWeatherMap 사이트에 들어가 우선은 회원가입을 해줍니다.
회원가입이 완료되었다면 메뉴바 상단에 API를 눌러 들어갑니다.
제가 만들 앱은 현재 날씨를 알려주는 앱이기 때문에 현재 날씨를 알려주는 Current Weater Data의 Subscribe 를 눌러줍니다.
Free 에서 Get API Key 를 눌러 API Key를 받습니다
우측 상단에 자신의 ID를 누르고 My API Keys 누릅니다
Key 이름을 정해주면 Generate 버튼 을 눌러주면 좌측에 Key가 생성됩니다
Key 이름은 자신이 정해주면 되는거라 아무거나 정해주면 됩니다. 저는 그냥 Default라고 지었습니다.
이제 키를 받았으니 어떻게 키를 사용하면 될지 설명서를 읽어보겠습니다
다시 상단의 API 메뉴를 눌러줍니다
그리고 아까 선택했던 Current Weather Data의 API doc 버튼을 눌러줍니다.
그러면 API call 하는 방법이 나옵니다.
도시와 APIKey 값은 필수이고 나머지는 선택입니다.
제가 사는 곳은 서울이기 때문에 도시는 Seoul 로 설정하고 ApiKey를 넣어주면 아래 주소와 같습니다.
https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=각자의APIKey
위 주소로 요청을 보내면
{
"coord": {
"lon": -122.08,
"lat": 37.39
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 282.55,
"feels_like": 281.86,
"temp_min": 280.37,
"temp_max": 284.26,
"pressure": 1023,
"humidity": 100
},
"visibility": 16093,
"wind": {
"speed": 1.5,
"deg": 350
},
"clouds": {
"all": 1
},
"dt": 1560350645,
"sys": {
"type": 1,
"id": 5122,
"message": 0.0139,
"country": "US",
"sunrise": 1560343627,
"sunset": 1560396563
},
"timezone": -25200,
"id": 420006353,
"name": "Mountain View",
"cod": 200
}
다음과 같이 응답이 옵니다. 현재 온도가 282도???? 엥??
여기서 주의할 점이 저 주소로 요청을 하면 현재온도를 절대온도값(Kelvin) 으로 보내줍니다!
우리나라는 섭씨온도를 쓰기 때문에 받아온 온도에서 273을 빼야합니다.
매번 273을 빼면 귀찮을 거 같은데..
273을 뺄 때 개발자가 실수해서 272 나 274로 입력할 수 도 있습니다. 개발자가 실수할 수 있는 여지를 최대한 줄여야합니다.
섭씨온도로 받는 법
units 이라는 Parameters를 하나 더 추가 해주겠습니다
units 이라는 Parameters에 metric(미터법) 으로 보내주면 Celsius(섭씨) 온도를 보내준다고 합니다.
아래 주소로 요청을 하면 섭씨 온도로 보내줍니다
https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=각자의APIKey&units=metric
+
한글도 지원해줍니다. description이 한글로 옵니다.
https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=각자의APIKey&units=metric&lang=kr
제가 만들 앱에는 따로 description이 없으므로 그냥 영어로 받아 사용하겠습니다.
PlayGround로 데이터 받아오기
이제 Swift를 통해 실제 데이터를 받아오겠습니다.
xCode 에서 프로젝트를 하나 만듭니다.
그리고 Blank Playground 파일을 하나 만듭니다. Targets은 따로 연결하지 않습니다
Playground파일은 말 그대로 놀이터입니다. Swift 코드를 작성해서 놀 수 있는(?) 공간입니다 ㅎㅎ
SwiftUI에서 바로 파일을 만들고 데이터를 받아와 View로 보여줄 수 있지만 저같은 초보에게는 쉽지 않습니다.
그래서 Playground에서 코드가 잘 돌아가는지 확인하고 옮겨주겠습니다.
import Foundation
struct APIResponse: Decodable{
let name: String
let main: APIMain
let weather: [APIWeather]
}
struct APIMain: Decodable {
let temp: Double
let temp_min: Double
let temp_max: Double
}
struct APIWeather: Decodable {
let description: String
let icon: String
enum CodingKeys: String, CodingKey {
case description
case icon = "main"
}
}
func getData() {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=각자의APIKey&units=metric") else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
guard error == nil, let data = data else {return}
if let result = try? JSONDecoder().decode(APIResponse.self, from: data) {
print(result)
}
}.resume()
}
getData()
우선은 결과부터 확인하고 싶으면 위에 코드에서 appid에 자신의 APIKey만 잘 입력하고 getData 옆에 실행버튼을 눌러주면 됩니다.
그러면 아래와 같이 결과를 확인할 수 있습니다.
코드 살펴보기
이제 코드를 한 줄 한 줄 씩 살펴보겠습니다.
우선은 데이터를 받아올 Struct를 선언해주었습니다.
API 응답을 보면 가장 바깥 코드블럭 { } 을 기준으로 제가 사용할 데이터만 보면 아래와 같습니다.
{
도시이름
weather:{
description
icon
}
main :{
기온
최고
최저
}
}
이렇게 생겼습니다. 이걸 기준으로 구조체를 선언하면
struct APIResponse: Decodable{
let name: String
let main: APIMain
let weather: [APIWeather]
}
struct APIMain: Decodable {
let temp: Double
let temp_min: Double
let temp_max: Double
}
struct APIWeather: Decodable {
let description: String
let icon: String
enum CodingKeys: String, CodingKey {
case description
case icon = "main"
}
}
그림으로 보면 다음과 같습니다.
한 눈에 이해가 되시나요??
CodingKey
다른 거는 몇 번 접해볼 수 있었어도 CodingKeys는 처음 볼 수 있습니다.
CodingKeys는 Codable의 프로토콜 중 하나로써 내가 설정한 이름과 받아오는 데이터의 이름이 일치하지 않을 때 사용합니다.
다시 API가 보내주는 데이터를 보면
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
위와 같이 보내줍니다.
icon에서 보내주는 코드를 보고 날씨 아이콘을 만들 수 있습니다
But, 저는 가독성이 좋게 main에서 알려주는 날씨를 보고 그에 알맞게 아이콘을 설정해주려고 합니다.
(Ex. clear -> 해 아이콘, cloud -> 구름 아이콘 . 만약 icon 코드를 그대로 사용하면 01d -> 해 아이콘 이렇게 설정해주어야 한다)
따라서 제가 선언한 APIWeather 의 icon 에 API에서 보내주는 weather의 main 이 들어가게 됩니다.
description은 description 그대로 받아오므로 case description으로 선언해주면 됩니다. 사용하지 않을 건데 예시를 위해 넣었습니다.
URLSession
이제 데이터를 받아올 함수를 선언해 주겠습니다
func getData() {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=APIKey&units=metric") else { return }
URLSession.shared.dataTask(with: url) { data, response, error in
guard error == nil, let data = data else {return}
if let result = try? JSONDecoder().decode(APIResponse.self, from: data) {
print(result)
}
}.resume()
}
우선은 API 주소를 위한 url을 선언해줍니다.
URLSession 이라는 class 통해 서버에 데이터를 요청할 것입니다.
data 는 서버에 요청했을 때 보내주는 data 입니다.
Response는 data가 무슨 type인지 등을 알려줍니다
error는 error입니다
error 가 없으면 data에 받아온 data를 넣어주고 아니면( error 가 있으면) return 을 통해 함수를 종료시킵니다.
그리고 받아온 data를 JSONDecoder를 통해 받아온 data (JSON 형식) 을 APIResponse에 맞게 decode해주고 result에 넣어줍니다.
URLSession { } 코드 블럭 뒤에 .resume()을 붙여줘 실행시켜줘야합니다
Data가 APIResponse 형식에 맞게 출력되는 것을 확인할 수 있습니다.
이렇게 OpenWeaterhMap API를 이용해서 Swift로 날씨 데이터를 받아왔습니다.
너무 쉬우셨나요?? 🤣
저는 처음에 할 때 어려워서 헤맸는데 계속 찾아보고 타이핑해보니 이제 조금 익숙해지려고 합니다.
이제 다음시간에는 위에서 만든 함수를 실제 앱에 적용할수 있게 수정해보겠습니다.
그 전에 글에서 만든 playground파일은 지워줘야 에러가 나지 않습니다
playground 파일 지우세요!!
글 읽어주셔서 감사합니다. 피드백은 항상 환영합니다 ☺️
'SwiftUI > SwiftUI 앱 만들기' 카테고리의 다른 글
[SwiftUI] 날씨 어플 만들기 03 (Model 만들기, @escaping) (0) | 2021.09.02 |
---|---|
[SwiftUI] 날씨 어플 만들기 02 (View 구성하기, SF Symbol3 사용하기) (0) | 2021.09.02 |
[SwiftUI] 날씨 어플 만들기 00 (개요, MVVM 패턴으로 만들기) (0) | 2021.09.02 |
[SwiftUI] 기본적인 Todo 앱 만들기 05 완성(onDelete, remove 로 삭제기능 구현) (0) | 2021.08.28 |
[SwiftUI] 기본적인 Todo 앱 만들기 04 (UserDefault로 Local Database에 데이터 저장) (0) | 2021.08.28 |
- Total
- Today
- Yesterday
- todo앱
- UX
- 부스트캠프iOS
- Swift
- 프로그래머스
- 부스트캠프7기
- TODO
- ios
- 날씨어플
- 필독서
- swiftUI 기초
- 책
- Combine
- 코딩
- 코딩 테스트
- SwiftUI
- Swift 서버
- Swift문법
- 책후기
- 코딩테스트
- 개발
- 책리뷰
- 디자인 패턴
- 부스트캠프
- Swift공식문서
- vapor
- Swift 디자인 패턴
- 애플
- Swift DocC
- 앱개발
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |