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

2,934 阅读3分钟

往期导航:

Alamofire源码学习目录合集

简介

  • URLConvertible协议定义了可以将任意对象转换为URL对象,在创建URLRequest时使用
  • URLRequestConvertible协议定义了可以将任意对象转换为URLRequest对象,在创建Request对象时使用
    这两个协议抽象了URL与URLRequest,使得创建请求时不再局限于必须使用这两个对象来初始化,可以使用任意符合两个协议的对象即可,方便上层封装解耦。

URLConvertible协议

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

public protocol URLConvertible {
    func asURL() throws -> URL
}

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

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

自定义使用

若需要自定义创建url的规则(host,统一路径,基于不同接口的不同路径等需求)可以自己实现类/结构体,然后遵循该协议,返回自定义拼接的url即可

URLRequestConvertible协议

该协议类似URLConvertible,也是只有一个方法,不过生成的是URLRequest对象。也可以抛出错误。

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

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

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

extension URLRequest: URLRequestConvertible {
    public func asURLRequest() throws -> URLRequest { self }
}

自定义使用

类似于URLConvertible,需要自己创建URLRequest对象的话,

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

  • HTTPMethod -> 请求方法
  • HTTPHeaders+HTTPHeader -> 请求头
  • URLConvertible -> 请求地址 使用三个自定义类型来创建URLRequest,也能方便管理与扩展,因此扩展了URLRequest对象,添加了使用这三个类型来初始化的方法,方法允许抛出错误,抛出错误时返回创建请求失败的错误。

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,很好玩~有兴趣的可以看看。