EEYatHo 앱 깎는 이야기

Swift ) Moya Interceptor, Plugin - EEYatHo iOS 본문

iOS, Swift/Tip, Bug, Swift Error

Swift ) Moya Interceptor, Plugin - EEYatHo iOS

EEYatHo 2023. 7. 27. 16:43
반응형

 

Moya 에서 네트워크 통신에 접근할 수 있는 방법 2가지


  • Interceptor
  • Plugin

 

 

 

Interceptor #git


  • RequestInterceptor의 구현체를 MoyaProvider.Session 에 넣기
let insterceptor = MyInterceptor()
let session = Session(interceptor: insterceptor)
let provider = MoyaProvider<MyTargetType>(session: session)

 

  • adapt 로 모든 request 에 접근
  • retry 로 validation 에 실패한 response 에 접근
/// Type that provides both `RequestAdapter` and `RequestRetrier` functionality.
public protocol RequestInterceptor: RequestAdapter, RequestRetrier {}

extension RequestInterceptor {
    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        completion(.success(urlRequest))
    }

    public func retry(_ request: Request,
                      for session: Session,
                      dueTo error: Error,
                      completion: @escaping (RetryResult) -> Void) {
        completion(.doNotRetry)
    }
}

 

  • validation 을 위해서는, EndPoint 에 validationType 을 설정해야함
  • 일반적으로 .successCodes 로 설정
public extension TargetType {
    /// The type of validation to perform on the request. Default is `.none`.
    var validationType: ValidationType { .none }
}

/// Represents the status codes to validate through Alamofire.
public enum ValidationType {

    /// No validation.
    case none

    /// Validate success codes (only 2xx).
    case successCodes

    /// Validate success codes and redirection codes (only 2xx and 3xx).
    case successAndRedirectCodes

    /// Validate only the given status codes.
    case customCodes([Int])

    /// The list of HTTP status codes to validate.
    var statusCodes: [Int] {
        switch self {
        case .successCodes:
            return Array(200..<300)
        case .successAndRedirectCodes:
            return Array(200..<400)
        case .customCodes(let codes):
            return codes
        case .none:
            return []
        }
    }
}

 

  • response 에 접근하여 retry가 가능하기 때문에, 주로 AuthToken 로직 구현으로 사용.

    • adapt 에서 AccessToken 삽입
    • retry 에서 토큰 미인증 에러일 경우, Token Refresh 후 retry.

      • 좀더 심화하여, 동시 Token Refresh 방지 로직 등을 넣을 수 있음.

 

 

 

Plugin  #git


  • PluginType의 구현체를 MoyaProvider 생성자에 넣음
let plugin = MyPlugin()
let provider = MoyaProvider<MyTargetType>(plugins: [plugin])

 

  • prepare : request 에 접근하여 modifying 가능
  • 그 외, 네트워크 통신에 접근하여 side-effect 처리 가능
public protocol PluginType {
    /// Called to modify a request before sending.
    func prepare(_ request: URLRequest, target: TargetType) -> URLRequest

    /// Called immediately before a request is sent over the network (or stubbed).
    func willSend(_ request: RequestType, target: TargetType)

    /// Called after a response has been received, but before the MoyaProvider has invoked its completion handler.
    func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType)

    /// Called to modify a result before completion.
    func process(_ result: Result<Moya.Response, MoyaError>, target: TargetType) -> Result<Moya.Response, MoyaError>
}

 

  • Interceptor과 달리 retry 를 못함

    • 간단한 네트워크 통신 Logging 이나,
      공통된 에러 alert or 화면 이동 처리 (네트워크 에러, 서버 점검 에러 등)로 사용

 

 

 

공통


  • MoyaProvider 에 Plugin, Interceptor 둘 다 있다면 아래 순서로 동작

request :

1. Plugin.prepare -> 2. Plugin.willSend -> 3. Interceptor.adapt

response :

4. Interceptor.retry -> 5. Plugin.didReceive -> 6. Plugin.process

 

Plugin은 Moya, Interceptor은 Alamofire 기 때문

 

Comments