์ƒ์„ธ ์ปจํ…์ธ 

๋ณธ๋ฌธ ์ œ๋ชฉ

[ Swift ] ๋„คํŠธ์›Œํฌ ํ†ต์‹  - URLSession

๐ŸŽ iOS/Network

by AHN.Jihyeon 2024. 7. 15. 09:26

๋ณธ๋ฌธ

URLSession์€ Swift์—์„œ ์„œ๋ฒ„์™€ ์†Œํ†ตํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ณต๋˜๋Š” ํด๋ž˜์Šค.

URLSession์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋‹ค์šด๋กœ๋“œ, ์—…๋กœ๋“œ, API ์š”์ฒญ ๋“ฑ์„ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

URLSession์€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๋Š” ๊ณผ์ •์„ ๊ด€๋ฆฌํ•œ๋‹ค.

 

์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Alamorfire์™€ moya๋„ ์žˆ๋‹ค.  

 

 


โœ… URLSession์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

 

๐ŸŒŸ 1. URLSession

: ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฃผ์š” ๊ฐ์ฒด

 

 

 

๐ŸŒŸ 2. URLSessionConfiguration

: ์„ธ์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ํ™˜๊ฒฝ ์„ค์ •์„ ์˜๋ฏธํ•˜๋Š” ์†์„ฑ

 

- .default

๊ธฐ๋ณธ ํ†ต์‹ ์œผ๋กœ ๋””์Šคํฌ๋ฅผ ์ด์šฉํ•œ ์ •๋ณด ์ €์žฅ์„ ํ•˜๋Š” configuration

๊ทธ๋ƒฅ ๋ธŒ๋ผ์šฐ์ € ๋„์šธ๋•Œ

let defaultSession = URLSession(configuration: .defualt)

 

 

- .ephemeral

default ๋ž‘ ๋น„์Šทํ•˜์ง€๋งŒ, ์ฟ ํ‚ค๋‚˜ ์ธ์ฆ์„œ, ์บ์‹œ ๋“ฑ์„ ์ €์žฅํ•˜์ง€ ์•Š์„ ๋•Œ ์‚ฌ์šฉ

ex) ๋ธŒ๋ผ์šฐ์ € ์‹œํฌ๋ฆฟ ๋ชจ๋“œ, Safari์˜ ๊ฐœ์ธ ์ •๋ณด๋ณดํ˜ธ ๋ชจ๋“œ 

let ephemeralSession = URLSession(configuration: .ephemeral)

 

 

- .background

๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„๋•Œ

ex) ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ์žˆ์„ ๋•Œ, ๋‹ค์šด๋กœ๋“œ/์—…๋กœ๋“œํ•  ๋•Œ ์‚ฌ์šฉ

let backgroundSession = URLSession(configuration: .background)

 

 

 

๐ŸŒŸ 3. URLSessionTask

: ๋ฐ์ดํ„ฐ ์ „์†ก ์ž‘์—…

 

- URLSessionDataTask

์„œ๋ฒ„์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉ.

์„œ๋ฒ„์— ์งค๊ณ , ์ž์ฃผ ์š”์ฒญ๋˜๋Š” ์ž‘์—…์— ๋Œ€ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. 

๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ๋Š” ์ง€์›โŒ

 

- URLSessionDownloadTask

๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์ผ์˜ ํ˜•ํƒœ๋กœ ์ฝ๊ณ  ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•  ๋•Œ ์‚ฌ์šฉ.

๋‹ค์šด๋ฐ›์€ ํŒŒ์ผ์„ ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅํ•ด๋‘๊ณ  ๋‹ค์šด๋กœ๋“œ์— ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด ๋””๋ ‰ํ† ๋ฆฌ์˜ ์ฃผ์†Œ๋ฅผ completion handler์— ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

์ด๋•Œ ์ž„์‹œ ํŒŒ์ผ์„ completionHandler๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „ ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ์— ์˜ฎ๊ฒจ์ค˜์•ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๊ฐ€ ์•ˆ๋œ๋‹ค. 

๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ง€์›

 

- URLSessionUploadTask

๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ์—…๋กœ๋“œํ•  ๋•Œ ์‚ฌ์šฉ.

๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ง€์›

 

- URLSessionWebSocketTask

TCP๋‚˜ TLS๋ฅผ ํ†ตํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ์†Œ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ

 

 

 

โœ… URLSession์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. URLSessionConfiguration ์„ค์ •

๊ธฐ๋ณธ ์„ค์ •, ์ž„์‹œ ์„ค์ •, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์„ค์ • ๋“ฑ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

let defaultSession = URLSession(configuration: .default)

 

URLSessionConfigration ๊ฐ์ฒด๊ฐ€ ์„ธ์…˜์— ํ•œ๋ฒˆ ์„ค์ • ๋œ ์ดํ›„ ์ˆ˜์ •์€ ๋ฌด์‹œ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์—,

์ƒˆ๋กœ์šด URLSession ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

 

๋˜ํ•œ, URLSession์€ ์•ฑ ์ „์—ญ์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— shared๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์‹ฑ๊ธ€ํ†ค  ์„ธ์…˜๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. 

์ด ์„ธ์…˜์€ ์„ค์ • ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์•„, configuration์„ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค. 

์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์„ธ์…˜์„ ๋”ฐ๋กœ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.  

 

 

 

 

2. URLSession ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ URLSession ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 

 

3. URLRequest ๊ฐ์ฒด ์ƒ์„ฑ 

์š”์ฒญํ•  URL๊ณผ ๊ธฐํƒ€ ์š”์ฒญ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” URLRequest ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ 

  • URL
    ์š”์ฒญ์„ ๋ณด๋‚ผ ๋Œ€์ƒ์˜ URL๋กœ, URL ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์„ค์ •๋œ๋‹ค.
var request = URLRequest(url: URL(string: "https://example.com")!)
  • HTTP Method
    ์š”์ฒญ์˜ ์œ ํ˜•์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์„œ๋“œ๋กœ๋Š” GET, POST, PUT, DELETE ๋“ฑ์ด ์žˆ๋‹ค.
request.httpMethod = "GET"
  • HTTP Headers
    ์š”์ฒญ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ‚ค-๊ฐ’ ์Œ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Content-Type, Authorization, User-Agent ๋“ฑ์ด ์žˆ๋‹ค.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer token", forHTTPHeaderField: "Authorization")
  • HTTP Body
    ์ฃผ๋กœ POST๋‚˜ PUT ์š”์ฒญ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์„œ๋ฒ„๋กœ ์ „์†กํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. Data ๊ฐ์ฒด๋กœ ์„ค์ •๋œ๋‹ค.
let jsonData = try? JSONSerialization.data(withJSONObject: ["key": "value"], options: [])
request.httpBody = jsonData
  • Cache Policy
    ์บ์‹œ๋œ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.
    ๊ธฐ๋ณธ๊ฐ’์€ .useProtocolCachePolicy์ด๋ฉฐ,
    ๋‹ค๋ฅธ ์˜ต์…˜์œผ๋กœ๋Š” .reloadIgnoringLocalCacheData, .returnCacheDataElseLoad, .returnCacheDataDontLoad ๋“ฑ์ด ์žˆ๋‹ค.
request.cachePolicy = .reloadIgnoringLocalCacheData
  • Timeout Interval
    ์š”์ฒญ์ด ์‹œ๊ฐ„ ์ดˆ๊ณผ๋กœ ์‹คํŒจํ•˜๊ธฐ ์ „๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ฐ„์„ ์ง€์ •ํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 60์ดˆ.
request.timeoutInterval = 30.0  // 30์ดˆ๋กœ ์„ค์ •
  • Network Service Type
    ์š”์ฒญ์ด ์‚ฌ์šฉํ•˜๋Š” ๋„คํŠธ์›Œํฌ ์„œ๋น„์Šค ์œ ํ˜•์„ ์ง€์ •ํ•œ๋‹ค.
    ๊ธฐ๋ณธ๊ฐ’์€ .default์ด๋ฉฐ, ๋‹ค๋ฅธ ์˜ต์…˜์œผ๋กœ๋Š” .background, .video, .voice, .responsiveData ๋“ฑ์ด ์žˆ๋‹ค.
request.networkServiceType = .video

 

 

 

4. URLSessionDataTask ์ƒ์„ฑ ๋ฐ ์‹คํ–‰

๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ๋น„๋™๊ธฐ๋กœ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด 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()

 

 

 


โœ… URLSession์„ ์‚ฌ์šฉํ•œ ์˜ˆ์ œ

๊ฐ„๋‹จํ•œ 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๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ?

Codable ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ตฌ์กฐ์ฒด์—์„œ CodingKeys๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ๋œ ์ด์ ์€

JSON ๋ฐ์ดํ„ฐ์˜ ํ‚ค์™€ Swift ๊ตฌ์กฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ช…์ด ๋‹ค๋ฅผ ๋•Œ, ์ด๋ฅผ ๋งคํ•‘ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค.

์ฃผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ํ™œ์šฉ๋œ๋‹ค. 

 

  • ํ”„๋กœํผํ‹ฐ ๋ช…๋ช… ๊ทœ์น™์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ
    : JSON ๋ฐ์ดํ„ฐ์˜ ํ‚ค๊ฐ€ snake_case ํ˜•์‹์ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋ช…๋ช… ๊ทœ์น™์„ ๋”ฐ๋ฅด๋Š” ๊ฒฝ์šฐ,
    Swift์˜ camelCase ๋ช…๋ช… ๊ทœ์น™์— ๋งž์ถ”๊ธฐ ์œ„ํ•ด CodingKeys๋ฅผ ์‚ฌ์šฉ.
  • ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋งŒ ๋””์ฝ”๋”ฉ/์ธ์ฝ”๋”ฉ
    : JSON์—๋Š” ํ•„์š”ํ•œ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋งŒ ์žˆ์„ ๊ฒฝ์šฐ, CodingKeys๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ฒ˜๋ฆฌ.
  • ๊ธฐ๋ณธ๊ฐ’ ์ฒ˜๋ฆฌ
    : JSON์— ํŠน์ • ํ‚ค๊ฐ€ ์—†์„ ๋•Œ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก CodingKeys ์„ค์ •.

 

 

 

๐ŸŒŸ URLSession์˜ .default๊ณผ .shared์˜ ์ฐจ์ด์ ?

- URLSession.shared
: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” URLSession ์ธ์Šคํ„ด์Šค.

์•ฑ ์ „์ฒด์—์„œ ๊ณต์œ ๋˜๋ฉฐ, ๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ถ”๊ฐ€์ ์ธ ์„ธ๋ถ€ ์„ค์ •์ด ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ ์‚ฌ์šฉ.

 

- URLSession(configuration: .default)
: ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ตฌ์„ฑ์„ ์„ค์ •ํ•˜์—ฌ ์ƒ์„ฑํ•˜๋Š” URLSession ์ธ์Šคํ„ด์Šค.

๊ธฐ๋ณธ ๊ตฌ์„ฑ๊ณผ๋Š” ๋‹ค๋ฅธ ํƒ€์ž„์•„์›ƒ, ์บ์‹œ ์ •์ฑ… ๋“ฑ์˜ ์˜ต์…˜์„ ์ถ”๊ฐ€๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ • ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ํŠน์ • ํƒ€์ž„์•„์›ƒ์ด๋‚˜ ์บ์‹œ ์ •์ฑ… ์„ค์ •๊ณผ ๊ฐ™์€ ์„ธ๋ถ€์ ์ธ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ.

 

 

 

๐ŸŒŸ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ฃผ์š” HTTP ํ—ค๋”๋“ค์˜ ์ข…๋ฅ˜์™€ ์—ญํ• 

๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ ํŠน์ •ํ•œ HTTP ํ—ค๋”๋ฅผ ์„ค์ •ํ•˜๋ฉด ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์„ ๋”์šฑ ์ •๊ตํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

  • Content-Type
    : ์š”์ฒญ ๋ฐ”๋””์˜ ๋ฏธ๋””์–ด ํƒ€์ž…์„ ์ •์˜. ์ฃผ๋กœ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉ.
    ์˜ˆ: Content-Type: application/json
  • Accept
    : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์‘๋‹ต์˜ ๋ฏธ๋””์–ด ํƒ€์ž…์„ ์„œ๋ฒ„์— ์•Œ๋ฆผ. ์„œ๋ฒ„๋Š” ์ด๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ ์ ˆํ•œ ํฌ๋งท์œผ๋กœ ์‘๋‹ต.
    ์˜ˆ: Accept: application/json
  • Authorization: ์ธ์ฆ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜์—ฌ ๋ณด์•ˆ์ ์ธ ์ ‘๊ทผ์„ ์ œ์–ด. ์ฃผ๋กœ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์—์„œ ์‚ฌ์šฉ.
    ์˜ˆ: Authorization: Bearer {token}
  • User-Agent
    : ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ œ๊ณตํ•˜์—ฌ, ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ์ข…๋ฅ˜๋ฅผ ์‹๋ณ„.
    ์˜ˆ: User-Agent: MyApp/1.0 (iOS 14.5; iPhone 12)
  • Cache-Control: ์บ์‹ฑ ๋™์ž‘์„ ์„ค์ •. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ์บ์‹ฑ ์ •์ฑ…์„ ์กฐ์ •.
    ์˜ˆ: Cache-Control: no-cache
  • Cookie: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ๋ณด๋‚ธ ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜์—ฌ ์„ธ์…˜ ๊ด€๋ฆฌ ๋“ฑ.
    ์˜ˆ: Cookie: sessionid=123456

 

 

๐ŸŒŸ HTTP์š”์ฒญ์˜ ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” URLRequest ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ

  • addValue(_:forHTTPHeaderField:)
    : ์ง€์ •๋œ HTTP ํ—ค๋” ํ•„๋“œ์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋™์ผํ•œ ํ—ค๋” ํ•„๋“œ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ, ๊ธฐ์กด ๊ฐ’์— ์ถ”๊ฐ€
  • setValue(_:forHTTPHeaderField:)
    : ์ง€์ •๋œ HTTP ํ—ค๋” ํ•„๋“œ์— ์ƒˆ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค. ๋™์ผํ•œ ํ—ค๋” ํ•„๋“œ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ, ์ด์ „ ๊ฐ’์€ ๋Œ€์ฒด๋จ.
  • allHTTPHeaderFields
    : ํ˜„์žฌ ์„ค์ •๋œ ๋ชจ๋“  HTTP ํ—ค๋” ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •.
  • httpMethod
    : HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ(์˜ˆ: GET, POST ๋“ฑ)๋ฅผ ์„ค์ •.
  • httpBody
    : HTTP ์š”์ฒญ์˜ ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •.
  • timeoutInterval
    : ๋„คํŠธ์›Œํฌ ์š”์ฒญ์˜ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„์„ ์„ค์ •.

 

์ด๋“ค ๋ฉ”์„œ๋“œ๋“ค์„ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜์—ฌ URLRequest ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด, ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ 

ํ•„์š”ํ•œ ํ—ค๋”๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

๐Ÿ”— Reference
https://jeonyeohun.tistory.com/357
https://jazz-the-it.tistory.com/19

๊ด€๋ จ๊ธ€ ๋”๋ณด๊ธฐ