Weekoding

[Swift] 네트워크 통신(RESTful API, JSON, URLSession) 본문

공부 노트(Swift)

[Swift] 네트워크 통신(RESTful API, JSON, URLSession)

Weekoding 2022. 4. 20. 03:09

웹앱이 차지하는 비중이 점점 늘고 있는 추세이다.

따라서 네트워크 통신에 대한 기본적인 개념은 아주 중요할 것이다.

 

 

📂  RESTful(Representational State Transfer) API

REST : 소프트 아키텍쳐의 한 양식.

HTTP 프로토콜을 활용하였기 때문에, 웹의 장점을 최대한 활용할 수 있는 아키텍쳐 스타일.

REST는 HTTP URL을 통해 자원을 명시하고, POST / GET / PUT / DELETE를 통해 자원에 대한 CRUD를 적용한다.

Client의 요청에 따라 자원을 여러 Representation으로 나타낼 수 있는데, 대부분 JSON을 통해 주고받는다.

Client에서 바로 객체로 치환 가능한 형태의 데이터 통신이 가능하여, Server와 Client의 역할을 분리할 수 있게 되었다.

→ Client Side가 PC브라우저 뿐만 아니라, 모바일, 어플리케이션 등 플랫폼에 제약을 받지 않게 된다.

 

결론적으로 URL로 정보의 자원을 표현하는 아키텍쳐 스타일이다.

 

RESTful : HTTP, URI 기반으로 자원에 접근할 수 있도록 제공하는 애플리케이션 개발 인터페이스.

REST API를 제공하는 웹 서비스를 RESTful이라 일컫는다고 할 수 있겠다.

RESTful API를 통해 개발자는 HTTP메소드, URI만으로도 인터넷에 자료를 CRUD할 수 있는 것이다.

 

⌘ URI(Uniform Resource Identifier) : URL(Uniform Resource Locator)의 상위개념. 자원의 식별자이다.

 

 

📂 JSON(JavaScript Object Notation)

데이터를 저장하거나 전송할 때 사용되는 경량의 DATA 교환 형식

단순히 데이터를 표시하는 표현 방법이다. 텍스트 형식이며, javascript 객체 형식을 기반으로 만들어졌다.

Swift는 JSONDecoder, JSONEncoder를 통해 JSON 데이터를 핸들링 할 수 있다.

name-value 쌍으로 이루어져 있다.

//ex) JSON 배열
"developers": [
	{
      "name": "weekoding"
      "techStack": "Swift"
    },
    {
      "name": "SonHeungMin"
      "techStack": "Android"
    }
]

 

 

📂  URLSession

Foundation Framework에서 지원하는 iOS 앱과 서버간 데이터를 주고받기 위해 사용되는 API.

HTTP를 포함한 몇가지 프로토콜을 지원하고, 인증, 쿠키 관리, 캐시 관리 등을 지원한다.

통신 시에는 RequestResponse를 기본 구조로 가진다.

 

Request :

   URL객체를 통해 직접 통신하는 형태 / URLRequest객체를 만들어 통신하는 형태(옵션 설정 가능)가 있다.

   설정 가능한 옵션으로는 HTTP Method(Get, Post등), 어떤 내용을 전송할 것인지 등이다. 

Response

   설정된 Completion Handler로 Response를 받는 형태 / URLSessionDelegate를 통해 지정 메소드를 호출하는 형태가 있다.

   background 상태에서의 동작이나, 인증 및 캐싱을 default 옵션으로 사용하지 않는 경우 Delegate 패턴을 사용한다.

 

URLSession은 두 가지 종류로 구성되어 있다.

  • URLSessionConfiguration : URLSession 생성
  • URLSessionTask : 실제 서버와 통신 담당(서버로 보낸 요청에 대한 응답을 받는 역할)

 

URLSessionConfiguration을 통해 생성할 수 있는 Session은 다음과 같다.

   • URLSession.share() :

        공유 세션. Singleton이며, 기본요청을 하기 위한 세션이다.

   • URLSession(configuration: .default) :

        기본 세션. 직접 원하는 설정이 가능하다. 캐시, 쿠키 정보를 저장하고 delegate설정이 가능하다.

   • URLSession(configuration: .ephemeral) :

         캐시, 쿠키, 사용자 인증 정보들을 디스크에 저장하지 않으며, 세션 만료시 데이터가 사라진다. 

   • URLSession(configuration: .background) :

         앱이 실행되지 않는 background상태에서 컨텐츠 업로드나 다운로드 실행이 가능하다.

 

URLSessionTask의 종류는 다음과 같다.

   • URLSessionDataTask :

         data 객체를 사용해 데이터를 요청하고 응답받는다. 주로 요청이 짧고 빈번할 때 사용한다.

   • URLSessionUploadTask :

         data 객체나 파일을 업로드 한다. background 업로드를 지원한다. 

   • URLSessionDownloadTask :

         데이터를 다운받아 파일 형태로 저장한다. background 다운로드를 지원한다.

   • URLSessionStreamTask :

         TCP/IP 연결을 생성할 때 사용한다.

   • URLSessionWebSocketTask :

         Web Socket Protocol 표준을 통해 통신할 때 사용한다.

 

 

🔄  URLSession Life Cycle

    1. URLSessionConfiguration을 선택하여 Session을 생성하고, 속성을 정의한다.

    2. 통신할 URL객체, Request 객체를 생성 및 설정한다.

    3. 적절한 URLSessionTask를 생성하고, 이에 맞는 Completion Handler나 Delegate 메소드를 작성한다.

    4. 생성한 Task객체를 resume 해준다.

    5. Task가 완료되면 Completion Handler 클로저가 실행된다.(JSON 데이터 파싱, 전송 확인 완료 등등...)

 

 

⌘ 예시 코드

let url = URL(string: "https://~~~~~~")

//Request 객체
var request = URLRequest(url: url)
request.httpMethod = "GET"
        
//URLSessionConfiguration - shared(singleton)
//URLSessionTask - DataTask
//Completion Handler를 통한 Response 처리
let dataTask = URLSession.shared.dataTask(with: request, completionHandler: {[weak self] data, response, error in
    guard error == nil,
    let response = response as? HTTPURLResponse,
    let data = data,
    //응답으로 받은 JSON Decoding
    let movie = try? JSONDecoder().decode([movie].self, from: data) else{
          print("ERROR : URLSesstion data task \(error?.localizedDescription ?? "")")
          return
     }

    //상태 확인
    switch response.statusCode {
       case (200...299): //성공
          self.movieList += movie

          DispatchQueue.main.async {
            self.tableView.reloadData()
          }
                
       case (400...499): //client error
          print("""
             ERROR: Client Error - \(response.statusCode)
             Response: \(response)
          """)
         
       case(500...599): //server error
          print("""
             ERROR: Server Error - \(response.statusCode)
             Response: \(response)
          """)
         
       default:
          print("""
             ERROR: \(response.statusCode)
             Response: \(response)
          """)     
   }
})

//선언 후 꼭 resume(실행)을 해주어야 함
dataTask.resume()

 

⌘ 현업에서는 Alamofire 등의 라이브러리를 많이 사용한다고 한다.

 

 

 

📌 HTTP 통신은 여전히 어렵다고 생각한다..

그러나 이번 포스팅을 통해 가닥이 좀 잡히는게 느껴졌다.

URLSession LifeCycle에 대한 이해 및 활용 뿐만 아니라,

HTTP에 대한 지식과 JSON 파싱에 대한 공부와 코드 경험도 이루어져야 할 것이다.

 

 

 

 

 

 

 

 

참고 :

         https://velog.io/@somday/RESTful-API-%EC%9D%B4%EB%9E%80

         https://velog.io/@jch9537/URI-URL

         https://velog.io/@surim014/JSON%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

         https://hcn1519.github.io/articles/2017-07/iOS_URLSession

         https://velog.io/@sun02/iOS-URLSession-HTTP

Comments