Alamofire源码学习(八): URLConvertible与URLRequestConvertible

往期导航:

Alamofire源码学习目录合集git

简介

  • URLConvertible协议定义了能够将任意对象转换为URL对象,在建立URLRequest时使用
  • URLRequestConvertible协议定义了能够将任意对象转换为URLRequest对象,在建立Request对象时使用

这两个协议抽象了URL与URLRequest,使得建立请求时再也不局限于必须使用这两个对象来初始化,可使用任意符合两个协议的对象便可,方便上层封装解耦。github

URLConvertible协议

协议很简单,只有一个方法,遵循该协议的对象只须要实现一个方法,生成一个URL便可。而且该方法能够抛出异常,抛出异常时,Alamofire会中止请求并返回AFError.invalidURL的错误。swift

public protocol URLConvertible {
    func asURL() throws -> URL
}
复制代码

Alamofire内部定义遵循该协议的对象:

  • String:返回URL(string: self),为空时抛出错误
  • URL:返回自身,不会抛出错误
  • URLComponents:返回self.url,为空时抛出错误

自定义使用

若须要自定义建立url的规则(host,统一路径,基于不一样接口的不一样路径等需求)能够本身实现类/结构体,而后遵循该协议,返回自定义拼接的url便可api

URLRequestConvertible协议

该协议相似URLConvertible,也是只有一个方法,不过生成的是URLRequest对象。也能够抛出错误。markdown

public protocol URLRequestConvertible {
    func asURLRequest() throws -> URLRequest
}
//另外扩展了一下协议,添加了一个计算属性,能够快速获取URLRequest,返回的是个可选值,若是抛出错误,会忽略错误并返回nil:
extension URLRequestConvertible {
    public var urlRequest: URLRequest? { try? asURLRequest() }
}
复制代码

Alamofire内部定义遵循该协议的对象

只有URLRequest对象实现了该协议,返回自身:ide

extension URLRequest: URLRequestConvertible {
    public func asURLRequest() throws -> URLRequest { self }
}
复制代码

自定义使用

相似于URLConvertible,须要本身建立URLRequest对象的话,oop

Alamofire中使用自定义封装的类型建立URLRequest

  • HTTPMethod -> 请求方法
  • HTTPHeaders+HTTPHeader -> 请求头
  • URLConvertible -> 请求地址

使用三个自定义类型来建立URLRequest,也能方便管理与扩展,所以扩展了URLRequest对象,添加了使用这三个类型来初始化的方法,方法容许抛出错误,抛出错误时返回建立请求失败的错误。post

extension URLRequest {
    public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws {
        let url = try url.asURL()

        self.init(url: url)

        httpMethod = method.rawValue
        allHTTPHeaderFields = headers?.dictionary
    }
}
复制代码

总结

这两个协议,通常是须要对Alamofire进行二次封装(符合本身的业务逻辑需求)时会用到,对一些通用数据进行封装,以及一些须要针对业务需求进行变动的数据进行处理。推荐一个基于Alamofire进行二次封装的很棒的库:Moya,github上12k+的星星,对Alamofire进行了二次封装,把请求头,请求参数,请求类型等业务相关的部分抽象成Provider协议,方便实现管理各类本身的api。并且还支持Rx,很好玩~有兴趣的能够看看。学习