본문 바로가기

Swift

[Swift] Provider Pattern + Moya를 곁들여 네트워크 구조 더 잘 짜기 -1-

Provider Model Design Pattern and Specification, Part 1

 

Provider Model Design Pattern and Specification, Part 1

Table of contents Provider Model Design Pattern and Specification, Part 1 Article 06/30/2006 17 minutes to read In this article --> Rob Howard Microsoft Corporation March 2, 2004 Summary: Rob Howard returns to Nothin' But ASP.NET to look at how you can use

docs.microsoft.com

위 글을 함께 참고하시면 좋습니다

 

Provider Pattern

Provider 패턴은 BaseProvider를 기반으로 조건에 따라 각자 다른 Provider를 생성할 수 있는 패턴을 의미합니다.

이 패턴을 통해 얻을 수 있는 장점은 공통적으로 적용해야하는 기능은 BaseProvider를 통해 구현하고 세부적으로 다른 기능은

개별적인 Provider를 통해 다른 객체를 구현할 수 있다는 점입니다.

 

오잉? 다른 객체를 생성하는거면 그냥 클래스로 찍어내면 되지 않나요??

 

맞습니다. 실제로 Provider 패턴의 Provider는 기본이 되는 BaseProvider를 기반으로 만들어집니다.

다만 그냥 바로 클래스를 찍어내는 것과 '조건'을 타는것이 핵심입니다.

 

이해가 잘 되지 않는다면 쉬운 네트워크 작업을 위해 만들어진 Moya 라이브러리를 보시면 좋을 것 같습니다.

Moya의 경우 MoyaProvider라는 BaseProvider로 Provider를 구현하되,

조건(Target == API)에 따라 다양한 Provider를 생성해 구분된 네트워크 작업을 구현해줍니다.

 

Moya 코드 같이 보며 구현하기

Moya 공식 Github link

 

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의 공식 깃허브 글을 보면 간단한 사용법이 나와있습니다.

 

Usage 


provider = MoyaProvider<GitHub>()
provider.request(.zen) { result in
    switch result {
    case let .success(moyaResponse):
        let data = moyaResponse.data
        let statusCode = moyaResponse.statusCode
        // do something with the response data or statusCode
    case let .failure(error):
        // this means there was a network failure - either the request
        // wasn't sent (connectivity), or no response was received (server
        // timed out).  If the server responds with a 4xx or 5xx error, that
        // will be sent as a ".success"-ful response.
    }
}

provider는 MoyaProvider를 통해 생성되며, 네트워크 작업을 요청하는 과정을 정의합니다. 우리는 위 예제를 실제로 사용할 때 특정 클래스를 만들고 개별적인 provider를 이용해 네트워크 작업을 수행할 것입니다. 

 

그런데 이렇게만 보고 따라하는건 어렵지 않지만 우리가 알려고 하는 Provider 패턴을 이해하기엔 설명이 부족합니다.

따라서 실제 Moya 라이브러리를 import 했을 때 접근할 수 있는 코드로 분석해보려 합니다.

 

우리가 주목할 부분은 예제에서 호출하고 있는 MoyaProvider 입니다

/// Request provider class. Requests should be made through this class only.
open class MoyaProvider<Target> : Moya.MoyaProviderType where Target : Moya.TargetType {
	...
    
    /// Designated request-making method. Returns a `Cancellable` token to cancel the request later.
    open func request(_ target: Target, callbackQueue: DispatchQueue? = .none, progress: Moya.ProgressBlock? = .none, completion: @escaping Moya.Completion) -> Moya.Cancellable
}

주석과 함께 포인트라고 볼 수 있는 부분을 가져왔습니다. (코드 전문은 깃허브를 참고해주세요)

MoyaProvider는 Generic유형의 Target을 통해 생성됩니다. 즉, Target에 따라 생성되는 Provider가 바뀐다는 의미입니다.

그리고 Target은 Moya에 선언된 Protocol TargetType을 따르는 타입만 사용 가능합니다.

 

TargetType

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.
    var sampleData: Data { get }

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

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

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

TargetType은 네트워크 통신을 위해 필요한 EndPoint 요소를 정의하고 있습니다. 

baseURL, path, method 등등...을 통해 Provider가 네트워크 통신을 수행하면서 필요한 정보를 모두 포함하고 있습니다.

 

따라서 TargetType 프로토콜을 채택하여 조건을 준수한 타입을 Provider 생성시 Target(조건)으로 만들어준다면, 

같은 Provider로 만들었지만 역할이 다른 Provider를 만들 수 있습니다.

 

 

아직도 조금 이해가 안돼요. 그냥 메소드의 매개변수를 다르게 넣어주면 되지 않나요?

URL, method, header... 등등 조금만 신경써주면 되지 않을까요?


간단한 네트워크 구조가 필요한 경우 Provider 패턴은 불필요한 것일 수 있습니다.

하지만 다양한 네트워크 작업 기능이 필요한 경우엔 구분할 필요가 있습니다. 또한 수 많은 네트워크 작업을 분리해야 하지만 공통적으로 동작해야 하는 기능이 필요하다면 Provider는 괜찮은 방법이 될 수 있습니다 (ex. 네트워크 동작시 해당 동작 로그 출력 및 저장)

 

일단 이번 글의 포인트!

  • Provider 패턴은 같은 타입을 생성하지만 조건에 따라 다른 객체를 생성하는 구조를 의미한다
  • 패턴은 적절한 경우에 사용하면 좋은 것이지 무조건 사용한다고 좋은게 아니다

 

2편은 모야를 갖고 Provider 패턴을 구현해볼까 하는데 워낙 Moya를 갖고 네트워크 구현을 다룬 글들이 많아 언제 작성할진 모르겠습니다.

'Swift' 카테고리의 다른 글

[Swift] 안전하게 배열 접근하기  (0) 2022.04.26
[Swift] 로컬라이징(localizing)을 이용한 string 관리  (0) 2022.03.25
[Swift] 전처리문(The preprocessor macro)  (0) 2022.03.21
Protocol  (0) 2021.12.22
[Swift] Closure  (0) 2021.12.17