您的位置:首页 > 理论基础 > 计算机网络

Swift网络封装库Moya中文手册之Endpoints

2016-06-30 20:41 351 查看

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。

创建一个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: