URLSession
앱과 서버간에 데이터를 주고 받기 위해서는 HTTP를 이용했었다. 실제 iOS에서는 HTTP를 이용한 네트워킹을 어떻게 할까?
바로 URLSession을 활용하여 수행할 수 있다.
URLSession은 URLSessionConfiguration을 통해 생성하게 된다. 또한 URLSession은 여러 개의 URLSessionTask를 만들 수 있다. 이를 통해 실제 서버와의 통신을 하며, Delegate를 통해 네트워크 중간 과정을 확인해볼 수 있다.
또한 URLSessionConfiguration을 통해 다음 세 가지 유형의 URL을 생성할 수 있다,
.default : 기본 통신을 할 때 사용이 된다. (쿠키와 같은 저장 객체를 사용한다.)
.ephemeral : 쿠키나 캐시를 저장하지 않는 정책을 사용할 때 이용된다. private 모드를 생각하면 된다.
.background : 앱이 백그라운드에 있을 때 컨텐츠를 다운로드/업로드 할 때 사용한다.
그리고 URLSessionTask는 작업에 따라 세 가지로 나뉘게 된다.
URLSessionDataTask : 기본적인 데이터를 받는 경우, reponse 데이터를 메모리 상에서 처리하게 된다.
URLSessionUploadTask : 파일 업로드할 때 사용이되며, 업로드시에 더 편한 request body를 제공한다.
URLSessionDownloadTask : 실제 파일을 다운받아 디스크에 사용될 때 이용한다.
기본적으로 URL을 구성하는 요소들에 대해 먼저 알아보자.
import UIKit
// URL을 어떻게 만들까?
let urlString = "https://leechamin.tistory.com/manage/posts?searchKeyword=ios&searchType=title"
let url = URL(string: urlString)
url?.absoluteURL // 실제 주소
url?.scheme // 어떤식으로 네트워킹하고 있는지? -> https
url?.host // 제일 중요한 주소
url?.path // host뒤의 주소
url?.query // 검색어라던가 query들을 묶어서 보내게 되는데, 이에 대한 정보를 나타낸다.
url?.baseURL // nil
let baseURL = URL(string: "https://leechamin.tistory.com")
let relativeURL = URL(string: "manage/posts?searchKeyword=ios&searchType=title", relativeTo: baseURL)
relativeURL?.absoluteURL // 실제 주소
relativeURL?.scheme // 어떤식으로 네트워킹하고 있는지? -> https
relativeURL?.host // 제일 중요한 주소
relativeURL?.path // host뒤의 주소
relativeURL?.query //
relativeURL?.baseURL // 이제 baseURL 확인 가능함.
// URLComponents
var urlComponents = URLComponents(string: "https://leechamin.tistory.com/manage/posts?") // 쿼리문 전까지
// 조건(query)이 2개 있다 -> searchKeyword, searchType
let searchKeywordQuery = URLQueryItem(name: "searchKeyword", value: "ios")
let searchTypeQuery = URLQueryItem(name: "searchType", value: "title")
let keywordQuery = URLQueryItem(name: "searchKeyword", value: "애플")
// 한국어를 넣어도 %EC%95%A0%ED%94%8C 처럼 자동으로 인코딩해서 입력해준다.
urlComponents?.queryItems?.append(searchKeywordQuery)
urlComponents?.queryItems?.append(searchTypeQuery)
urlComponents?.queryItems?.append(keywordQuery)
urlComponents?.url // .scheme, .host, .path 등 확인 가능함
urlComponents?.string
urlComponents?.queryItems
urlComponents?.queryItems?.last?.value => URLComponents를 활용하여 값을 찾을 수도 있다.
그리고 위에서 언급했던 URLSession과 URLSessionTask에 대해 알아보자.
// URLSession
// 1. URLSessionConfiguration
// 2. URLSession
// 3. URLSessionTask 를 이용해서 서버와 네트워킹!
// URLSessionTask
// - dataTask
// - uploadTask
// - downloadTask
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// URL
var urlComponents = URLComponents(string: "https://leechamin.tistory.com/manage/posts?")!
let searchKeywordQuery = URLQueryItem(name: "searchKeyword", value: "ios")
let searchTypeQuery = URLQueryItem(name: "searchType", value: "title")
urlComponents.queryItems?.append(searchKeywordQuery)
urlComponents.queryItems?.append(searchTypeQuery)
let requestURL = urlComponents.url!
let dataTask = session.dataTask(with: requestURL) { (data, response, error) in
// target URL과 네트워킹 후행작업들(response에 대한 handler)을 completionHandler에 적어줘야 한다.
guard error == nil else { return } // error가 있으면 끝내고, nil이어야만 다음 작업 수행
// status 코드가 2xx이어야 성공적인 네트워킹을 했단느 것을 알 수 있다.
guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
let successRange = 200..<300 // 200에서 300전까지
guard successRange.contains(statusCode) else {
// 포함시 성공
// handle response error
return
}
guard let resultData = data else { return }
let resultString = String(data: resultData, encoding: .utf8)
print("result data ---> \(resultData)") // Data 타입
print("result data ---> \(resultString)")
}
dataTask.resume() // 실제 네트워킹이 진행된다.
// result data ---> 5374 bytes
// resultString은 엄청 많은 데이터를 보여준다.
아래의 화면이 resultString의 결과를 나타낸다.
한 눈에 봐도 양이 많다...
실제로 이렇게 받은 데이터는 Postman에서 받은 데이터와 동일하다.
이제 이 데이터들을 편하게 쓰기 위해, response 데이터를 원하는 object로 만드는 방법에 대해 알아볼 것이다.
** 패스트캠퍼스 iOS 앱 개발 올인원 패키지 : URLSession