iOS/Swift

[Swift] URLSession์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž

๊ฒฝํ‘ธ 2021. 12. 24. 13:00
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”~

 

์˜ค๋Š˜์€ URLSession์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค : )

 

์• ํ”Œ ๊ฐœ๋ฐœ์ž ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„ ๋งํฌ ๋‚จ๊ฒจ๋“œ๋ฆฝ๋‹ˆ๋‹ค ๐Ÿ˜ƒ

 

Apple Developer Documentation

 

developer.apple.com

 


 

URLSession์ด๋ž€?

URLSession์€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” API์ž…๋‹ˆ๋‹ค.

URLSession์€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋ฉฐ, HTTP, HTTPS ๋ฐ FTP ๋“ฑ์˜ ํ”„๋กœํ† ์ฝœ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

URLSession์€ NSURLSessionConfiguration ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ์…˜์„ ๊ตฌ์„ฑํ•˜๊ณ , ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ URLSessionDataTask, URLSessionDownloadTask ๋ฐ URLSessionUploadTask์™€ ๊ฐ™์€ ์ž‘์—… ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

URLSession์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

1. ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ / ์—…๋กœ๋“œํ•˜๋Š” ๋“ฑ์˜ API๋ฅผ ์ œ๊ณตํ•ด ์ฃผ๋Š” ํด๋ž˜์Šค๋กœ์„œ URL์ด ๊ฐ€๋ฆฌํ‚ค๋Š” End Point๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

2. ๋ฐ์ดํ„ฐ ์ „์†ก, ๋™์ž‘ ๋“ฑ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ์ •์ฑ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์ „์†ก์—์„œ์˜ ๊ธฐ๋ณธ ์ •์ฑ…์€ Shared Session์ด๊ณ  ์ด์™ธ์—๋„ Session Configure๋ฅผ ์ด์šฉํ•ด Default, Ephemeral, Background Session์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ข…ํ•ฉํ•ด์„œ ์„ค๋ช…ํ•˜๋ฉด

URL์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ / ์—…๋กœ๋“œ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” API๋กœ์„œ

๋„ค ๊ฐ€์ง€์˜ Session Configure๋ฅผ ์ด์šฉํ•ด์„œ ์ •์ฑ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

URLSession์˜ ์ข…๋ฅ˜

์ฒซ ๋ฒˆ์งธ, Shared Session

    • ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋‹จ์ˆœํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ๋„คํŠธ์›Œํฌ ์‘๋‹ต์€ Completion Handler๋ฅผ ์ด์šฉํ•ด ์ „๋‹ฌ๋ฐ›์Šต๋‹ˆ๋‹ค.
    • ์žฅ์  : ๊ตฌํ˜„์ด ์‰ฝ์Šต๋‹ˆ๋‹ค.
    • ๋‹จ์  : ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ „์†ก์€ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ „์†ก์ด๋ผ ํ•˜๋ฉด ๋ง ๊ทธ๋Œ€๋กœ ๋‹ค๋ฅธ ์ž‘์—… ์‹œ์—๋„ ์ง€์†์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ / ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑธ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ, Default Session

  • Shared Session๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • Delegate๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

์„ธ ๋ฒˆ์งธ, Ephemeral Session

  • Shared Session๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ์บ์‹œ, ์ฟ ํ‚ค, ์ธ์ฆ ์ •๋ณด์™€ ๊ฐ™์€ ๊ฒƒ์„ ๊ธฐ๋กํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํฌ๋กฌ์˜ ์‹œํฌ๋ฆฟ ๋ชจ๋“œ์™€ ์‚ฌํŒŒ๋ฆฌ์˜ ์‹œํฌ๋ฆฟ ๋ชจ๋“œ๊ฐ€ ์ด์™€ ๋น„์Šทํ•˜๋‹ˆ๋‹ค.

 

๋„ค ๋ฒˆ์งธ, Background Session

  • ์•ž์„œ ๋งํ–ˆ๋˜ Share Session์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” Session์œผ๋กœ ๋‹ค๋ฅธ ์ž‘์—… ์‹œ ํ˜น์€ ํ•ด๋‹น ์•ฑ์ด ์ข…๋ฃŒ๋˜๋”๋ผ๋„ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

URL Session Task์˜ ์ข…๋ฅ˜

์„ธ์…˜ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” Task๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” ๋””์Šคํฌ์˜ ํŒŒ์ผ ํ˜•ํƒœ๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์˜ NSData ๊ฐ์ฒด ํ˜•ํƒœ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฒซ ๋ฒˆ์งธ, Data task

  • NSData ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ณ  ๋ฐ›์Šต๋‹ˆ๋‹ค. Data task๋Š” ์งง๊ณ , ์žฆ์€ ์š”์ฒญ์„ ์„œ๋ฒ„์™€ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.
  • HTTP / GET ์š”์ฒญ์„ ์ฒ˜๋ฆฌ

๋‘ ๋ฒˆ์งธ, Upload task

  • data task์™€ ๋น„์Šทํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•ฑ์ด ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์„ ๋•Œ์—๋„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์—…๋กœ๋“œ๋ฅผ ์ง€์›ํ•˜๋‹ˆ๋‹ค.
  • HTTP / POST ์š”์ฒญ์„ ์ฒ˜๋ฆฌ

์„ธ ๋ฒˆ์งธ, Download task

  • ํŒŒ์ผ์˜ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•ฑ์ด ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์„ ๋•Œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋‹ค์šด๋กœ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • HTTP / GET ์š”์ฒญ์„ ์ฒ˜๋ฆฌ

 

์ƒ์„ฑ๋œ task๋ฅผ resume() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

URLRequest

URLRequest๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

URLRequest๋Š” NSURLRequest ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

URLRequest ๊ฐ์ฒด๋Š” ์š”์ฒญ URL, HTTP ๋ฉ”์„œ๋“œ, ํ—ค๋” ๋“ฑ์˜ ์ •๋ณด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ด ์ •๋ณด๋Š” URLSession ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋งŒ๋“ค ๋•Œ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

 

์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

let url = URL(string: "https://fu.com/data")
var request = URLRequest(url: url!)
request.httpMethod = "GET"

 

์œ„ ์ฝ”๋“œ์—์„œ๋Š” ์š”์ฒญ URL์„ ์ƒ์„ฑํ•˜๊ณ , URLRequest๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ดํ›„ HTTP ๋ฉ”์„œ๋“œ๋ฅผ GET์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์š”์ฒญ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 

URLResponse

URLResponse๋Š” ๋„คํŠธ์›Œํฌ ์‘๋‹ต์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

URLResponse๋Š” NSURLResponse ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

URLResponse ๊ฐ์ฒด๋Š” ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ, ํ—ค๋” ๋“ฑ์˜ ์ •๋ณด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ด ์ •๋ณด๋Š” URLSession ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์‘๋‹ต์„ ๋ฐ›์„ ๋•Œ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

 

์•„๋ž˜๋Š” HTTP GET ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ฐ›์•„ URLResponse ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let httpResponse = response as? HTTPURLResponse,
          (200...299).contains(httpResponse.statusCode) else {
        print("Error: invalid response")
        return
    }
    print("Response status code: \(httpResponse.statusCode)")
}
task.resume()

URLSession ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTTP GET ์š”์ฒญ์„ ๋ณด๋‚ธ ์ดํ›„ ์‘๋‹ต์ด ์˜ค๋ฉด URLResponse ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

 

์•ž์„œ ์„ค๋ช…ํ–ˆ๋˜ shared session๊ณผ dataTask๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์„œ ๊ตฌํ˜„ํ–ˆ๋˜ request๋ฅผ ์‚ฌ์šฉํ•ด ์š”์ฒญํ•  URL, httpMethod๋ฅผ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

URLSessionDataDelegate

์œ„์— ์ž‘์„ฑํ–ˆ๋˜ ์˜ˆ์‹œ์—์„œ Completion Handler ํ˜•ํƒœ๋กœ ์‘๋‹ต์„ ๋ฐ›์€ ๊ฑธ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ URLSessionDataDelegate๋ฅผ ํ†ตํ•ด์„œ๋„ ์‘๋‹ต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

URLSessionDataDelegate๋Š” URLSession ๊ฐ์ฒด์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋ฉฐ

URLSessionDataTask ๋ฐ URLSessionUploadTask์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

 

์ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ, ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•  ๋•Œ, ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ ๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” URLSessionDataDelegate๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

class ViewController: UIViewController, URLSessionDataDelegate {
    
    override func viewDidLoad() {
    	super.viewDidLoad() 
    	
    }
    
    func getData() {
        let url = URL(string: "https://fu.com/data")
        var request = URLRequest(url: url!)
        request.httpMethod = "GET"
        let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
        let task = session.dataTask(with: request)
        task.resume()
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        // ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
        print("๋ฐ›์€ ๋ฐ์ดํ„ฐ: \(data)")
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        // ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
        if let error = error {
            print("Error: \(error.localizedDescription)")
        } else {
            print("์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ใ…ใ„ท์•˜์Šต๋‹ˆ๋‹ค.")
        }
    }
}

 

URLSession ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, delegate ๋งค๊ฐœ๋ณ€์ˆ˜์— self๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ์ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ดํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉด, urlSession(:dataTask:didReceive:) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด, urlSession(:task:didCompleteWithError:) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

 

์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ๋งˆ๋‹ค print๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ UI์— ํ‘œ์‹œํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 


 

URLSession, URLRequest, URLResponse์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด ๋ดค์Šต๋‹ˆ๋‹ค.

์ž˜๋ชป๋œ ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š” : )

 

๊ทธ๋Ÿผ ์ด๋งŒ ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป

๋ฐ˜์‘ํ˜•