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 (單元測試用).
Providers 將 Targets 映射為Endpoints,然后將Endpoints映射為實際的網絡請求。
有兩種方式使用Endpoints。
- 創建一個provider的時候,可以定義一個Target到Endpoint的映射。
- 創建一個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現有的方法上進行擴展,endpointByAddingParameters 和 endpointByAddingHTTPHeaderFields 允許你利用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 使用 Endpoint 的 urlRequest 屬性作為默認值。
這個閉包接受一個 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
