URL Session과 Alamofire

dsfasdfsfsfds·2022년 4월 14일
0

안녕하세요 제제로입니다 😊
개인 프로젝트를 진행하면서 사용은 자주 했지만 두 라이브러리의 차이점을 정확히 인지하고 사용하고 있다는 생각이 안들어서 이번 기회에 정리 해보려고 합니다.

💡 URL Session 이란?

앱에서 보통 서버랑 통신할때 REST API를 자주사용한다. 이때 HTTP통신을 하기 위한 Swift에 있는 라이브러리 입니다.

URL Session은 인증 지원을 위한 많은 델리게이트 메서드를 제공하며, 애플리케이션이 실행 중이지 않거나 일시 중단된 동안 백그라운드 작업을 통해 콘텐츠를 다운로드하는 것을 수행하기도 합니다.

💡 URL Session의 유형

URL Session은 세가지 유형의 세션을 제공하는데, URLSession 객체가 소유한 configuration 프로퍼티 객체에 의해 결정됩니다.

1.Default Session

  • 기본 통신을 할때 사용 (쿠키와 같은 저장 객체 사용)

2.Ephemeral Session

  • 쿠키나 캐시를 저장하지 않는 정책을 사용할 때 이용

3.Background Session

  • 앱이 백그라운드 상태에 있을 때 컨텐츠를 다운로드/업로드

💡 URLSessionTask

URLSessionTask 세션 작업 하나를 나타내는 추상 클래스입니다.

하나의 세션 내에서 URLSession 클래스는 세 가지 작업 유형, 즉 데이터 작업(Data Task), 업로드 작업(Upload task), 다운로드 작업(Download Task)을 지원합니다.

URLSessionDataTask: HTTP의 각종 메소드를 이용해 서버로부터 응답 데이터를 받아서 Data 객체를 가져오는 작업을 수행

URLSessionUploadTask: 애플리케이션에서 웹 서버로 Data 객체 또는 파일 데이터를 업로드 하는 작업을 수행, 주로 POST 혹은 PUT 메소드를 이용

URLSessionDownloadTask: 서버로부터 데이터를 다운로드 받아서 파일의 형태로 저장하는 작업을 수행한다. 애플리케이션의 상태가 대기 중 이거나 실행 중이 아니라면 백그라운드 상태에세도 다운로드 가능

JSON, XML, HTML 데이터 등 단순한 데이터의 전송에는 주로 데이터 작업을 사용하며, 용량이 큰 파일의 경우 애플리케이션이 백그라운드 상태인 경우에도 전달할 수 있도록 업로드(다운로드) 작업을 주로 사용합니다.

💡 코드 예제
// 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 request = URLRequest(url:requestURL) 
// method나 header를 지정해야 할 때 request 객체 생성해서 프로퍼티로 지정
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()

그럼 Alamofire는 무엇인가??

💡 Alamofire는 Swift 기반 HTTP 네트워킹 라이브러리로 Apple의 Foundation networking 기반으로 인터페이스를 제공하여 일반적인 네트워킹 작업을 단순화합니다

즉, Alamofire는 기존의 URL Session 기반으로 작동하며 URL Session 을 Wrapping한 라이브러리 입니다.

  • 연결가능한(Chainable) Request/Response 메서드
  • URL / JSON / plist 파라미터 인코딩
  • 파일 / 데이타 / 스트림 / 멀티파트 폼 데이타 업로드
  • Request 또는 Resume 데이터를 활용한 다운로드
  • NSURLCredential을 통한 인증(Authentication)
  • HTTP 리스폰스 검증(Validation)
  • TLS 인증서와 공개 키 Pinning
  • 진행 상태 클로저와 NSProgress
  • cURL 디버깅 출력
  • 광범위한 단위 테스트 보장
  • 완벽한 문서화

이런 다양한 기능들을 제공한다고 합니다.

즉 우리는 코드를 더 간결화하고 가독성 있게 작성하기 위해 Alamofire를 많이 사용합니다.

💡 코드로 확인하는 URL Session, Alamofire 의 차이점

// URL Session Code
var request = URLRequest(url: URL(string: "https://api.github.com/users")!)
request.httpMethod = "POST"
let params = ["id":id, "password":password] as Dictionary

do {
  try request.httpBody = JSONSerialization.data(withJSONObject: params, options: [])
} catch {
  return
}

request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) -> Void in
  if let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode {
    //SUCCESS
  }else{
    //Failure
    }
})

request 객체를 생성하면 Method를 설정, parameter를 딕셔너리로 만든후 JSON으로 encoding 후 httpbody에 넣어주고 따로 헤더도 addValue로 넣어줘야합니다.

또한 completionHandler에서 성공 유무도 따로 검사해야합니다.

이 코드를 Alamofire로 변환해보면

 AF.request("https://api.github.com/users", method: .get, parameters: param, encoding: URLEncoding.default, headers: ["Content-Type":"application/json", "Accept":"application/json"])
            .validate(statusCode: 200..<300)
            .responseJSON { (response) in
            if let JSON = response.result.value
            {
                print(JSON)
            }
        }

이렇게 간단하게 바꿀 수 있습니다.

request 메소드의 파라미터로 http통신 파라미터를 넣어주고 encoding 값으로 어떻게 파라미터를 인코딩 할지 , 어떻게 값이 전달 될 지 정하게 됩니다.

URLEncoding.default는 get,head,delete 일 경우 query파라미터로 붙히게 되고 나머지일 경우 http body로 값이 전달 됩니다.

validate로 유효성 체크도 진행 할 수 있습니다.

responseJSON,responseData 등 response로 받는 data의 형식을 정할 수 있습니다.


마무리

예전에 Alamofire 공부하면서 노션으로 정리했던 내용인데 블로그 시작하면서 옮기면서 다시 읽어보니 새롭게 느껴지는 부분도 있었다. 글 작성만 하고 다시 보지 않으면 까먹으니 꾸준히 작성한 글들을 자주 읽어야겠다!!

감사합니다 😊
건강한 지적은 언제나 환영합니다

profile
fdsafsdafsda

0개의 댓글