iOS/UIKit

iOS 네트워크 통신 (1/3) - 개요 (URLSession, Alamofire, Moya)

kyxxn 2024. 5. 12. 16:59
728x90

학습 목표

  • 이번 시간에는 iOS에서 사용되는 네트워크 통신의 수박 겉핥기 개요
  • 서버와 통신할 때 사용되는 URLSession, Alamofire 각 특징 알기
  • URLSession과 Alamofire 차이 알기
  • Moya 특징/동작 알기

학습 내용

URLSession과 Alamofire

URLSession

An object that coordinates a group of related, network data transfer tasks.

네트워크 데이터 전송과 관련한 일을 처리하는 클래스
애플이 제공하는 API

URL Loading System

표준 IP 혹은 유저가 만든 커스텀 프로토콜을 사용하여
URLs에 의해 구분되는 자원을 접근하게 함

→ 비동기적으로 진행되므로 통제해줘야 하는데 이를 URL Session이 해줌

하나의 URL Session에서 여러 개의 URLSessionTask 인스턴스를 만들 수 있음

각각 데이터를 Fetch, Upload, Download 가능

URLSession

URL Loading System을 가능하게 하는 클래스
앱과 서버간 데이터 상호작용을 위해 HTTP 사용

구성요소

  • URL Session Configuration
    • .default: 기본 통신을 할 때 사용
    • .ephemeral: 쿠키나 캐시를 저장하지 않는 정책을 사용할 때 이용
    • .background: 앱이 백그라운드 상태에 있을 때 컨텐츠를 다운로드/업로드
  • URL Session Delegate
  • URL Session Task
    • DataTask
    • UploadTask
    • DownloadTask

사용 순서

URLSession을 사용하려면

  1. URLSession Configuration 설정 및 Session 생성
  2. Request 작성
  3. Session에 Task 부여 및 실행

Alamofire

URLSession을 추상화하여 Wrapping 한 것으로,
어려운 네트워킹 작업을 쉽게 작업할 수 있게 제공해주는 오픈소스

주요 함수

  • AF.upload: 멀티파트, 스트림, 파일 메소드를 통해 파일을 업로드
  • AF.download: 파일을 다운하거나 진행중인 다운로드를 재개
  • AF.request: 파일과 관련없는 HTTP 요청

Request 하기

Alamofire 내부에 HTTPMethod에 대해 정의된 것이 있음

요청 보낼 때 method에 넣을 인자로 사용된다.

GET

func getTest() {
        let url = "https://jsonplaceholder.typicode.com/todos/1"
        AF.request(url,
                   method: .get,
                   parameters: nil,
                   encoding: URLEncoding.default,
                   headers: ["Content-Type":"application/json", "Accept":"application/json"])
            .validate(statusCode: 200..<300)
            .responseJSON { (json) in
                // 가져온 json을 여기서 가공
                print(json)
        }
    }
  • url: 서버 주소
  • method: 통신 방식
  • parameters: 없음
  • encoding: URL이므로, URLEncoding
  • headers: JSON 형식으로 받게끔
  • validate: 상태확인 코드
  • responseJSON: 정보 받는 부분

POST

func postTest() {
    let url = ~~"https://ptsv2.com/t/im8p3-1592789118/post"~~ //지금은 막힘
    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.timeoutInterval = 10

    // POST 로 보낼 정보
    let params = ["id":"아이디", "pw":"패스워드"] as Dictionary

    // httpBody 에 parameters 추가
    do {
        try request.httpBody = JSONSerialization.data(withJSONObject: params, options: [])
    } catch {
        print("http Body Error")
    }

    AF.request(request).responseString { (response) in
        switch response.result {
        case .success:
            print("POST 성공")
        case .failure(let error):
            print("🚫 Alamofire Request Error\nCode:\(error._code), Message: \(error.errorDescription!)")
        }
    }
}

Download

func downTest() {
    let url = "http://212.183.159.230/50MB.zip"
    let fileManager = FileManager.default // 파일매니저
    // 앱 경로
    let appURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
    // 파일이름 url 의 맨 뒤 컴포넌트로 지정 (50MB.zip)
    let fileName : String = URL(string: url)!.lastPathComponent
    let fileURL = appURL.appendingPathComponent(fileName) // 파일 경로 생성
    // 파일 경로 지정 및 다운로드 옵션 설정 ( 이전 파일 삭제 , 디렉토리 생성 )
    let destination: DownloadRequest.Destination = { _, _ in
        return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
    }

    // 다운로드 시작
    AF.download(url, method: .get, parameters: nil, encoding: JSONEncoding.default, to: destination).downloadProgress { (progress) in
        // 이 부분에서 프로그레스 수정
        self.progressView.progress = Float(progress.fractionCompleted)
        self.progressLabel.text = "\(Int(progress.fractionCompleted * 100))%"
    }.response{ response in
            if response.error != nil {
                print("파일다운로드 실패")
            }else{
                print("파일다운로드 완료")
            }
    }
}

Delete, PATCH .. 등등 통신방식 다양함

Moya

Alamofire를 사용하며 네트워크 계층을 구조화하는 다른 접근 방법을 제공

Moya 특징

  • 일반적으로 열거형을 사용
  • 네트워크 요청을 안전하게 캡슐화하는데 초점
  • URLSession, Alamofire를 한 번 더 감싼 네트워크 통신 API
  • 추상화 네트워킹 라이브러리
Moya는 네트워킹을 수행하지 않음 -> 깔끔한 네트워크 계층을 구성

Alamofire의 네트워킹 기능을 사용하고,
Alamofire를 추상화하기 위한 추가적인 능력, 타입, 개념을 제공
Moya로 Alamofire를 사용한다고 생각하면 될듯

Moya 사용법

  1. 일반적으로 열거형을 사용
  2. TargetType을 채택하여 MoyaTarget을 정의해줌

*TargetType = MoyaProvider에 필요한 프로토콜

  1. MoyaTarget과 상호작용하는 MoyaProvider 생성

     class SignUpVC: UIViewController {
             private let authProvider = MoyaProvider<MoyaTest>()
     }
  2. MoyaProvider 인스턴스로 request 요청 ..

TargetType 프로퍼티 살펴보기

  1. baseURL - 서버의 도메인
    • 모든 Target의 BaseURL을 명시
    • Moya는 이를 통해 EndPoint 객체 생성
  2. path - baseURL 뒤에 추가될 Path (일반적으로 API)
    • Moya는 path를 통해 라우팅함
    • baseURL 뒤에 들어갈 subPath를 정의하며 case에 따른 EndPoint 생성
  3. method - HTTP Method (GET, POST ..)
    • Target의 모든 케이스를 위해 정확한 HTTP 메소드 제공
    • JSONEncoding, URLEncoding 두 가지를 보통 사용
    • URL에 query 값이 들어가는 경우 → URLEncoding
    • 나머지 경우 → JSONEncoding
  4. sampleData - 테스트용 Mock Data
    • 테스트를 위한 목업 데이터를 제공할 때 사용
  5. task - 리퀘스트에 사용되는 파라미터 설정
    • 제일 중요한 프로퍼티
    • 수행할 HTTP 작업 유형
    • 사용할 모든 EndPoint 마다 Task 열거형 케이스를 작성해야 함
      여기서 EndPoint란 ..? (.signUP, .signIN과 같은 동작이 수행될 서버 위치들 ?)

- `plain request` = 추가 데이터가 없는 요청 (Param이 필요없는 경우)
- `parameter request` = 인코딩된 매개변수가 포함된 요청의 body 집합
- `JSONEncodable request` = Encodable 유형으로 설정된 요청 Body
- `data request`, `upload request`
  1. validationType - 허용할 Response의 타입
  2. headers - HTTP header
    • 모든 Target의 EndPoint를 위한 HTTP header를 반환
    • EndPoint가 JSON을 반환한다면 “Content-Type”: “application/json” 반환
  • TMI

    MoyaPrider 인스턴스 생성할 때 Plugin도 넣을 수 있고,

    CombineMoya, RxMoya, ReactiveMoya 도 있고 ..

    배울게 한참 남은듯


배운 점

  • URLSession을 통해 코드 작성을 해보진 않았으나,
    URLSession을 알아야 Alamofire, Moya를 이해할 수 있겠다는 생각이 듬
  • URLSession, Alamofire, Moya의 각 특징을 알게 됨
  • 하나씩 깊게 살펴보기보다 전체적인 틀의 흐름을 이해하는 느낌 ?
    URLSession부터 하나하나 어떻게 동작하는지 봐야할 거 같음

TMI

  • Moya를 내려받으면 Alamofire도 자동으로 받아진다.
    (SPM, cocoapod 둘 다 적용)
  • 애플은 기본적으로 http를 막아둠 → https 만 사용해야 함
    이를 해제하려면 Info.plist에서 ATS(App Transport Security) 설정해주기

질문

  • 아직 EndPoint의 정확한 의미를 잘 모르겠다
  • GET 요청 연습은 할 줄 알겠는데, POST는 어떻게 할 지 모르겠음
    포스트맨 사용법도 아직,,

참조 링크

URLSession

URL Loading System | Apple Developer Documentation

URLSession | Apple Developer Documentation

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

[Swift] URLSession(1) - 개념 모아보기(URLSession, URLSessionConfiguration, URLSessionTask)

Alamofire

GitHub - Alamofire/Alamofire: Elegant HTTP Networking in Swift

iOS Swift 라이브러리 Alamofire 사용하기

[Swift] Alamofire 알아보기

Moya

https://github.com/Moya/Moya

https://github.com/Central-MakeUs/DayCarat-iOS/blob/main/DayCarat-iOS/Source/Data/Network/Moya.swift

[정리] 모야가 뭐야? 대단한 라이브러리지~👍🏻