To practice URLSession to fetch json data from open weather API

Overview

⛅️ weatherApp-iOS-practice

스크란샷

πŸ“Œ κΈ°λŠ₯ 상세

  • λ„μ‹œ 이름을 μž…λ ₯ν•˜λ©΄ ν˜„μž¬ 날씨 정보λ₯Ό 가져와 화면에 ν‘œμ‹œλ˜κ²Œ λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€

  • λ„μ‹œ 이름을 잘λͺ» μž…λ ₯ν•˜λ©΄ μ„œλ²„λ‘œλΆ€ν„° 응닡받은 μ—λŸ¬ λ©”μ‹œμ§€κ°€ alert으둜 ν‘œμ‹œ λ©λ‹ˆλ‹€

πŸ”‘ Check Point !

image

πŸ”· Current Weather API (OpenWeather API)

json κ³Ό struct ꡬ쑰체(model) mapping ν•˜κΈ°

image

// WeatherInfo.swift

import Foundation

// Codable 은 μžμ‹ μ„ λ³€ν™˜ν•˜κ±°λ‚˜, μ™ΈλΆ€ν‘œν˜„μœΌλ‘œ λ³€ν™˜ ν•  수 μžˆλŠ” (예, .json) νƒ€μž…μ„ μ˜λ―Έν•¨
// Codable 은 decodable(μžμ‹ μ„ 외뢀에 decoding νƒ€μž…), encodable(μžμ‹ μ„ μ™ΈλΆ€μ—μ„œ encoding νƒ€μž…)
// Codable protocol 을 채택 ν–ˆλ‹€λŠ” 것은 Json decoding, encoding 이 λͺ¨λ‘ κ°€λŠ₯ ν•˜λ‹€λŠ” κ²ƒμž„, 즉 Json <-> WeatherInfo 객체
struct WeatherInfo: Codable {
	let weather: [Weather]
	let temp: Temp
	let nameL: 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
}


// λ§Œμ•½ json의 property 이름과 type 의 이름이 λ‹€λ₯Ό 경우 type λ‚΄λΆ€μ—μ„œ codingKeys λΌλŠ” String type 의 μ—΄κ±°ν˜•μ„ μ„ μ–Έν•˜κ³  codingKey protocol 을 μ€€μˆ˜ν•˜κ²Œ λ§Œλ“€μ–΄μ•Ό 함
// main property 의 json μ—μ„œ temp struct 에 mapping μ‹œν‚€κΈ° μœ„ν•΄μ„œ property μ •μ˜ν•¨
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"
	}
}

response ν•œ dataλ₯Ό UI 에 μ—…λ°μ΄νŠΈ

//

// UI창에 weatherInfo κ°€ λ‚˜νƒ€λ‚˜κ²Œ ν•˜λŠ” method
func configureView(weatherInfo: WeatherInfo) {
	self.cityNameLabel.text = weatherInfo.name
	// weatherInfor μ•ˆμ— wather 의 첫번째 μƒμˆ˜μ— λŒ€μž…
	if let weather = weatherInfo.weather.first {
		self.weatherDescriptionLabel.text = weather.description
	}
	self.tempLabel.text = "\(Int(weatherInfo.temp.temp))Β°C"
	self.minTempLabel.text = "μ΅œμ €: \(Int(weatherInfo.temp.minTemp))Β°C"
	self.maxTempLabel.text = "졜고: \(Int(weatherInfo.temp.maxTemp))°C"
}
  • λ„μ‹œμ˜ ν˜„μž¬ 날씨 정보λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€

πŸ”· URLSession

func getCurrentWeather(cityName: String) {
	guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&units=metric&lang=kr&appid=0fb8463dce1de96897cba0b1eff08e18") else { return }
	// session 을 default session 으둜 μ„€μ •
	let session = URLSession(configuration: .default)
	// compression handler 둜써 closure 맀개 λ³€μˆ˜μ— data(μ„œλ²„μ—μ„œ 응닡 받은 data), response(HTTP header λ‚˜ μƒνƒœ μ½”λ“œμ˜ metaData), error(error μ½”λ“œ λ°˜ν™˜)
	session.dataTask(with: url) { [weak self] data, response, error in
......
	}

Describing check point in details in Jacob's DevLog - https://jacobko.info/ios/ios-06/

❌ Error Check Point

πŸ”Ά API Response Error λ°œμƒμ‹œ Error 처리

image

μœ„μ™€ 같이 textField μ—μ„œ λ„μ‹œμ΄λ¦„μ΄ μ˜€νƒ€λ‚˜ 검색이 λ˜μ§€ μ•ŠμœΌλ©΄, 404 error κ°€ λ°œμƒν•©λ‹ˆλ‹€. κ·ΈλŸ΄λ•Œ alert 창으둜 λ„μ‹œμ΄λ¦„μ΄ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ λΌλŠ” λ‚˜μ˜€κ²Œ ν•˜λŠ” code λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€

  • Error message 처리λ₯Ό μœ„ν•œ struct λͺ¨λΈ 생성
// in ViewController.swift

// Error message κ°€ alert 에 ν‘œμ‹œλ˜κ²Œ ν•˜λŠ” logic
func showAlert(message: String) {
	let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
	alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
	self.present(alert, animated: true, completion: nil)
}

// URLSession 을 μ΄μš©ν•΄μ„œ currentWeather APIλ₯Ό ν˜ΈμΆœν•˜κΈ°
func getCurrentWeather(cityName: String) {
	guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&units=metric&lang=kr&appid=0fb8463dce1de96897cba0b1eff08e18") else { return }
	// session 을 default session 으둜 μ„€μ •
	let session = URLSession(configuration: .default)
	// compression handler 둜써 closure 맀개 λ³€μˆ˜μ— data(μ„œλ²„μ—μ„œ 응닡 받은 data), response(HTTP header λ‚˜ μƒνƒœ μ½”λ“œμ˜ metaData), error(error μ½”λ“œ λ°˜ν™˜)
	session.dataTask(with: url) { [weak self] data, response, error in
		// 응닡받은 response (json data)λ₯Ό weatherInfo struct 에 decoding 되게 ν•˜λŠ” logic
		let successRange = (200..<300)
		guard let data = data, error == nil else { return }
		let decorder = JSONDecoder()
		// 응닡받은 data 의 statusCode κ°€ 200λ²ˆλŒ€ (200 ~ 299) μΌλ•Œ
		if let response = response as? HTTPURLResponse, successRange.contains(response.statusCode) {
			guard let weatherInfo =  try? decorder.decode(WeatherInfo.self, from: data) else { return }
			// debugPrint(weatherInfo)
			// λ°›μ•„μ˜¨ 데이터λ₯Ό UI 에 ν‘œμ‹œν•˜κΈ° μœ„ν•΄μ„œλŠ” main thread μ—μ„œ μž‘μ—…μ„ 진행 햐여 됩
			DispatchQueue.main.async {
				self?.weatherStackView.isHidden = false
				self?.configureView(weatherInfo: weatherInfo)
				}
			} else { // status code κ°€ 200 λ²ˆλŒ€κ°€ μ•„λ‹ˆλ©΄ error μƒνƒœ μ΄λ‹ˆκΉŒ error message 생성 logic
				guard let errorMessage = try? decorder.decode(ErrorMessage.self, from: data) else { return }
				// debugPrint(errorMessage)
				// main thread μ—μ„œ alert 이 ν‘œμ‹œλ˜κ²Œ 해야됨
				DispatchQueue.main.async {
					self?.showAlert(message: errorMessage.message)
				}
		}
	}.resume() // app 이 μ‹€ν–‰λ˜κ²Œ 함
	}

Kapture 2021-12-18 at 14 33 20


πŸ”Ά πŸ”· πŸ“Œ πŸ”‘ πŸ‘‰

πŸ—ƒ Reference

Jacob's DevLog - https://jacobko.info/ios/ios-08/

아직은 어렡지 - https://greatpapa.tistory.com/66

fastcampus - https://fastcampus.co.kr/dev_online_iosappfinal

You might also like...
Lightweight REST and JSON library for Swift.

RestEssentials is an extremely lightweight REST and JSON library for Swift and can be used on iOS, iPadOS, macOS, tvOS, and watchOS. Features Easily p

Swish is a networking library that is particularly meant for requesting and decoding JSON via Decodable
Swish is a networking library that is particularly meant for requesting and decoding JSON via Decodable

Swish Nothing but net(working). Swish is a networking library that is particularly meant for requesting and decoding JSON via Decodable. It is protoco

Lazily deserialize JSON into strongly typed Swift objects

LazyObject Lazily deserialize JSON into strongly typed Swift objects, with a few getter style options. Is your app using it? Let me know! Installation

Enable WebSocket in OPC DA/AE Server with JSON return, first time ever
Enable WebSocket in OPC DA/AE Server with JSON return, first time ever

WebSocket4OPC Enable WebSocket in OPC DA/AE Server with JSON return, first time ever DCOM was developed more than 2 decades ago, wich was the pillar o

APIProvider - API Provider Package for easier API management inspired by abstraction

APIProvider Using APIProvider you can easily communicate with all API endpoints

An open-source Swift framework for building event-driven, zero-config Multipeer Connectivity apps

PeerKit An open-source Swift framework for building event-driven, zero-config Multipeer Connectivity apps Usage // Automatically detect and attach to

SwiftCANLib is a library used to process Controller Area Network (CAN) frames utilizing the Linux kernel open source library SOCKETCAN.

SwiftCANLib SwiftCANLib is a library used to process Controller Area Network (CAN) frames utilizing the Linux kernel open source library SOCKETCAN. Th

SkyWite is an open-source and highly versatile multi-purpose frameworks.

SkyWite is an open-source and highly versatile multi-purpose frameworks. Clean code and sleek features make SkyWite an ideal choice. Powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use.

Metatext A free, open-source iOS Mastodon client.

Metatext A free, open-source iOS Mastodon client. Contributing Bug Reports GitHub is used for bug tracking. Please search existing issues and create a

Owner
Jacob Ko
Everything is Awesome
Jacob Ko
Another network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application.

Another network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application. Install Carthage

Ronan Rodrigo Nunes 89 Dec 26, 2022
A reactive library for using URLSession

Reactive wrapper for URLSession using Combine. At its core, the library consist of the NetworkServiceClient protocol along with a minimal implementation NetworkService.

MFB Technologies, Inc. 2 Nov 20, 2022
Write clean, concise and declarative network code relying on URLSession, with the power of RxSwift. Inspired by Retrofit.

ReactiveAPI Reactive API library allows you to write clean, concise and declarative network code, with the power of RxSwift and URLSession! iOS Demo A

Sky UK Ltd 79 Nov 19, 2022
GeminiProtocol - URLSession support for the Gemini Protocol

GeminiProtocol Network.Framework and URLSession support for the Gemini Protocol

Izzy 3 Feb 16, 2022
πŸ€΅πŸ½β€β™€οΈ Janet β€” A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

????‍♀️ Janet β€” Just another networking kit β€” A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveragi

Niklas Holloh 3 Sep 6, 2022
A library for Search & Parse the weather data from Wunderground & Openweathermap conveniently.

SmileWeather A library for Search & Parse the weather data from Wunderground & Openweathermap conveniently. #What can it do for you? 1. Handle all com

Rain 482 Sep 28, 2022
An Alamofire extension which converts JSON response data into swift objects using EVReflection

AlamofireJsonToObjects ?? This is now a subspec of EVReflection and the code is maintained there. ?? You can install it as a subspec like this: use_fr

Edwin Vermeer 161 Sep 29, 2022
Open source SDK to quickly integrate subscriptions, stop worring about code maintenance, and getting advanced real-time data. Javascript / iOS glue framework

Open source SDK to quickly integrate subscriptions, stop worring about code maintenance, and getting advanced real-time data. Javascript / iOS glue framework

glassfy 5 Nov 7, 2022
Swift/Obj-C HTTP framework with a focus on REST and JSON

Now Archived and Forked PMHTTP will not be maintained in this repository going forward. Please use, create issues on, and make PRs to the fork of PHMT

Postmates Inc. 509 Sep 4, 2022
A barebones Swift HTTP client with automatic JSON response parsing.

HTTP Client A barebones Swift HTTP client with automatic JSON response parsing. Installation Add HTTP Client as a dependency through Xcode or directly

Joe Masilotti 30 Oct 11, 2022