Moya官方文件翻譯

xixinRunBoy發表於2018-03-21

原文地址:https://github.com/Moya/Moya/tree/master/docs 參考文章:http://www.jianshu.com/p/c1494681400b

Endpoints功能翻譯

endpoint是Moya用來推斷最終將要進行的網路請求的半內部資料結構。 endpoint儲存以下資料:

  • The url.
  • The HTTP method (GET, POST, etc).
  • The request parameters.
  • The parameter encoding (URL, JSON, custom, etc). 引數編碼
  • The HTTP request header fields. 請求頭
  • The sample response (for unit testing). 測試資料返回

Providers將Targets的資料解析Endpoint裡面,再將Endpoint解析到實際的網路請求中. 這裡有兩種方式和Endpoint互動 1.當建立provider時,可以指定從Target到Endpoint的對映方式。 2.當建立provider時,可以指定從Endpoint到URLRequest的對映方式。 第一條類似於以下內容

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let url = target.baseURL.appendingPathComponent(target.path).absoluteString
    return Endpoint(url: url, sampleResponseClosure: {.networkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
}
複製程式碼

這實際上是Moya提供的預設實現。 如果您需要某些自定義內容,例如,如果您的API需要自定義引數解析,或者如果您要建立一個在單元測試中返回非200 HTTP狀態的測試提供程式,這就是你可以修改的地方。 第二種使用是非常罕見的。 Moya試圖阻止你不必擔心低階細節。如果你需要它也可以進行修改。 其使用在下面進一步描述。 讓我們來看一個提供從Target到Endpoint靈活解析的示例。

從Target 到 Endpoint

預設情況下,Endpoint例項使用URLEncoding.default型別引數編碼。 您可以在設定提供程式時使用endpointClosure中的Endpoint初始值設定的可選parameterEncoding引數指定在endpointClosure中逐個目標地編碼引數的方式。 有三種引數編碼型別:URL編碼,JSON編碼,PropertyList編碼,它直接對映到Alamofire中的相應型別.每個型別都有.default屬性,它給你一個特定的ParameterEncoding型別的預設例項。此外,如果你想建立你的自定義型別,只是實現ParameterEncoding協議就可以了.通常你只是想要URLEncoding.default,但你可以使用你喜歡的。這些直接對映到Alamofire引數編碼。 如果你想獲得關於ParameterEncoding型別的更多資訊以及如何建立自己的,請檢視Alamofire的關於這個問題的文件。 您可以在此閉包中新增引數或HTTP頭欄位。 例如,我們可能希望在HTTP頭欄位中設定我們的應用程式名稱供服務端分析

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let defaultEndpoint = MoyaProvider.defaultEndpointMapping(target)
    return defaultEndpoint.adding(newHttpHeaderFields: ["APP_NAME": "MY_AWESOME_APP"])
}
let provider = MoyaProvider<GitHub>(endpointClosure: endpointClosure)
複製程式碼

這也意味著您可以向部分或所有endPoint提供額外引數。 例如,假設我們需要假設的MyTarget目標的所有值的認證令牌,除了實際進行認證的目標之外。 我們可以構造類似於以下的endpointClosure。

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let defaultEndpoint = MoyaProvider.defaultEndpointMapping(target)

    // Sign all non-authenticating requests
    switch target {
    case .authenticate:
        return defaultEndpoint
    default:
        return defaultEndpoint.adding(newHttpHeaderFields: ["AUTHENTICATION_TOKEN": GlobalAppStorage.authToken])
    }
}
let provider = MoyaProvider<GitHub>(endpointClosure: endpointClosure)
複製程式碼

注意我們可以依靠Moya的現有行為並擴充套件 - 而不是替換它。 add(newParameters :)和add(newHttpHeaderFields :)函式允許您依賴現有的Moya程式碼並新增您自己的自定義值。 示例響應是TargetType協議的要求。 但是它們只指定返回的資料。 目標到端點對映閉包是可以指定更多細節的地方,這對單元測試很有用。 示例響應具有以下兩個值之一:

  • NetworkError,帶有NSError?可選錯誤型別。
  • NetworkResponse,具有Int狀態程式碼和Data返回的資料。

Request Mapping

正如我們前面提到的,這個庫的目的不是真正提供一個編碼框架來訪問網路 - 這是Alamofire的工作.相反,Moya是一種方式來構思你對網路訪問的想法,並提供編譯時檢查明確定義的網路目標。您已經瞭解瞭如何使用MoyaProvider初始值設定器的endpointClosure引數將Targets對映到endpoints。這讓你建立一個Endpoint例項,Moya將使用它來推斷網路API呼叫。在某些時候,該Endpoints必須解析成一個實際的URLRequest給Alamofire。這就是requestClosure引數的用途。 requestClosure是一種可選的,用來修改網路的請求的最後方式。它具有預設值MoyaProvider.DefaultRequestMapper,它只使用Endpoint例項的urlRequest屬性。 此閉包接收Endpoint例項,並負責呼叫RequestResultClosure(Result <URLRequest,MoyaError> - > Void的簡寫)的引數與表示Endpoint的請求。在這裡做你的OAuth簽名或其他事情。因為你可以非同步地呼叫閉包,你可以使用你喜歡的任何認證庫(例子)。除了修改請求,你可以簡單地記錄它。

let requestClosure = { (endpoint: Endpoint<GitHub>, done: MoyaProvider.RequestResultClosure) in
    var request = endpoint.urlRequest

    // Modify the request however you like.

    done(.success(request))
}
let provider = MoyaProvider<GitHub>(requestClosure: requestClosure)
複製程式碼

此requestClosure可用於修改特定於URLRequest的屬性或向請求提供直到該請求建立成功才能知道的資訊,例如Cookie設定。注意上面提到的endpointClosure不是用於這個目的或任何特定於請求的應用程式級對映。 此引數實際上對修改請求物件非常有用。 URLRequest有很多可以自定義的屬性。假設您要停用所有要求的Cookie:

{ (endpoint: Endpoint<ArtsyAPI>, done: MoyaProvider.RequestResultClosure) in
    var request: URLRequest = endpoint.urlRequest
    request.httpShouldHandleCookies = false
    done(.success(request))
}
複製程式碼

您還可以執行網路請求的日誌記錄,因為此閉包在請求傳送到網路之前被呼叫。

Providers功能翻譯

當使用Moya時,您通過MoyaProvider例項建立所有API請求,傳遞一個列舉值,指定您要呼叫的endpoint。 設定好您的endpoint後,您基本上設定好了基本用法:

let provider = MoyaProvider<MyService>()
複製程式碼

經過簡單的設定,你就可以開始請求了:

provider.request(.zen) { result in
    // `result` is either .success(response) or .failure(error)
}
複製程式碼

這就是全部的了! request()方法返回一個Cancellable,它只有一個公共函式cancel(),您可以使用它來取消請求。 有關Result型別的更多資訊請參閱示例。 記住如何放置target和provider完全取決於你。 你可以檢視Artsy的實現的例子。 但不要忘記在屬性中保留它的引用。 如果它被釋放,你會看到-999“cancelled”錯誤響應。

Advanced Usage

為了解釋MoyaProvider的所有配置選項,我們將在下面的章節逐一介紹每個引數。

endpointClosure:

MoyaProvider初始化程式的第一個(可選)引數是一個endpoints閉包,它負責將列舉值對映到具體的Endpoint例項。 讓我們來看看具體是什麼樣子。

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let url = target.baseURL.appendingPathComponent(target.path).absoluteString
    return Endpoint(url: url, sampleResponseClosure: {.networkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
}
let provider = MoyaProvider(endpointClosure: endpointClosure)
複製程式碼

注意,我們不必在MoyaProvider初始化程式中指定泛型型別,因為Swift將從我們的endpointClosure型別推斷它。 這個endpointClosure就像你可以得到的一樣簡單。 它實際上也是預設實現,儲存在MoyaProvider.defaultEndpointMapping。 檢視Endpoints文件瞭解更多有關為什麼你需要自定義這些的資訊。

requestClosure:

下一個可選的初始化引數是requestClosure,它將Endpoint解析為實際的URLRequest。 再次檢視Endpoints文件瞭解如何以及為什麼這樣做。

stubClosure:

下一個選項是提供一個stubClosure。 這將返回.never(預設值),.immediate或.delayed(seconds)之一,您可以將已存根的請求延遲一定的時間。 例如,.delayed(0.2)將延遲每個存根請求。 這可以很好地模擬單元測試中的網路延遲。 很好的是如果你需要不同於其他請求來存根一些請求,你可以使用自己的閉包。

let provider = MoyaProvider<MyTarget>(stubClosure: { target: MyTarget -> Moya.StubBehavior in
    switch target {
        /* Return something different based on the target. */
    }
})
複製程式碼

但通常你想要對所有的目標執行同樣的stubbing行為。 有三個類方法在MoyaProvider你可以使用代替。

MoyaProvider.neverStub
MoyaProvider.immediatelyStub
MoyaProvider.delayedStub(seconds)
複製程式碼

所以在上面的例子中,如果你想要立即改變所有目標的stubbing行為,以下任一將起作用。

let provider = MoyaProvider<MyTarget>(stubClosure: { (_: MyTarget) -> Moya.StubBehavior in return .immediate })
let provider = MoyaProvider<MyTarget>(stubClosure: MoyaProvider.immediatelyStub)
複製程式碼

manager

接下來就是manager引數。 預設情況下,你會得到一個基本配置的自定義Alamofire.Manager例項。

public final class func defaultAlamofireManager() -> Manager {
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders

    let manager = Alamofire.Manager(configuration: configuration)
    manager.startRequestsImmediately = false
    return manager
}
複製程式碼

只有一個特別的事情:因為構造一個Alamofire.Request在AF將預設立即啟用請求,即使單元測試的stubbing請求。 因此在Moya中,startRequestsImmediately預設設定為false。 如果您想要自定義自己的管理器,例如要新增SSL繫結,請建立一個並傳遞進來,所有請求將路由通過自定義配置的管理器。

let policies: [String: ServerTrustPolicy] = [
    "example.com": .PinPublicKeys(
        publicKeys: ServerTrustPolicy.publicKeysInBundle(),
        validateCertificateChain: true,
        validateHost: true
    )
]

let manager = Manager(
    configuration: URLSessionConfiguration.default,
    serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
)

let provider = MoyaProvider<MyTarget>(manager: manager)
複製程式碼

plugins

最後您還可以向provider提供一個plugins陣列。 這些接收在傳送請求之前和接收到響應之後回撥。 有一些外掛已經包括:一個用於網路活動(NetworkActivityPlugin),一個用於記錄所有網路活動(NetworkLoggerPlugin),另一個用於HTTP驗證。 例如,您可以通過在Endpoint的plugins引數傳遞[NetworkLoggerPlugin()]來啟用logger plugin。 注意,外掛也可以是可配置的,例如已經包含的NetworkActivityPlugin需要一個networkActivityClosure引數。 可配置的外掛實現如下所示:

ublic final class NetworkActivityPlugin: PluginType {

    public typealias NetworkActivityClosure = (change: NetworkActivityChangeType) -> ()
    let networkActivityClosure: NetworkActivityClosure

    public init(networkActivityClosure: NetworkActivityClosure) {
        self.networkActivityClosure = networkActivityClosure
    }

    // MARK: Plugin

    /// Called by the provider as soon as the request is about to start
    public func willSend(request: RequestType, target: TargetType) {
        networkActivityClosure(change: .began)
    }

    /// Called by the provider as soon as a response arrives
    public func didReceive(data: Data?, statusCode: Int?, response: URLResponse?, error: ErrorType?, target: TargetType) {
        networkActivityClosure(change: .ended)
    }
}
複製程式碼

networkActivityClosure是一個閉包,您可以提供此閉包,以便在網路請求開始或結束時收到通知。 這對於使用網路活動指示器很有用。 注意這個閉包的簽名是(change:NetworkActivityChangeType) - >(),因此只有當請求有.began或.end時才會通知您 - 您不會被提供請求本身的任何其他詳細資訊。

Plugins功能翻譯

Moya外掛用於修改請求和響應或執行副作用。 呼叫一個外掛:

  • (prepare)在Moya已經將TargetType解析為URLRequest之後,這是在傳送請求之前修改請求的機會(例如新增頭)。
  • (willSend)在請求被髮送前,這是檢查請求並執行任何副作用(例如日誌記錄)的機會。
  • (didReceive)這是請求返回後,執行副作用的機會。
  • (process)在完成呼叫結果之前,這是對請求的結果進行任何修改的機會。

Built in plugins

Moya附帶一些預設外掛,可用於常用功能:身份驗證,網路活動指示燈管理和日誌記錄。在provider初始化的時候你可以簡單的宣告一個外掛:

let provider = MoyaProvider<GitHub>(plugins: [NetworkLoggerPlugin(verbose: true)])
複製程式碼

Authentication

認證外掛允許使用者為每個請求分配一個可選的URLCredential。 收到請求時沒有操作。 該外掛可以在Sources/Moya/Plugins/CredentialsPlugin.swift找到

Network Activity Indicator

iOS網路的一個常見任務是在網路請求期間顯示網路活動指示器,並在所有請求完成後將其刪除。provided外掛新增回撥,在請求開始和結束時呼叫回撥,可用於跟蹤正在進行的請求數,並相應地顯示/隱藏網路活動指示器。 該外掛可以在Sources/Moya/Plugins/NetworkActivityPlugin.swift找到

Logging

在開發期間,將網路活動記錄到控制檯非常有用。 這可以是從傳送和接收的請求的URL到記錄完整頭,方法,請求正文等任何東西。 provided的日誌外掛是最複雜的外掛,並且可以配置為適合您的應用程式(和構建型別)所需的日誌量。初始化外掛時,您可以選擇是否verbosity,是否記錄curl命令以及提供輸出資料的功能(如果您使用自己的日誌框架代替print),並在列印之前格式化資料(預設情況下,返回資料將用String.Encoding.utf8轉換為字串,但如果你想轉換為完美列印的JSON為你的響應,你可以傳入一個formatter函式,請參閱Demo/Shared/GitHubAPI.swift中的函式JSONResponseDataFormatter的一個例子) 該外掛可以在Sources/Moya/Plugins/NetworkLoggerPlugin.swift找到

Custom plugins

每次您需要在傳送請求之前和/或響應後立即執行一些程式碼,您可以建立一個自定義外掛,實現PluginType協議。 有關建立外掛的示例,請參閱docs/Examples/CustomPlugin.md and docs/Examples/AuthPlugin.md.

相關文章