-
μλλ³ μ κ· νμ§μ μκ° νμ΄ μ°¨νΈλ‘ νμ λμ΄μΌ ν©λλ€
-
λμ νλͺ©μ μ ννλ©΄ μμΈ νν©μ λ³Ό μ μλ νλ©΄μΌλ‘ μ΄λλμ΄μΌ ν©λλ€.
// in CityCovidOverView.swift
import Foundation
struct CityCovidOverView: Codable {
let korea: CovidOverview
let seoul: CovidOverview
let busan: CovidOverview
let daegu: CovidOverview
let incheon: CovidOverview
let gwangju: CovidOverview
let daejeon: CovidOverview
let ulsan: CovidOverview
let sejong: CovidOverview
let gyeonggi: CovidOverview
let gangwon: CovidOverview
let chungbuk: CovidOverview
let chungnam: CovidOverview
let jeonbuk: CovidOverview
let jeonnam: CovidOverview
let gyeongbuk: CovidOverview
let gyeongnam: CovidOverview
let jeju: CovidOverview
}
struct CovidOverview: Codable {
let countryName: String
let newCase: String
let totalCase: String
let recovered: String
let death: String
let percentage: String
let newCcase: String
let newFcase: String
}
// in CovidTime.swift
import Foundation
struct CovidTime: Codable {
let updateTime: String
}
Corona-19-API - https://github.com/dhlife09/Corona-19-API
- Alamofire λ Swift κΈ°λ°μ HTTP λ€νΈμνΉ λΌμ΄λΈλ¬λ¦¬ μ λλ€. URLSession μ κΈ°λ°μΌλ‘ ν λΌμ΄λΈλ¬λ¦¬λ‘μ, λ€νΈμνΉ μμ μ λ¨μν νκ³ λ€νΈμνΉμ μν λ€μν method, json parsing λ±μ μ 곡 ν©λλ€.
- μ°κ²° κ°λ₯ν request, response method λ₯Ό μ 곡νλ©°, URL json parameter encoding μ μ§μ ν©λλ€. νμΌ λ°μ΄ν° μ€νΈλ¦¬λ°, multi part form date λ± upload κΈ°λ₯μ μ 곡νλ©°, HTTP response κ²μ¦κ³Ό κ΄λ²μν Unit Test, ν΅ν© Test λ±μ μ§μν©λλ€
-
func μμ escape μ μΈμ ν¨μμ scope λ₯Ό λ²μ΄ λμλ λ³μκ° μ°Έμ‘° λ μ μκ² νλ ν΄λ‘μ Έ μ. μ¦, ν¨μμ μΈμλ‘ closure κ° μ λ¬λμ§λ§, λ°νλ νμλ μ€νλλ κ²μ μλ―Έν©λλ€.
-
escaping closure λ₯Ό μ¬μ©νλ λνμ μΈ κ²½μ°λ λΉλκΈ° μμ μ νλ κ²½μ° completionHandler λ‘μ escaping closure λ₯Ό λ§μ΄ μ¬μ©ν©λλ€. λ³΄ν΅ λ€νΈμνΉ ν΅μ μ λΉλκΈ° μμ μΌλ‘ μ²λ¦¬ λλλ°,
.responseData
μ μ μλcompletionHandler closure
λ fetch data κ° λ°ν λ νμ, νΈμΆμ΄ λ©λλ€. μλνλ©΄, μλ²μμ λ°μ΄ν°λ₯Ό μΈμ μλ΅ ν΄μ€μ§ λͺ¨λ₯΄κ³ , μλ΅μκ°μ΄ λ‘λ© λκΈ° λλ¬Έμ server μμ λΉλκΈ°λ‘ μλ΅ λ°κΈ° μ μ μ¦, .responseData μ μ λ¬ν parameter κ° completionHandlerκ° νΈμΆλκΈ° μ μ ν¨μκ° μ’ λ£λμ μλ²μ μλ΅μ λ°μλ λμνμ§ μκ² λ©λλ€ -
κ·Έλμ, λΉλκΈ° μμ μ completionHandler λ‘ callback μ μμΌμ€μΌ νλ€λ©΄, escaping closure λ₯Ό μ¬μ©νμ¬ ν¨μκ° return λ νμλ, μ€ν μμΌμ€μΌ ν©λλ€
// in viewDidLoad.swift
// fetch data SearchCovideOverview
func fetchCovidOverview(
// API λ₯Ό ν΅ν΄μ severμμ json dat λ₯Ό λ°κ±°λ, μμ²μ μ€ν¨ νμμλ completionHandler λ₯Ό νΈμΆν΄μ ν΄λΉ closure λ₯Ό μ μνλ κ³³μ μλ΅λ°μ dataλ₯Ό μ λ¬ ν΄μΌ ν©λλ€
// completionHandler λ₯Ό @escaping closure κ° λκ² μ€μ
completionHandler: @escaping (Result<CityCovidOverView, Error>) -> Void
) {
let url = "https://api.corona-19.kr/korea/country/new/"
let param = [
"serviceKey": "16KIXAdhg7tk93ivjzsHFCQ8oOLyNSUuE"
]
// Alamofire λ₯Ό ν΅ν΄μ API νΈμΆ
AF.request(url, method: .get, parameters: param)
.responseData(completionHandler: { response in
switch response.result {
case let .success(data):
do {
let decoder = JSONDecoder()
let result = try decoder.decode(CityCovidOverView.self, from: data)
completionHandler(.success(result))
} catch { // error code μ²λ¦¬
completionHandler(.failure(error))
}
case let .failure(error):
completionHandler(.failure(error))
}
})
}
-
Apple platform μμ κ°λ°μ ν λ, μΈλΆ λΌμ΄λΈλ₯Ό κ΄λ¦¬νκΈ° μ½λλ‘ λμμ£Όλ μμ‘΄μ± κ΄λ¦¬λꡬ μ λλ€
-
νλ‘μ νΈμμ νμν μΈλΆ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ½κ² κ΄λ¦¬νκ³ , μ¬μ©ν μ μμ΅λλ€.
Cocoapods official site - https://cocoapods.org/
$ sudo gem install cocoapods
- xcode λ‘ μλ‘μ΄ project λ₯Ό μμ±νλ©΄ κ·Έ κ²½λ‘μ terminal λ‘ κ°μ Podfile μμ±
pod init
- Podfile μ μμ νκ² λλ©΄ μΈλΆ λΌμ΄λΈλ¬λ¦¬λ₯Ό κ°μ Έμ€κ±°λ, μμ ν μ μμ΅λλ€.
-
ViewController μ loading indicator λ₯Ό νμνμ¬, Covid API λ₯Ό νΈμΆ νμμ λ, μλ²μμ μλ΅μ΄ μ€κΈ° μ μ΄λΌλ©΄ νλ©΄μ indicator κ° νμλκ² κ΅¬ννκΈ°
-
μλ²μμ μλ΅μ΄ μ¨λ€λ©΄, indicator λ₯Ό μ¨κΈ°κ³ label κ³Ό pieChart κ° νμλκ² κ΅¬ν νκΈ°
- storyboard μμ Activity Indicator μΆκ° νλ€μμ κΈ°μ‘΄μ StackViewμ label, pieChartView μλ hidden μ μ²΄ν¬ ν΄μ€μ μ μ μ¨κΉλλ€
// in ViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
// app μ΄ μ€νλλ©΄ indicator μ animation μμ
self.indicatorView.startAnimating()
// μνμ°Έμ‘°λ₯Ό λ°©μ§νκΈ° μν΄μ [weak self] λ‘ capture list λ₯Ό μ μν΄μ€
self.fetchCovidOverview(completionHandler: { [weak self] result in
guard let self = self else { return } // self κ° μΌμμ μΌλ‘ strong μ΄ λκ² ν¨
// μλ΅μ΄ μ€λ©΄ completionHandler κ° μλλκΈ° λλ¬Έμ μ΄λ indicatorView μ animating μ stop μμΌ μ£Όκ³ , hidden μμΌ μ£Όκ³ , λλ¨Έμ§ information data λΆλΆμ΄ λνλκ² ν΄μ€
self.indicatorView.stopAnimating()
self.indicatorView.isHidden = true
self.labelStackView.isHidden = false
self.readingDate.isHidden = false
self.pieChartView.isHidden = false
......
}
}
- GitHub λ μΈλΆλ‘ public νκ² project 곡μ μ, apiKey λ, passWord, authentication κ΄λ ¨ key κ°λ€μ μΈλΆμ λ ΈμΆ μν€μ§ μκΈ° μν΄μ code μ key κ°μ λ°λ‘ μ λκ²μ΄ μλλΌ, plist (property list) λ₯Ό μμ±ν΄μ€μ λ°λ‘ κ΄λ¦¬ ν΄μΌ ν©λλ€
- Key κ°μΌλ‘
API_KEY
value κ°μΌλ‘ API key κ°μ λ£μ΅λλ€
// in CovidApp++Bundle.swift
// "μ±μ΄λ¦++Bundle.swift νμμΌλ‘
import Foundation
// Bundle κ°μΌλ‘ λ³μ key λ₯Ό return
extension Bundle {
var apiKey: String {
guard let file = self.path(forResource: "CovidKey", ofType: "plist") else { return ""}
guard let resource = NSDictionary(contentsOfFile: file) else {return ""}
guard let key = resource["API_KEY"] as? String else { fatalError("Check API Key value")}
return key
}
}
π Bundle μ extension ν΄μ μμ±νλ μ΄μ ?
-
Bundle μ΄λ μ€νκ°λ₯ν μ½λμ κ·Έ μ½λμ μμμ ν¬ν¨νκ³ μλ λλ ν 리 μ λλ€.
-
Bundle μμ apiKey κ°μ κ°μ Έμ€κΈ° μν΄
Bundle.main.apiKey
μμΌλ‘ μ κ·Όν΄μ μ¬μ©ν©λλ€
// in viewController.swift
// fetch data SearchCovideOverview
func fetchCovidOverview(
// API λ₯Ό ν΅ν΄μ severμμ json dat λ₯Ό λ°κ±°λ, μμ²μ μ€ν¨ νμμλ completionHandler λ₯Ό νΈμΆν΄μ ν΄λΉ closure λ₯Ό μ μνλ κ³³μ μλ΅λ°μ dataλ₯Ό μ λ¬ ν΄μΌ ν©λλ€
// completionHandler λ₯Ό @escaping closure κ° λκ² μ€μ
completionHandler: @escaping (Result<CityCovidOverView, Error>) -> Void
) {
let apiKey = Bundle.main.apiKey
let url = "https://api.corona-19.kr/korea/country/new/"
let param = [
"serviceKey": apiKey
]
....
# Created by https://www.toptal.com/developers/gitignore/api/xcode,cocoapods
# Edit at https://www.toptal.com/developers/gitignore?templates=xcode,cocoapods
### CocoaPods ###
## CocoaPods GitIgnore Template
# CocoaPods - Only use to conserve bandwidth / Save time on Pushing
# - Also handy if you have a large number of dependant pods
# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
Pods/
### Xcode ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
##APIKEY
CovidKey.plist
## User settings
xcuserdata
.....
- μΆν git clone project μ€νμ local νκ²½μμ APIKEY κ°μ΄ λ³κ²½λλλΌλ git μμ μλ μΆμ λμ§ μκ³ gitHub λ±μ μ λ‘λ λμ§ μκ² νκΈ°μ λλ€
# git update-index --skip-worktree νλ‘μ νΈλͺ
/νμΌλͺ
.plist
git update-index --skip-worktree 07_covid_app/covidKey.plist
- λ€μ μμ 볡κ·λ
--no-skip
ν΄μ£Όλ©΄ λ©λλ€
git update-index --no-skip-worktree 07_covid_app/covidKey.plist
Describing check point in details in Jacob's DevLog - https://jacobko.info/ios/ios-08/
πΆ π· π π π
Jacob's DevLog - https://jacobko.info/uikit/ios-08/
λλ₯Έν μ½λ© - https://nareunhagae.tistory.com/44
codewithchrist - https://codewithchris.com/alamofire/
fastcampus - https://fastcampus.co.kr/dev_online_iosappfinal