본문 바로가기
iOS/개념

[iOS] HTTP 통신 / URLSession

by 나리._. 2021. 10. 2.

네트워크 통신을 구현하는 애플리케이션에서는 OSI 계층의 최상단 계층, 응용 계층을 구현해서 통신을 설정한다.

 

그럼 이 응용 계층을 어떻게 구현해야할까?  URL을 이용하여 구현한다.

URL이란?

URL은 Uniform Resoure Locator의 줄임말로 네트워크 상에서 리소스들이 어디에 있는지 알려주기 위한 규약이다.
보통은 URL을 웹 주소나 웹 상에 파일이 갖는 링크로 생각하지만 데스크 탑에 있는 파일 또한 URL을 가질 수 있다.
즉 어떤 자원이든 자원이 가지는 주소값으로 URL이 매칭이 된다.

아래 웹 주소 URL 예시를 통해 알아보자.

https://yesiamnahee.tistory.com:8080/ios.html  

- https://

프로토콜로 어떠한 프로토콜을 따를 것인지를 나타냄. 다른 예시로는 ftp, mailto등이 존재.
- yesiamnahee.tistory.com
웹서버명으로 어떠한 프로토콜을 따를 것인지를 알고 나서 웹서버명(DNS명)을 해독하고 이것은 곧 IP주소로 치환된다. (OSI 계층에서 3-네트워크 계층)
- :8080
포트명으로 http 프로토콜 서버의 8080이 기본값이기 때문에 생략된다. (OSI 계층에서 4-전송 계층)
- ios.html 
리소스 경로 (OSI 계층에서 7-응용 계층)

 

응용 계층에서 가장 자주 사용하는 프로토콜  -  HTTP 프로토콜에 대해서 공부해보자.

 

HTTP?

- Hyper Text Transfer Protocol (Hyper Text를 전송하기 위한 프로토콜)

html 문서를 주고받는 데에 쓰이는 통신 프로토콜

위와 같이 HTTP통신은 기본적으로 request(요청)과 response(응답)으로 이루어져 있다

서버는 클라이언트가 요청하는 정보를 전송하고 곧바로 연결을 종료시키기 때문에 계속 연결되어있지 않다.

 

HTTP통신은 정보를 주고받을 때 그 정보를 패킷에 넣어서 보낸다.

위와 같이 패킷은 크게 Header와 Body로 이루어져 있다.

Header에는 보내는 사람 주소, 받는 사람 주소, 패킷의 생명 시간 등이 담겨있고

Body에는 전하려는 정보가 담겨있다.

 

Request

Request는 아래와 같이 이루어져있다.

Http Method - URL - Header- Body

 

클라이언트가 서버에게 HTTP 요청을 하려면 Method와 URL를 정해주어야 하는데,

서버에서는 Method에 따라 어떤 요청인지를 파악이 가능하다.

 

Http Method

- GET: 클라이언트가 서버의 리소스를 요청할 때

- POST: 클라이언트가 서버의 리소스를 새로 만들 때 (로그인 , 게시글 업로드 등)

- PUT: 클라이언트가 서버의 리소스를 전체 수정할 때 (회원정보 전체 수정) 

- PATCH: 클라이언트가 서버의 리소스를 일부 수정 할 때

- DELETE: 클라이언트가 서버의 리소스를 삭제할 때

- HEAD: GET과 동일하지만 메시지 헤더와 status만 반환 (클라이언트가 서버의 정상 작동 여부를 확인할 때)

- OPTIONS: 클라이언트가 서버에서 해당 URL이 어떤 메서드를 지원하는지 확인할 때 사용

- CONNECT: 클라이언트가 프록시를 통하여 서버와 SSL 통신을 하고자 할 때 사용

- TRACE: 클라이언트와 서버 간 통신관리 및 디버깅할 때 사용

 

Http Method에서 가장 많이 사용하는 GET과 POST에 차이에 대해 알아보자.

일단, 이 둘은 서버에 파라미터를 전달하는 방법이 다르다.
아래 예시를 통해 확인해보면,

GET

https://www.naver.com/account?id=nari&response_type=token
GET에서는 id=nari, response_type=token 두개의 파라미터를 전달하는데 URL에 다 노출이 된다.

하지만, 로그인등을 할때 중요한 정보들이 파라미터에 들어간다면 안되기 때문에
POST에서는 전달해야하는 파라미터를 Body에 넣어 정보를 노출시키지 않는다.

POST
https://www.naver.com/account
Body
id=nari

response_type=token

 

Response

서버는 클라이언트에서 보낸 Request를 해석하여 요청에 맞는 Response를 전달한다.

 

Response는 아래와 같이 이루어져있다.

Status Code - Message - Header- Body

 

Status Code

서버는 클라이언트의 요청에 응답하면서 요청이 성공적으로 완료되었는지를 알려주는 상태 코드를 함께 보낸다.

네트워크 작업에서 어떤 문제로 에러가 발생했는지 이해하려면 이 상태코드를 알고 있어야한다.

또한 코드를 작성할때부터 아래 오류들에 대해 케이스별로 처리를 해 놓아야 한다.

- 100번대 : 요청 정보를 처리 중 (현재는 거의 사용되지 않음)

- 200번대 : 요청을 정상적으로 처리 (성공)

- 300번대 : 요청을 완료하기 위해 추가 동작 필요

- 400번대 : 서버가 해결할 수 없는 클라이언트 측 에러코드 (클라이언트 잘못된 요청) 

- 500번대 : 서버가 요청 처리 실패함 (대부분)

 

 

iOS를 포함한 애플의 OS 상에서 네트워크를 구축을 하려면 URLSession을 활용해야한다. 

URLSession은 HTTP를 포함한 OSI 7계층의 프로토콜들을 지원하고 네트워크 인증, 쿠키, 캐시 관리와 같은 서버와의 데이터 교류 작업 전반을 지원한다. 또한 네트워크 데이터 전송과 관련된 테스크 그룹 또한 조정한다.

 

URLSession : URL 로딩 시스템을 구현할 수 있게하는 객체

여기서 URL 로딩 시스템이란, URL을 통해 상호작용하고 표준 인터넷 프로토콜을 이용하여 서버와 통신하는 시스템을 말한다.

URLSession은 이러한 로딩 시스템을 바탕으로 사용자나 특정 앱에서 만든 사용자 지정 프로토콜을 사용하여 URL 형태로 식별되는 리소스에 대한 access를 제공한다.

또한 데이터 읽기는 비동기형태로 수행되기 때문에 앱이 응답을 유지하고 수신 데이터(or 오류) 가 도착하는 즉시 처리할 수 있다.

 

큰 그림을 먼저 잡으면,

URLSessionConfiguration을 통해 URLSession을 생성하고

생성된 URLSession을 통해 한 개 이상의 URLSessionTask를 생성할 수 있으며 이를 통해 서버와 통신한다.

 

URLSession 객체을 생성할때 URLSessionConfiguration이라는 객체를 사용하게 되는데,

여기서는 캐시 및 쿠키를 사용하는 방법, 셀룰러 네트워크에서 연결을 허용할지와 같은 동작을 제어하는 객체를 만들게 된다.

 

이러한 객체를 만들지 않고서도 URLSession은 URLSession.Shared라는 싱글톤을 제공하기 때문에 세션에 대한 복잡한 요구사항이 없을때는 일반적으로 이러한 싱글톤을 이용하여 Session을 사용하면 된다.

 

URLSession의 종류

- 공유 세션 / Shared Session / URLSession.Shared

싱글톤으로 사용할 수 있고 기본 요청을 하기 위한 세션 (세션에 대한 복잡한 요구사항이 없을때)

- 기본 세션 / Default Session / URLSession(configuration: .default)

직접 원하는 설정 할 수 있고 캐시와 쿠키 등을 디스크에 저장, 순차적으로 데이터를 처리하기 위해 delegate 지정 가능

- 임시 세션 / Ephemeral Session / URLSession(configuration: .ephemeral)

사용자 인증 정보, 캐시, 쿠키 등을 디스크에 저장하지 않음 , 세션 만료 시 데이터 사라짐

- 백그라운드 세션 / BackgroundSession / URLSession(configuration: .background(withIdentifier:"")

 앱이 실행되지 않는 동안  백그라운드에서 콘텐츠 업로드 및 다운로드 가능

 

이렇게 세션을 구성했으면 URLSessionTask 객체를 생성할 수 있다.

URLSessionTask는 세션 내에서 데이터를 서버에 업로드 한 다음, 서버로 부터 데이터를 검색하는 작업을 만들게 된다.

 

URLSessionTask 종류

- URLSessionDataTask: 데이터 객체를 사용하여 데이터를 요청하고 응답 받음(짧고 빈번하게 요청되는 경우 사용)

- URLSessionUploadTask: 데이터 객체 또는 파일 형태의 데이터를 업로드하는 작업 수행(앱이 실행되지 않았을 때 백그라운드 업로드 지원)

- URLSessionDownloadTask: 데이터를 다운로드하여 파일 형태로 저장(앱이 실행되지 않았을 때 백그라운드 다운로드 지원)

- URLSessionStreamTask: TCP/IP 연결을 생성할 때 사용

- URLSessionWebSocketTask: WebSocket 프로토콜 표준을 통해 통신

 

 

URLSession Life Cycle

출처 : https://docs-assets.developer.apple.com/published/c7124fb5d7/bf4501ff-82b2-4dd4-9ec3-243ef0e70d21.png

 

1. SessionConfiguration을 결정한 후에 URLSession 생성

2. 통신할 URL과 Request 객체를 설정

3. 사용할 URLSessionTask를 결정하고 그에 맞는 Completion Handler나 Delegate 메서드를 작성

4. 해당 URLSessionTask를 실행(resume)

5. Task 완료 후 Completion Handler 클로저가 호출이 되고 클로저 아래서 작업에 대한 결과 값을 받아볼 수 있다.