생성한 URL을 통하여 URLSession 을 통해 데이터를 받아와보자

이전 내용 반드시 보고오기!

URLSession 의 개념

URL 생성 하는 방법

API

  • 실습을 하기에 앞서 실습하고 싶은 API를 구해야 한다
  • 본 글에서는 TMDB 를 사용하여 영화를 검색한 결과를 불러온다
  • 사용하고자 하는 API의 호출 구조를 잘 파악하고, Query 내용도 파악해야 한다

URL 생성하기

let API_KEY = "발급받은 API Key 정보 입력"
var movieSearchURL = URLComponents(string: "https://api.themoviedb.org/3/search/movie?")

// 쿼리 아이템 정의
let apiQuery = URLQueryItem(name: "api_key", value: API_KEY)
let languageQuery = URLQueryItem(name: "language", value: "ko-KR")
let searchQuery = URLQueryItem(name: "query", value: "어벤져스")

// URLComponents 에 쿼리 아이템 추가
movieSearchURL?.queryItems?.append(apiQuery)
movieSearchURL?.queryItems?.append(languageQuery)
movieSearchURL?.queryItems?.append(searchQuery)
  • 해당 API의 BaseURL은 movieSearchURL 변수에 URLComponents로 저장한다
  • 쿼리는 3가지로 구분된다
    • apiQuery → API Key
    • languageQuery → 언어 설정 ( 한국어로 검색하기 위해 ko-KR 설정 )
    • searchQuery → 검색하고자 하는 검색어 입력 ( 예제에서는 어벤져스 )
  • QueryItem을 설정했으면 Components에 추가시켜 준다

URL 얻어오기

  • URL을 생성했으면 URL 정보를 얻어와야 하는데 Optional로 정의되어 있기 때문에 옵셔널 바인딩을 이용해 그 값을 가져오도록 한다
guard let requestMovieSearchURL = movieSearchURL?.url else { throw NSError() }
  • 일반적으로 else { return } 의 형태지만, 예제에서는 함수내의 구현이 아니기 때문에 Error정보를 던져주기 위하여 throw NSError() 를 사용했다
  • URL 정보가 nil 이 아니라면 requestMovieSearchURL 상수에 URL 정보가 저장된다

URLSession Configuration 설정

// configuration 설정 -> default
let config = URLSessionConfiguration.default

// session 설정
let session = URLSession(configuration: config)
  • URLSession Configuration을 설정하기 위해 config 상수에 default 로 설정
  • session 상수에 해당 configuration을 적용한 URLSession 을 할당한다

URLSessionTask 설정

  • 해당 예제에서는 Task 목록중, DataTask를 적용
// dataTask 설정
let dataTask = session.dataTask(with: requestMovieSearchURL) { (data, response, error) in
    guard error == nil else { return }
    
    guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
    let successRange = 200..<300
    guard successRange.contains(statusCode) else { return }
    
    guard let resultData = data else { return }
    let resultString = String(data: resultData, encoding: .utf8)
    print("resultData -->\(resultData)")
    print("resultString -->\(resultString)")
}

dataTask.resume()
  • dataTask 상수에 session.dataTask를 적용
  • dataTask에는 일반적으로 data 정보, response 정보, error정보 가 들어온다
guard error == nil else { return }
  • error 가 nil 일경우 즉, error 상황이 아닐경우에만 다음 코드를 실행하고 error일경우 return으로 종료
guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
    let successRange = 200..<300
    guard successRange.contains(statusCode) else { return }
  • HTTP StateCode 중, 200번대의 코드가 정상적인 상황이기 때문에 200번대의 상황일때만 다음 코드 진행
  • response 를 HTTPURLResponse 로 다운캐스팅(as?) 하여 statusCode로 상태코드를 확인할 수 있다
  • response의 상태코드가 200번대 일때 다음 코드를 진행하고 그렇지 않으면 return으로 종료

→ 해당 코드는 간단한 예시이지만 각 상태코드 마다 적절한 View를 보여주면 좋을것 같다

guard let resultData = data else { return }
    let resultString = String(data: resultData, encoding: .utf8)

    print("resultData -->\(resultData)")
		// resultData -->8482 bytes
 
    print("resultString -->\(resultString)")
		// 실행 결과가 너무 길기 때문에 직접 확인해보는걸 추천!
  • data가 nil인지 아닌지 확인하기 위해 바인딩을 통하여 nil 이 아닌경우 다음 코드를 진행
  • resultData 상수에는 data에 대한 길이정보가 출력
  • resultString 상수에는 해당 데이터를 utf8로 인코딩하여 그 내용을 보여준다
dataTask.resume()
  • 위에서 dataTask를 정의했어도 즉각 실행되진 않는다 resume() 메서드를 사용하면 통신을 시작한다

전체코드

let API_KEY = "발급받은 API Key 정보 입력"
var movieSearchURL = URLComponents(string: "https://api.themoviedb.org/3/search/movie?")

// 쿼리 아이템 정의
let apiQuery = URLQueryItem(name: "api_key", value: API_KEY)
let languageQuery = URLQueryItem(name: "language", value: "ko-KR")
let searchQuery = URLQueryItem(name: "query", value: "어벤져스")

// URLComponents 에 쿼리 아이템 추가
movieSearchURL?.queryItems?.append(apiQuery)
movieSearchURL?.queryItems?.append(languageQuery)
movieSearchURL?.queryItems?.append(searchQuery)

// 옵셔널 바인딩
guard let requestMovieSearchURL = movieSearchURL?.url else { throw NSError() }

// configuration 설정 -> default
let config = URLSessionConfiguration.default

// session 설정
let session = URLSession(configuration: config)

// dataTask 설정
let dataTask = session.dataTask(with: requestMovieSearchURL) { (data, response, error) in
    guard error == nil else { return }
    
    guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
    let successRange = 200..<300
    guard successRange.contains(statusCode) else { return }
    
    guard let resultData = data else { return }
    let resultString = String(data: resultData, encoding: .utf8)
    print("resultData -->\(resultData)")
    print("resultString -->\(resultString)")
}

dataTask.resume()

+ Recent posts