URLSession์ Swift์์ ์๋ฒ์ ์ํตํ๊ธฐ ์ํด ์ ๊ณต๋๋ ํด๋์ค.
URLSession์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ๋ค์ด๋ก๋, ์ ๋ก๋, API ์์ฒญ ๋ฑ์ ์ฝ๊ฒ ์ํํ ์ ์๋ค.
URLSession์ ๋คํธ์ํฌ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ ์๋ต์ ๋ฐ์์ค๋ ๊ณผ์ ์ ๊ด๋ฆฌํ๋ค.
์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Alamorfire์ moya๋ ์๋ค.
: ๋คํธ์ํฌ ์์ฒญ์ ์ํํ๋ ์ฃผ์ ๊ฐ์ฒด
: ์ธ์ ์ ๊ตฌ์ฑํ๋ ํ๊ฒฝ ์ค์ ์ ์๋ฏธํ๋ ์์ฑ
- .default
๊ธฐ๋ณธ ํต์ ์ผ๋ก ๋์คํฌ๋ฅผ ์ด์ฉํ ์ ๋ณด ์ ์ฅ์ ํ๋ configuration
๊ทธ๋ฅ ๋ธ๋ผ์ฐ์ ๋์ธ๋
let defaultSession = URLSession(configuration: .defualt)
- .ephemeral
default ๋ ๋น์ทํ์ง๋ง, ์ฟ ํค๋ ์ธ์ฆ์, ์บ์ ๋ฑ์ ์ ์ฅํ์ง ์์ ๋ ์ฌ์ฉ
ex) ๋ธ๋ผ์ฐ์ ์ํฌ๋ฆฟ ๋ชจ๋, Safari์ ๊ฐ์ธ ์ ๋ณด๋ณดํธ ๋ชจ๋
let ephemeralSession = URLSession(configuration: .ephemeral)
- .background
๋คํธ์ํฌ๋ฅผ ํตํด ํ์ผ ๋ค์ด๋ก๋ ๋ฐ์๋
ex) ์ฑ์ด ๋ฐฑ๊ทธ๋ผ์ด๋์ ์์ ๋, ๋ค์ด๋ก๋/์ ๋ก๋ํ ๋ ์ฌ์ฉ
let backgroundSession = URLSession(configuration: .background)
: ๋ฐ์ดํฐ ์ ์ก ์์
- URLSessionDataTask
์๋ฒ์์ ๋ฉ๋ชจ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ๋ณด๋ผ ๋ ์ฌ์ฉ.
์๋ฒ์ ์งค๊ณ , ์์ฃผ ์์ฒญ๋๋ ์์ ์ ๋ํด ์ฌ์ฉ๋๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋์์๋ ์ง์โ
- URLSessionDownloadTask
๋ฐ์ดํฐ๋ฅผ ํ์ผ์ ํํ๋ก ์ฝ๊ณ ๋์ฉ๋ ํ์ผ์ ๋ค์ด๋ก๋ํ ๋ ์ฌ์ฉ.
๋ค์ด๋ฐ์ ํ์ผ์ ์์ ๋๋ ํ ๋ฆฌ์ ์ ์ฅํด๋๊ณ ๋ค์ด๋ก๋์ ์ฑ๊ณตํ๋ค๋ฉด ๋๋ ํ ๋ฆฌ์ ์ฃผ์๋ฅผ completion handler์ ๋ฐํํ๋ค.
์ด๋ ์์ ํ์ผ์ completionHandler๊ฐ ์ข ๋ฃ๋๊ธฐ ์ ๋ค๋ฅธ ๋๋ ํ ๋ฆฌ์ ์ฎ๊ฒจ์ค์ผ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๊ฐ ์๋๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ง์
- URLSessionUploadTask
๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ์ ๋ก๋ํ ๋ ์ฌ์ฉ.
๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ง์
- URLSessionWebSocketTask
TCP๋ TLS๋ฅผ ํตํด ๋ฉ์์ง๋ฅผ ์ฃผ์ ๋ฐ์ ๋ ์ฌ์ฉ
๊ธฐ๋ณธ ์ค์ , ์์ ์ค์ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค์ ๋ฑ ๋ค์ํ ๊ตฌ์ฑ์ ์ฌ์ฉํ ์ ์๋ค.
let defaultSession = URLSession(configuration: .default)
URLSessionConfigration ๊ฐ์ฒด๊ฐ ์ธ์ ์ ํ๋ฒ ์ค์ ๋ ์ดํ ์์ ์ ๋ฌด์๊ฐ ๋๊ธฐ ๋๋ฌธ์,
์๋ก์ด URLSession ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
๋ํ, URLSession์ ์ฑ ์ ์ญ์์ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ shared๋ผ๋ ์ด๋ฆ์ผ๋ก ์ฑ๊ธํค ์ธ์ ๋ ๊ฐ๋ฅํ๋ค.
์ด ์ธ์ ์ ์ค์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์, configuration์ ๋ฐ๊พธ๊ธฐ ์ํด์๋ ์ถ๊ฐ ์ค์ ์ด ํ์ํ๋ค.
์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ธ์ ์ ๋ฐ๋ก ์์ฑํ ํ์๊ฐ ์๋ค.
์ค์ ์ ์ฌ์ฉํ์ฌ URLSession ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ค.
์์ฒญํ URL๊ณผ ๊ธฐํ ์์ฒญ ์ ๋ณด๋ฅผ ํฌํจํ๋ URLRequest ๊ฐ์ฒด๋ฅผ ์์ฑ
var request = URLRequest(url: URL(string: "https://example.com")!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer token", forHTTPHeaderField: "Authorization")
let jsonData = try? JSONSerialization.data(withJSONObject: ["key": "value"], options: [])
request.httpBody = jsonData
request.cachePolicy = .reloadIgnoringLocalCacheData
request.timeoutInterval = 30.0 // 30์ด๋ก ์ค์
request.networkServiceType = .video
๋ฐ์ดํฐ ์์ฒญ์ ๋น๋๊ธฐ๋ก ์ํํ๊ธฐ ์ํด URLSessionDataTask๋ฅผ ์์ฑํ๊ณ ์คํํ๋ค.
URL ์์ฑ๊ณผ ํ์ํ ์ ๋ณด๋ฅผ ์ด์ ์์ฒญํ๋ ๋ถ๋ถ์ด๋ค.
URLSession์์ URL์ ์์ฒญ ํ dataTask์์ ์๋ต์ด ์ค๋ฉด ์ฝ๋ ์ํ
์๋ต์ completion(closure)์ delegate ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
์ธ์ ๋ด์์ ์งํ๋๋ Task๋ค์ ๊ณตํต๋ Delegate ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ๊ณ ์๋ค.
์ด Delegate๋ฅผ ๊ตฌํํ๋ฉด ํต์ ๊ณผ์ ์์ ๋ฐ์ํ๋ ๊ถํ ์ธ์ฆ ์คํจ, ์๋ฒ๋ก๋ถํฐ์ ๋ฐ์ดํฐ ๋์ฐฉ, ๋ฐ์ดํฐ ์บ์ฑ ๋ฑ
๋ค์ํ ์ด๋ฒคํธ์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐ์ ์ ์๋ค.
Delegate๊ฐ ํ์ํ์ง ์๋ค๋ฉด, Session์ ์์ฑํ ๋ ์ธ์๋ก nil์ ์ ๋ฌํ๋ค.
// URLSession ์์ฑ, delegate ์ธ์๋ก nil์ ์ ๋ฌ
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
์ธ์ ๊ฐ์ฒด๋ Delegate๋ฅผ ์ฑ์ด ์ข ๋ฃ๋๊ฑฐ๋ ์ธ์ ์ด ๋๋ ๋๊น์ง ๊ฐํ๊ฒ ์ฐธ์กฐํ๋ค.
๋ฉ๋ชจ๋ฆฌ ๋ฆญ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋์ด์ ์ฌ์ฉํ์ง ์๋ ์ธ์ ์ invalidateAndCancel() ๋ฉ์๋๋ฅผ ํธ์ถํด ๋ฌดํจํํ๋ค.
// ์ธ์
๋ฌดํจํ ๋ฐ ์ทจ์
session.invalidateAndCancel()
๊ฐ๋จํ GET ์์ฒญ์ ๋ณด๋ด๊ณ JSON ์๋ต์ ์ฒ๋ฆฌํ๋ ์์
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
// ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฉ์๋ ์ ์ธ
private func fetchData() {
let defaultUrlSession = URLSession(configuration: .default)
guard let url: URL = URL(string: "https://reqres.in/api/users/1") else {
print("URL is not correct")
return //ํจ์์ ์คํ์ ์ฆ์ ์ข
๋ฃํ๊ณ ํจ์๊ฐ Void๋ฅผ ๋ฐํ
}
// URLRequest ์ธ์คํด์ค ์ค์
var request: URLRequest = URLRequest(url: url)
// ์์ฒญ์ ์ฌ์ฉํ HTTP๋ฉ์๋ ์ค์ - GET ๋ฉ์๋ ์ฌ์ฉ
request.httpMethod = "GET"
// HTTP ํค๋ ์ค์ - json ๋ฐ์ดํฐ ํ์์์ ๋ํ๋
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// URLSession ์์ฑ (๊ธฐ๋ณธ default ์ธ์
)
let session: URLSession = URLSession(configuration: .default)
// dataTask - URLSession์ ์ฌ์ฉํด ์์ฒญ ์ํ
session.dataTask(with: request) { (data, response, error) in
// http ํต์ response ์๋ status code ๊ฐ ํจ๊ป์ค๋๋ฐ, 200๋ฒ๋๊ฐ ์ฑ๊ณต์ ์๋ฏธ.
let successRange: Range = (200..<300)
// ํต์ ์ฑ๊ณต
guard let data, error == nil else { return }
if let response: HTTPURLResponse = response as? HTTPURLResponse{
print("status code: \(response.statusCode)")
// ์์ฒญ ์ฑ๊ณต (StatusCode๊ฐ 200๋ฒ๋)
if successRange.contains(response.statusCode){
// decode
guard let userInfo: ResponseData = try? JSONDecoder().decode(ResponseData.self, from: data) else { return }
print(userInfo)
} else { // ์์ฒญ ์คํจ (Status code๊ฐ 200๋ ์๋)
print("์์ฒญ ์คํจ")
}
}
}.resume() //์์
์์
}
}
// ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด ์ ์
struct UserData: Codable {
let id: Int
let email: String
let firstName: String
let lastName: String
let avatar: URL
// JSON ํค์ ๊ตฌ์กฐ์ฒด ํ๋กํผํฐ ๊ฐ์ ๋งคํ์ ์ํด CodingKeys ์ด๊ฑฐํ ์ ์
enum CodingKeys: String, CodingKey {
case id
case email
case firstName = "first_name"
case lastName = "last_name"
case avatar
}
}
// Support ๊ตฌ์กฐ์ฒด ์ ์
struct SupportData: Codable {
let url: URL
let text: String
}
// ์ต์์ ๊ตฌ์กฐ์ฒด ์ ์
struct ResponseData: Codable {
let data: UserData
let support: SupportData
}
Codable ํ๋กํ ์ฝ์ ์ค์ํ๋ ๊ตฌ์กฐ์ฒด์์ CodingKeys๋ฅผ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ์
JSON ๋ฐ์ดํฐ์ ํค์ Swift ๊ตฌ์กฐ์ฒด์ ํ๋กํผํฐ๋ช ์ด ๋ค๋ฅผ ๋, ์ด๋ฅผ ๋งคํํด์ค ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํ๋ค.
์ฃผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ํ์ฉ๋๋ค.
- URLSession.shared
: ์ ํ๋ฆฌ์ผ์ด์
๋ด์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋๋ URLSession ์ธ์คํด์ค.
์ฑ ์ ์ฒด์์ ๊ณต์ ๋๋ฉฐ, ๊ธฐ๋ณธ ๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ ๋คํธ์ํฌ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ์์ ์ฌ์ฉํ ์ ์๊ณ , ์ถ๊ฐ์ ์ธ ์ธ๋ถ ์ค์ ์ด ํ์ํ์ง ์์ ๋ ์ฌ์ฉ.
- URLSession(configuration: .default)
: ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ตฌ์ฑ์ ์ค์ ํ์ฌ ์์ฑํ๋ URLSession ์ธ์คํด์ค.
๊ธฐ๋ณธ ๊ตฌ์ฑ๊ณผ๋ ๋ค๋ฅธ ํ์์์, ์บ์ ์ ์ฑ ๋ฑ์ ์ต์ ์ ์ถ๊ฐ๋ก ์ค์ ํ ์ ์๋ค.
ํน์ ์๊ตฌ์ฌํญ์ ๋ง์ถฐ ํน์ ํ์์์์ด๋ ์บ์ ์ ์ฑ ์ค์ ๊ณผ ๊ฐ์ ์ธ๋ถ์ ์ธ ์ปค์คํฐ๋ง์ด์ง์ด ํ์ํ ๋ ์ฌ์ฉ.
๋คํธ์ํฌ ์์ฒญ ์ ํน์ ํ HTTP ํค๋๋ฅผ ์ค์ ํ๋ฉด ์๋ฒ์์ ํต์ ์ ๋์ฑ ์ ๊ตํ๊ฒ ์ ์ดํ ์ ์๋ค.
์ด๋ค ๋ฉ์๋๋ค์ ์ ์ ํ ํ์ฉํ์ฌ URLRequest ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ๋ฉด, ์ํ๋ ํํ์ HTTP ์์ฒญ์ ๋ณด๋ด๊ณ
ํ์ํ ํค๋๋ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ ์ ์๋ค.
๐ Reference
https://jeonyeohun.tistory.com/357
https://jazz-the-it.tistory.com/19