들어가면서

Moya의 장점은 뭐가 있을까??

장점으로 언급되는 곳에는 항상 테스트에 용이하다 라는 말이 항상 존재한다.

얼마나 용이하길래 항상 장점으로 꼽히는 것일까?

한번 알아보자.

(Moya를 사용하면서 만들어봤던 영화 검색 프로젝트를 예시로 사용하겠다.)

간단히보는 Moya 사용법

본격적으로 알아보기 전에 아주 간단히 Moya의 사용법을 한번 더 짚고 넘어가자.

다들 알다시피 Moya를 사용하기 위해선 TargetType 이라는 protocol을 채택해야만 한다.

import Foundation

/// The protocol used to define the specifications necessary for a `MoyaProvider`.
public protocol TargetType {

    /// The target's base `URL`.
    var baseURL: URL { get }

    /// The path to be appended to `baseURL` to form the full `URL`.
    var path: String { get }

    /// The HTTP method used in the request.
    var method: Moya.Method { get }

    /// Provides stub data for use in testing. Default is `Data()`.
    var sampleData: Data { get }

    /// The type of HTTP task to be performed.
    var task: Task { get }

    /// The type of validation to perform on the request. Default is `.none`.
    var validationType: ValidationType { get }

    /// The headers to be used in the request.
    var headers: [String: String]? { get }
}

public extension TargetType {

    /// The type of validation to perform on the request. Default is `.none`.
    var validationType: ValidationType { .none }

    /// Provides stub data for use in testing. Default is `Data()`.
    var sampleData: Data { Data() }
}

Moya를 사용하기 위해선 해당 프로토콜을 채택하는 열거형을 하나 만들어야한다.

enum MovieSearchEndPoint {
    case nowPlaying
    case searchMovie(query: String)
}
extension MovieSearchEndPoint: TargetType {
    var baseURL: URL {
        return URL(string: "<https://api.themoviedb.org/3>")!
    }
    
    var path: String {
        switch self {
        case .nowPlaying:
            return "/movie/now_playing"
        case .searchMovie:
            return "/search/movie"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .nowPlaying:
            return .get
        case .searchMovie:
            return .get
        }
    }
    
    var task: Moya.Task {
        switch self {
        case .nowPlaying:
            return .requestParameters(parameters: ["language": "ko",
                                                   "region": "KR"],
                                      encoding: URLEncoding.queryString)
        case .searchMovie(let query):
            return .requestParameters(parameters: ["language": "ko",
                                                   "region": "KR",
                                                   "query": query],
                                      encoding: URLEncoding.queryString)
        }
    }
    
    var headers: [String : String]? {
        return [
            "Content-type": "application/json",
            "authorization": "Bearer \\(Bundle.main.apiKey)"
        ]
    }
}