관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] URLSession 네트워크 통신 기본 (URLSessionConfiguration, URLSession, URLComponents, URLSessionTask) 본문

iOS 기본 (swift)

[iOS - swift] URLSession 네트워크 통신 기본 (URLSessionConfiguration, URLSession, URLComponents, URLSessionTask)

jake-kim 2021. 8. 2. 22:42

URL이란?

URLSession 을 알아야하는 이유

  • swift에서 HTTP를 이용한 네트워크 사용 방법을 이해
  • Alamofire, Moya 모두 URLSession을 wrapping한것뿐
  • testable 코드를 만들 경우 URLSession을 알면 더욱 작성하기 용이
  • Alamofire, Moya를 사용할 때 오류나 특정 log에 대한것을 이해하려면 URLSession을 알고 있어야 용이

URLSession이란

  • 앱과 서버간에 데이터를 주고받기 위해서 HTTP 사용
  • URLSession은 URLSessionConfiguration을 통해 생성하고 URLSession은 여러 개의 URLSessionDataTask를 생성하여 이를 통해 서버와의 통신을 하고 Delegate를 통해 네트워크의 과정을 확인하는 형태

URLSessionConfiguration을 통해 URL 생성

  • .default: 기본 통신을 할때 사용 (쿠키와 같은 저장 객체 사용)
  • .ephemeral: 쿠키나 캐시를 저장하지 않는 정책을 사용할 때 이용
  • .background: 앱이 백그라운드 상태에 있을 때 컨텐츠를 다운로드/업로드

URLSessionTask 작업 유형

  • URLSessionDataTask: 기본적인 데이터를 받는 경우, response데이터를 메모리 상에서 처리
  • URLSessionUploadTask: 파일 업로드 시 사용, 사용하기 편한 request body 제공
  • URLSessionDownloadTask: 실제 파일을 다운받아 디스크에 사용될때 사용

URL을 구성하는 요소

let urlString = "https://ios-development.tistory.com/search/users?id=123&age=20"
let url = URL(string: urlString)

/// 주소 전체 "https://ios-development.tistory.com/search/users?id=123&age=20"
print(url?.absoluteURL)
/// 어떤식으로 네트워킹 하는지 "https"
print(url?.scheme)
/// baseURL과 같이 메인 주소 "ios-development.tistory.com"
print(url?.host)
/// host뒤에 query parameter를 제외한 주소 "/search/users"
print(url?.path)
/// query parameter 값 "id=123&age=20"
print(url?.query)
/// 설정하지 않으면 디폴트는 nil
print(url?.baseURL)

let baseURL = URL(string: "https://ios-development.tistory.com")
let relativeURL = URL(string: "/search/users?id=123&age=20", relativeTo: baseURL)
print(relativeURL?.absoluteURL)
print(relativeURL?.scheme)
print(relativeURL?.host)
print(relativeURL?.path)
print(relativeURL?.query)
print(relativeURL?.baseURL) // 이제 baseURL 확인 가능 "https://ios-development.tistory.com"

URLComponents

  • URLComponents를 사용하는 이유: URL을 사용하는 것보다는 URLComponents를 이용하면 query parameter부분을 URLQueryItem과 같은 객체로 쉽게 추가 가능
// https://ios-development.tistory.com/search/users?id=123&age=20
var urlComponents = URLComponents(string: "https://ios-development.tistory.com/search/users?")

// query 설정
let userIDQuery = URLQueryItem(name: "id", value: "123")
let ageQuery = URLQueryItem(name: "age", value: "20")
urlComponents?.queryItems?.append(userIDQuery)
urlComponents?.queryItems?.append(ageQuery)

/// 전체 경로 (문자열이 아닌 형태) https://ios-development.tistory.com/search/users?id=123&age=20
print(urlComponents?.url)
/// "https://ios-development.tistory.com/search/users?id=123&age=20"
print(urlComponents?.string)
/// [id=123, age=20]
print(urlComponents?.queryItems)

URLSession과 URLSessionTask

  • URLSessionConfiguration 생성 > URLSession 생성 > URLSession과 URLComponents를 이용하여 URLSessionDataTask 생성 > dataTask를 resume()하여 네트워크 통신
// URLSessionConfiguration 생성 (세 가지 존재): .default / .ephemeral / .background
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

// URLComponents를 생성하여 query 설정
var urlComponents = URLComponents(string: "https://ios-development.tistory.com/search/users?")
let userIDQuery = URLQueryItem(name: "id", value: "123")
let ageQuery = URLQueryItem(name: "age", value: "20")
urlComponents?.queryItems?.append(userIDQuery)
urlComponents?.queryItems?.append(ageQuery)

// URLComponents와 URLSession을 이용하여 URLSessionDataTask 생성
guard let requestURL = urlComponents?.url else { return }
let dataTask = session.dataTask(with: requestURL) { (data, response, error) in

    // error가 존재하면 종료
    guard error == nil else { return }

    // status 코드가 200번대여야 성공적인 네트워크라 판단
    let successsRange = 200..<300
    guard let statusCode = (response as? HTTPURLResponse)?.statusCode,
          successsRange.contains(statusCode) else { return }

    // response 데이터 획득, utf8인코딩을 통해 string형태로 변환
    guard let resultData = data else { return }
    let resultString = String(data: resultData, encoding: .utf8)
    print(resultData)
    print(resultString)
}

// network 통신 실행
dataTask.resume()

* 참고

https://developer.apple.com/documentation/foundation/urlsession

Comments