URLSession
์๋ 3๊ฐ์ง๋ฅผ ์ ๊ธฐ์ตํด๋ณด์
- URLSession
- URLSessionDataTask
- Response, CompletionHandler
URLSessionDataTask
- ์์ฒญ์ ํ๋ ํ๋ํ๋(Task)
- ์ผ๋ฐ ํต์ , ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ค์ด๋ก๋, ์ํฌ๋ฆฟ ๋ชจ๋ ๋ฑ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ค์ํ Task๋ก ์ข ๋ฅ๊ฐ ๋๋๋ค.
URLSessionDelegate
- + å๋ก ๋ฌด์ธ๊ฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
- ์ค๊ฐ ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ง๋ ๋ฐ์์๋์ง ํ์ธํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
- ex. ์นด์นด์คํก ์ฌ์ง 10์ฅ ํ ๋ฒ์ ์ ์ฅ (๋ค์ด๋ก๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ํ ์ฅ์ฉ ๋ค์ด๋ก๋ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.)
- ์ผ๋ฐ ํต์ ์์๋ ์๋๊ฐ ๊ต์ฅํ ๋น ๋ฅธ ํธ์ด๊ธฐ ๋๋ฌธ์ Delegate๊น์ง ์ฌ์ฉํ ํ์๊ฐ ์๋ค.
URLSession ์ฌ์ฉํ๊ธฐ
Session
์ ํ์ด ์ ๊ณตํ๋ ๊ธฐ๋ณธ์ ์ธ ํํ ์ฌ์ฉ, ์ผ๋ฐ์ ์ธ ์์ฒญ โก๏ธ shared(Singleton Session) ์ฌ์ฉ
์ข ๋ ์ปค์คํฐ๋ง์ด์ฆํ๊ฒ ์ฌ์ฉ โก๏ธ ์์ฑ์ ์ฌ์ฉ
(1) shared
- ๊ธฐ๋ณธ ์ธ์
- ๋จ์, ์ปค์คํ ๋ถ๊ฐ, ์๋ต์ ํด๋ก์ ํํ๋ก ์ ๋ฌ, ๋ฐฑ๊ทธ๋ผ์ด๋ ํํ๋ ์ฒ๋ฆฌ ๋ถ๊ฐ
(2) init(configuration: _)
- default : shared์ ์ ์ฌ, ์ปค์คํ ์ด ๊ฐ๋ฅํ๊ณ , ์๋ต์ ํด๋ก์ ๋๋ Delegate ํํ๋ก ํ ์ ์์
- ephemeral : ์ ๋ณด๋ฅผ ํ๋ฐ์ํค๊ณ ์ ํ ๋ ์ฌ์ฉ
- background : ์ฌ์ฉ์๊ฐ ์ฑ์ ์ฐ๊ณ ์์ง ์์ ๋ ์ด๋ค ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ (ex. ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฌ์)
DataTask
- resume ๋ฉ์๋๋ฅผ ๋ฐ๋์ ์์ฑํด์ฃผ์ด์ผ ์คํ๋๋ค.
- ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ๋์ํ๊ฒ ๋๋ค. ๊ทธ๋์ UI ๊ด๋ จ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ธฐ ์ํด์๋ ๋ฉ์ธ ์ค๋ ๋๋ก ์ ํํด์ฃผ์ด์ผ ํ๋ค.
- ์์ ๊ตฌํ๋ถ์์ ๋ฉ์ธ ์ค๋ ๋๋ก ๋ฐ๊ฟ์ฃผ๋ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ธฐ๋ ํ๋ค.
let url = URL(string: "")!
URLSession.shared.dataTask(with: url) { data, response, error in
// ์์ ๊ตฌํ๋ถ์์ ๋ฉ์ธ ์ค๋ ๋๋ก ๋ฐ๊ฟ์ฃผ๋ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ธฐ๋ ํ๋ค.
DispatchQueue.main.async {
guard error == nil else {
completion(nil, .failedRequest)
return
}
guard let data = data else {
completion(nil, .noData)
return
}
// HTTPURLResponse๋ก ํ์
์บ์คํ
// URLResponse > HTTPURLResponse๋ ์์ ๊ด๊ณ
guard let response = response as? HTTPURLResponse else {
completion(nil, .invaildResponse)
return
}
guard response.statusCode == 200 else {
completion(nil, .failedRequest)
return
}
do {
let result = try JSONDecoder().decode(Lotto.self, from: data)
completion(result, nil)
} catch {
completion(nil, .invaildData)
}
}
}.resume()
Completion์ ์ธ์๋ก๋ Data์ Error๋ฅผ ๋๊ฒจ์ฃผ๊ฒ ๋๋ค. ๋คํธ์ํฌ ์์ฒญ์ด ์ฑ๊ณตํ ์๋ ์๊ณ ์คํจํ ์๋ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ ์ต์ ๋ ํ์ ์ด ๋๊ณ nil๊ฐ์ ์ ๋ฌํ๊ฒ ๋๋ค. ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ํ๋ฉด์ nil๊ฐ์ ๋๊ฒจ์ฃผ๋ ์์ ์ด ์๋นํ ๊ท์ฐฎ๊ธฐ ๋๋ฌธ์ Result๋ผ๋ ํ์ ์ด ๋ฑ์ฅํ๊ฒ ๋์๋๋ฐ ์ด ๋ํ ๊ทผ๋ณธ์ ์ธ ํด๊ฒฐ์ฑ ์ด ๋์ง ๋ชปํด์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ข ๋ ์ฝ๊ฒ ํ ์ ์๊ณ , ๊ทธ ํ๋ฆ์ด ์์ฐ์ค๋ฌ์ด async, await API๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
์ฌ์ฉ ํ๋ฆ
์ง์ ๋คํธ์ํฌ ํต์ ์ฝ๋๋ฅผ viewDidLoad๋ controller ๋จ์์ ์์ฑํด์ ์ฌ์ฉํ ์ ์๊ฒ ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ๋คํธ์ํฌ ์ฝ๋๋ฅผ ๋ฉ์๋๋ก ๊ฐ์ธ๋๊ธฐ ๋๋ฌธ์ ๊ตฌํ๋ถ์ ํธ์ถ๋ถ๋ฅผ ๋ถ๋ฆฌํด์ ๋ณด๋๋ก ํ๊ฒ ๋ค.
๋คํธ์ํฌ ๋งค๋์ ์ฝ๋ (๊ตฌํ๋ถ)
final class PersonAPIManager {
static func requestPerson(query: String, completion: @escaping ((Person?, APIError?) -> Void)) {
let url = URL(string: "https://api.themoviedb.org/3/search/person?api_key=APIKEY&language=en-US&query=\(query)&page=1&include_adult=false®ion=ko-KR")!
URLSession.shared.dataTask(with: component.url!) { data, response, error in
DispatchQueue.main.async {
guard error == nil else {
completion(nil, .failedRequest)
return
}
guard let data = data else {
completion(nil, .noData)
return
}
guard let response = response as? HTTPURLResponse else {
completion(nil, .invaildResponse)
return
}
guard response.statusCode == 200 else {
completion(nil, .failedRequest)
return
}
do {
let result = try JSONDecoder().decode(Person.self, from: data)
completion(result, nil)
} catch {
completion(nil, .invaildData)
}
}
}.resume()
}
}
ํธ์ถ๋ถ
Controller์์ ํธ์ถ
PersonAPIManager.requestPerson(query: "Squid") { person, error in
guard let person = person else { return }
self.list = person
self.tableView.reloadData()
}
์ ๋ฆฌ
'๐ iOS & Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift/Algorithm] dictionary default value ์ฌ์ฉํ๊ธฐ (3) | 2022.09.08 |
---|---|
[iOS] UIToolbar LayoutConstraint Issue (4) | 2022.09.03 |
[iOS+Network] Swift๋ฅผ ๊ณ๋ค์ธ URL ๊ตฌ์กฐ ๋ถ์ (2) | 2022.08.30 |
[iOS] Realm ์ข ๋ ๋๋ํ๊ฒ ์ฌ์ฉํ๊ธฐ(with Singleton class) (0) | 2022.08.25 |
[iOS] ์ ์ (dash-line) ๊ทธ๋ฆฌ๊ธฐ (3) | 2022.08.24 |