URLSession

SteadySlower·2022년 2월 9일
0

iOS Development

목록 보기
4/37

URLSession

정의

HTTP를 이용한 네트워크 통신을 가능하게 해주는 iOS 개발의 기본 API입니다.

iOS를 개발을 할 때 네트워크 통신을 위해서는 보통 Alamofire라는 프레임워크를 많이 사용하시는데 그 Alamofire가 URLSession을 한 단계 추상화해서 만든 것입니다.

이번 포스팅에서는 URLSession의 개요와 활용하는 기본적인 방법을 정리해보겠습니다.

구조

URLSession을 이해하기 위해서 알아야할 3 (+ 1)가지 객체가 있습니다. 아래 그림과 표로 설명하도록 하겠습니다.

객체 이름역할
URLSessionConfiguration통신 작업의 설정 값을 가지고 있음. URLSession 객체를 만들 때 인자로 전달함.
URLSession실제 네트워크 통신을 실행하는 객체
URLSessionTask실행할 네트워크 통신 그 자체
URLSessionDelegate네트워크 통신의 과정에서 실행해야할 코드를 실행해주는 객체 (필수는 아님)

위 그림에 표시된 과정을 코드로 간략하게 보여드리면 아래와 같습니다.

//✅ configuration 객체 만들기
let config = URLSessionConfiguration.default

//✅ configuration 객체를 인자로 전달해서 URLSession객체 만들기
let session = URLSession(configuration: config)

//✅ task 만들기
let task = session.dataTask(with: requestURL) { (data, response, error) in
  print(response)
}

//✅ task 실행하기
task.resume()

위 코드를 보면 URLSessionTask는 URL과 completionHandler를 받는 것을 볼 수 있습니다. 특히 completionHandler는 서버에서 받은 data와 통신의 성공 여부를 담은 response, 마지막으로 error를 인자로 받는 것을 볼 수 있습니다.

또한 URLSessionTask는 객체를 생성함과 동시에 실행되지 않고 resume이라는 메소드를 통해서 실행해주어야 합니다.

URLSessionConfiguration의 유형

통신 작업의 설정 값을 가진 객체인 URLSessionConfiguration는 총 3가지의 유형을 가지고 있습니다.

이름특징
default기본적인 통신
ephemeral흔적을 남기지 않는 통신으로 브라우저의 시크릿 모드처럼 캐시나 쿠키를 저장하지 않음.
backgroud앱이 백그라운드에 있을 때 통신할 때 사용

URLSessionTask

URLSessionTask도 3가지 옵션이 있습니다.

이름특징
URLSessionDataTask가장 기본적인 통신 방법으로 데이터를 메모리에 저장해서 처리하는 방법입니다. background session에서는 실행할 수 없습니다.
URLSessionUploadTask파일을 업로드할 때 사용합니다. 업로드할 데이터를 Request Body에 담아서 전송할 수 있습니다.
URLSessionDownloadTask파일을 다운로드에서 기기의 디스크에 저장할 때 사용합니다.

URL 객체 다루기

iOS에서는 URL을 단순히 String 객체로 다루지 않고 URL을 위한 전용 객체가 있습니다.

URL 객체 만들기

string을 이용해서 만들거나 기존의 baseURL에 더해 만들 수도 있습니다.

//✅ String으로 URL 객체 만들기
let urlString = "https://itunes.apple.com/search?media=music&entity=song&term=Gdragon"
let url = URL(string: urlString)

//✅ baseURL 사용하는 법 = 상대 경로로 URL 쓰기
let baseURL = URL(string: "https://itunes.apple.com")
let relativeURL = URL(
    string: "search?media=music&entity=song&term=Gdragon",
    relativeTo: baseURL
    )

URL 객체의 Property들

let urlString = "https://itunes.apple.com/search?media=music&entity=song&term=Gdragon"
let url = URL(string: urlString)

url?.absoluteString //👉 String으로 표현된 전체 경로
	// = "https://itunes.apple.com/search?media=music&entity=song&term=Gdragon"

url?.scheme //👉 통신방법
	// = "http"

url?.host //👉 호스트 
	// = "itunes.apple.com"

url?.path //👉 경로
	// = "/search"

url?.query //👉 쿼리
	// = "media=music&entity=song&term=Gdragon"

url?.baseURL //👉 baseURL
	// = nil -> 🚫 일반적인 URL 객체에는 없다.

relativeURL?.baseURL
	// = "https://itunes.apple.com" -> 💡 상대 경로로 init한 URL 객체는 가지고 있는 property

URLComponents

위 URL 객체가 String보다 더 네트워크 통신에 특화된 객체이기는 하지만 중간에 쿼리문 등을 추가, 수정, 삭제하거나 할 때는 결국 String을 수정하는 것과 큰 차이가 없습니다. 이런 문제를 해결하기 위해서 URL 객체를 한단계 추상해서 URL의 구성 요소를 하나하나 분리해서 object화 시켜놓은 것이 URLCompenents 객체입니다.

//✅ URL components 객체 만들기
var urlComponents = URLComponents(string: "https://itunes.apple.com/search?")

//✅ 각 쿼리들을 QueryItem 객체로 만들 수 있다.
let mediaQuery = URLQueryItem(name: "media", value: "music")
let entityQuery = URLQueryItem(name: "entity", value: "song")
let termQuery = URLQueryItem(name: "term", value: "지드래곤")

//✅ URLComponents 안에 있는 queryItems 배열에 URLQueryItem객체를 추가할 수 있다.
urlComponents?.queryItems?.append(mediaQuery)
urlComponents?.queryItems?.append(entityQuery)
urlComponents?.queryItems?.append(termQuery)

//✅ URL이 자동으로 조립된다!
urlComponents?.string
	// = Optional("https://itunes.apple.com/search?media=music&entity=song&term=%EC%A7%80%EB%93%9C%EB%9E%98%EA%B3%A4")

특히 URL에 한글이 들어가면 인코딩 문제가 발생할 수 있는데 완성된 URL을 보면 인코딩이 자동으로 되어 있는 것을 볼 수 있습니다.

마치며

  1. 사실 네트워킹은 앱의 핵심적인 기능이다보니 더 좋은 프레임워크가 많습니다. 해당 프레임 워크들을 더 편리한 기능들을 제공하곤 합니다.
  2. 하지만 결국 URLSession의 위에서 작동하는 경우가 많습니다. URLSession의 기본을 공부하면 해당 프레임워크를 공부할 때 더 도움이 되는 것 같습니다^^
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글