Swift網絡封裝庫Moya中文手冊之Endpoints


Endpoints

Endpoint是一種半私有的數據結構,Moya用來解釋網絡請求的根本構成。一個endpoint儲存了以下數據:

  • The URL.
  • The HTTP method (GET,POST,等).
  • The request parameters.
  • The parameter encoding (URL,JSON,自定義,等).
  • The HTTP request header fields.
  • The sample response (單元測試用).

ProvidersTargets 映射為Endpoints,然后將Endpoints映射為實際的網絡請求。

有兩種方式使用Endpoints。

  1. 創建一個provider的時候,可以定義一個Target到Endpoint的映射。
  2. 創建一個provider的時候,可以定義一個Endpoint到 NSURLRequest的映射。

第一種方式如下:

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
    return Endpoint(URL: url, sampleResponseClosure: {.NetworkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
}

這其實是Moya provides的默認實現。如果你需要自定義,比如你的API需要自定義參數mapping,或者在單元測試中創建一個返回非200 HTTP statuses的測試provider,可以在這里實現。

第二種方式很少使用。Moya希望使用者盡量不用關注底層實現的細節。但如果你需要, 請接着往下看。

讓我們看看一個從Target到Endpoint的可變映射的示例。

From Target to Endpoint

默認情況,Endpoint 實例使用 .URL 類型的參數編碼。如果需要其他編碼方式,可以在配置provider時,用 Endpoint 的可選參數 parameterEncoding 來初始化你的endpointClosure

這里有四種編碼類型:.URL.JSON.PropertyList.Custom,可以直接解析成Alamofire可用的類型。這些也可以在provider的 endpointClosure 中配置。通常你只會用到 .URL,但也可以使用任何你需要的。這是直接解析為 Alamofire parameter encodings

你可以在閉包里為HTTP頭文件添加參數。例如,我們可能想要在HTTP頭文件中設置"APP_NAME"以便服務器端解析。

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
    let endpoint: Endpoint<MyTarget> = Endpoint<MyTarget>(URL: url, sampleResponseClosure: {.NetworkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
    return endpoint.endpointByAddingHTTPHeaderFields(["APP_NAME": "MY_AWESOME_APP"])
}

這也意味着你可以為部分或全部endpoints提供附加參數。例如,我們需要給所有MyTarget 類型的 target添加認證token,但不包括用來進行認證的target。這就需要構造一個如下的 endpointClosure

let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
    let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
    let endpoint: Endpoint<MyTarget> = Endpoint<MyTarget>(URL: url, sampleResponseClosure: {.NetworkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)

    // Sign all non-authenticating requests
    switch target {
    case .Authenticate:
        return endpoint
    default:
        return endpoint.endpointByAddingHTTPHeaderFields(["AUTHENTICATION_TOKEN": GlobalAppStorage.authToken])
    }
}

注:我們可以在Moya現有的方法上進行擴展,endpointByAddingParametersendpointByAddingHTTPHeaderFields 允許你利用Moya現有的代碼添加自定義value。

Sample responses是 TargetType 協議所必須的。然而,這只是定義了返回數據。Target-to-Endpoint映射閉包可以定義更多細節,在單元測試時非常有用。

Sample responses返回下面二者之一:

  • NetworkResponse,包含一個 Int 類型的status code 和NSData 類型的返回數據。
  • NetworkError,包含一個 NSError? 類型的error。

Request Mapping

我們最初就提到,這個庫不是一個封裝網絡請求的第三方庫 - 那是Alamofire干的事。事實上,Moya是一種封裝網絡訪問的方式,並提供編譯時檢查已經定義的targets。你已經知道怎樣在MoyaProvider 的初始化中用 endpointClosure 把targets映射為endpoints。Moya會根據你創建的 Endpoint 實例來推動API請求。某些情況,Endpoint 必須要解析為 NSURLRequest 提供給Alamofire,這也就是 requestClosure 的作用。

requestClosure 是可選的,是修改request的根本辦法。MoyaProvider.DefaultRequestMapper 使用 EndpointurlRequest 屬性作為默認值。

這個閉包接受一個 Endpoint 作為參數,以及一個NSURLRequest -> Void ,在這里可以完成OAuth認證或其他事情。你想異步的調用這個閉包的時候,也可以使用第三方庫認證 (example)。不需要修改request的話,可以單純的log。

let requestClosure = { (endpoint: Endpoint<GitHub>, done: NSURLRequest -> Void) in
    let request = endpoint.urlRequest

    // Modify the request however you like.

    done(request)
}
provider = MoyaProvider<GitHub>(requestClosure: requestClosure)

requestClosure 在修改 NSURLRequest 屬性時很好用,或者提供一些請求創建之前不知道的信息,例如cookies設置。請注意前面提到的 endpointClosure 不能實現這種應用層的特定請求。

這個屬性對於修改request對象非常有用,NSURLRequest 可以自定義很多屬性,例如你想讓禁用所有cookies:

{ (endpoint: Endpoint<ArtsyAPI>) -> (NSURLRequest) in
    let request: NSMutableURLRequest = endpoint.urlRequest.mutableCopy() as NSMutableURLRequest
    request.HTTPShouldHandleCookies = false
    return request
}

你也在請求送達之前調用這個閉包來可以打印網絡請求。

轉載請注明出處http://www.cnblogs.com/liuliuliu/p/5627944.html,並注明轉載。

原文鏈接
翻譯: bibibi_liuliu
聯系方式: 395985239@qq.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM