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
联系方式: [email protected]
|
请发表评论