zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    『轉』数据类型 双字节字符类型 wchar_t
    数据库连接
    12种方法返回2个文件路径之间的公共基路径ExtractBasePath
    cxgrid删除应用过滤后的行
    如何赛筛选出多列内容相同的数据??
    如何知道是哪个进程造成死锁?如何把这个进程杀掉?
    数据库中查询某表是否存在
    Delphi中解决MDI的DLL子窗体中的Tab键下移控件问题
    Delphi中闪动应用程序在任务栏的标题
    SQL语句如何更改重复的记录
  • 原文地址:https://www.cnblogs.com/liuliuliu/p/5627944.html
Copyright © 2011-2022 走看看