Swift Moya Provider 커스텀

예전에 Moya + RxSwift에 대한 포스트를 올린적이 있었는데, 이번에는 제가 프로젝트에서 사용하고 있는 Moya Provider를 커스텀 한 내용을 공유하고자 합니다.

Plugins

    class OpenitProvider<T:TargetType>: MoyaProvider<T> {
      init(stubClosure: @escaping StubClosure = MoyaProvider.neverStub) {
        /// NetworkActivityPlugin
        let networkClosure = {(_ change: NetworkActivityChangeType, _ target: TargetType) in
          switch change {
            case .began:
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
            case .ended:
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
          }
        }
        //Your custom configuration
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Manager.defaultHTTPHeaders
        ///Add the network logger on the configuration
        //For Alamofire
        let manager = Manager(configuration: configuration)
        manager.startRequestsImmediately = false
        // make provider
        super.init(stubClosure: stubClosure,
                   manager: manager,
                   plugins: [APILoggingPlugin(),
                            NetworkActivityPlugin(networkActivityClosure: networkClosure)])
      }
    }

NetworkActivityPlugin


Moya를 사용하면서 가장 먼저 부딪치는 문제로 Network Activity Indicator 문제일 겁니다. Alamofire나 다른 통신 방법들을 사용하면 공통 메소드를 만들어 간단하게 처리할 수 있는데, 저는 RxSwift와 Moya를 사용하는 케이스라 이게 공통으로 만들어서 쓰기 번거로웠습니다. 처음 Moya와 RxSwift를 함께 사용했을 때에는 api 호출 전에 에서 시작하고 종료하는 로직을 추가해서 사용했었는데, 이게 하나하나 추가해서 쓰는 게 여간 불편한 게 아녔습니다. 그래서 처음에 plugin이 있는지도 모르고 쓰고 있다가 moya 문서에서 plugin 내용을 발견했습니다. 문서 하단에 아주 친절하게 나와 있었습니다.


Network Activity Indicator One very common task with iOS networking is to show a network activity indicator during network requests, and remove it when all requests have finished. The provided plugin adds callbacks which are called when a requests starts and finishes, which can be used to keep track of the number of requests in progress, and show / hide the network activity indicator accordingly. The plugin can be found at [Sources/Moya/Plugins/NetworkActivityPlugin.swift](<https://github.com/Moya/Moya/blob/master/Sources/Moya/Plugins/NetworkActivityPlugin.swift>)


덕분에 쉽게 사용 예시들을 찾아서 추가했는데 그 내용이 이 코드입니다.

    /// NetworkActivityPlugin
    let networkClosure = {(_ change: NetworkActivityChangeType, _ target: TargetType) in
      switch change {
        case .began:
          UIApplication.shared.isNetworkActivityIndicatorVisible = true
        case .ended:
          UIApplication.shared.isNetworkActivityIndicatorVisible = false
      }
    }

    NetworkActivityPlugin(networkActivityClosure: networkClosure)

네트워크 클로저에서는 이것 말고도 여러 작업을 할 수 있습니다. 따로 설명 없이도 쉽게 이해하실 수 있겠지만 내용을 보시면 네트워크 began일 때 네트워크 인디케이터를 돌리고 ended일 때 멈춥니다. 그리고 그 클로져를 NetworkActivityPlugin 에 집어넣어 Provider 를 만들어줍니다.

Logging Plugin

처음으로 Provider 를 확장해서 사용해보고 Plugin 의 존재를 알게 되고 이것저것 시험해봤습니다. 무엇을 할 수 있을까 고민하다가 다음으로 시도한 게 Logging입니다. 저희 프로젝트에서는 항상 Header에 사용자 정보를 담아서 API를 주고받고 있습니다. 근데 이게 잘못된 경우도 쉽게 알게 하기 위해서 통신 부분만 플러그인으로 로그를 찍어보기로 했습니다. 문서를 보면 기본적으로 네트워크 로깅을 지원합니다.


Logging During development it can be very useful to log network activity to the console. This can be anything from the URL of a request as sent and received, to logging full headers, method, request body on each request and response. The provided plugin for logging is the most complex of the provided plugins, and can be configured to suit the amount of logging your app (and build type) require. When initializing the plugin, you can choose options for verbosity, whether to log curl commands, and provide functions for outputting data (useful if you are using your own log framework instead of print) and formatting data before printing (by default the response will be converted to a String using String.Encoding.utf8 but if you’d like to convert to pretty-printed JSON for your responses you can pass in a formatter function, see the function JSONResponseDataFormatter in [Examples/_shared/GitHubAPI.swift](<https://github.com/Moya/Moya/blob/master/Examples/_shared/GitHubAPI.swift>) for an example that does exactly that) The plugin can be found at [Sources/Moya/Plugins/NetworkLoggerPlugin.swift](<https://github.com/Moya/Moya/blob/master/Sources/Moya/Plugins/NetworkLoggerPlugin.swift>)


하지만 로깅을 찍는 결과가 제가 원하는 형태가 아니라서 너무 보기 불편해 커스텀 플러그인을 만들어서 사용하기로 했습니다. 커스텀 플러그인을 만들려면 PluginType 을 구현해야 합니다.