틈틈히 적어보는 개발 일기

[TIL #2] 네트워크 코드를 더욱 깔끔하게 (feat: URLSession, Moya) 본문

📝 TIL

[TIL #2] 네트워크 코드를 더욱 깔끔하게 (feat: URLSession, Moya)

itllbegone 2022. 3. 31. 15:50

기존에 네트워킹을 위한 코드를 작성하면서 일부 중복 코드를 줄이는데에는 어느정도 성공했었다. 그러나 네트워킹 요구사항이 많아지거나 활용하는 기능들이 많아질수록 필요한 매개변수들이 많아졌다.

// 기존 네트워킹 코드
func request<T: Decodable>(httpMethod: HttpMethod,
				endPoint: EndPoint,
                                uri: String? = nil,
                                params: [(String, String)] = [],
                                type: T.Type,
                                completion: @escaping(Result<T, NetworkError>) -> Void) {
                                
	// URLSession dataTask ...
}

이렇게 API를 호출함에 있어 필요한 파라미터, 헤더 등등이 늘어날수록 `networkRequest` 메소드에 추가해야 할 파라미터도 늘어났고, 또한 이 메소드를 호출하는 입장에서도 파라미터가 늘어나서 가독성 측면에서도 좋게 보이지 않았다.

무엇보다 해당 메소드를 변경하게 된다면 이 메소드를 쓰는 모든 곳에서 변경이 일어나야 했으므로 여러모로 문제가 많아서 이를 해결할 방법에 대해 선배님에게 여쭤보았고 좋은 방법에 대한 자료를 얻을 수 있었다.

 

https://github.com/Moya/Moya

 

GitHub - Moya/Moya: Network abstraction layer written in Swift.

Network abstraction layer written in Swift. Contribute to Moya/Moya development by creating an account on GitHub.

github.com

네트워킹을 도와주는 많은 라이브러리 중 많이 애용한다는 Moya의 존재에 대해 알게되었고, 이것과 유사하게 사용해본 결과 정말.. 놀라운 경험을 했었다.

 

// Moya like 네트워킹 코드
func request(_ api: TestAPI, completion: @escaping (Result<Data, Error>) -> Void) {
}

코드는 단순하게 요청에 필요한 것들(TestAPI)과 응답을 처리할 completion으로 깔끔하게 정리할 수 있게 되었고 호출하는 곳에서도 Human Error를 막을 수 있으며 TestAPI의 내용이 바뀌더라도 코드를 수정할 필요가 없는 장점까지 느낄 수 있었다.

TestAPI의 경우에는 다음과 같이 작성하였다.

 

enum TestAPI: Service {
    case getItem(id: String)
    case postItem
    
    var baseURL: URL {
        return BaseURL
    }
    
    var path: String? {
        switch self {
        case .getItem:
            return "getItem"
        case .postItem:
            return "postItem"
        }
    }
    
    var method: HTTPMethod {
        switch self {
        case .getItem:
            return .get
        case .postItem:
            return .post
        }
    }
    
    var parameters: Parameters? {
        switch self {
        case .getItem(let id):
            return ["id": id]
        case .fetchCarList(let id) :
            return nil
        }
    }
}

typealias Parameters = [String: String]
protocol Service {
    var baseURL: URL { get }
    var path: String? { get }
    var method: HTTPMethod { get }
    var parameters: Parameters? { get }
}

enum HTTPMethod: String {
    case get = "GET"
    case post = "POST"
}

 

이렇게 하였을 때 해당 API를 호출하고자 할 때에는 이렇게 간단하게 표현이 가능해진다. 이전의 형태에서는 호출하기 이전에 해당 API를 호출하기 위한 작업을 모두 마친 뒤 직접 호출하는 형태였다면, 이제는 호출에 있어 무엇이 필요하고 준비 없이 원하는 API를 enum에 선언된 리스트에서 부르기만 하면 되는 것이다.

APIManager().request(.getItem(id: id)) { result in }

 

Alamofire나 Moya, Kingfisher와 같이 네트워킹을 도와주는 많은 라이브러리들이 있다. 나는 Apple에서 제공하는 기본 프레임워크를 더 공부하고 이를 활용하는 것이 좋다고 생각했었는데 그래도 이런 라이브러리들을 훑어보면서 이들이 왜 인기가 많고 장점이 무엇인지에 대해 조금이나마 알 수 있었다.

 

Moya에 대한 예제나 내용을 더 알고 싶다면 아래 내용도 좋아보인다.

https://velog.io/@dlskawns96/iOS-Moya%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%82%B9-Swift-Http-%ED%86%B5%EC%8B%A0

 

[iOS] Moya를 사용한 네트워킹 (Swift Http 통신)

Moya를 사용한 네트워킹을 예제 프로젝트로 알아보겠습니다.

velog.io

 

Comments