美文网首页iOS 专题iOS Developer
【swift源码阅读】Alamofire-Part2:Sessi

【swift源码阅读】Alamofire-Part2:Sessi

作者: PolarCat | 来源:发表于2017-01-16 11:16 被阅读193次

    Alamofire推荐给开发者的调用层是位于source文件夹下最外层的Alamofire.swift文件,我们先从这里开始。

    入口文件目录位置

    文件最开始的地方定义了一个URLConvertible的协议,里面只有一个asURL方法,返回一个URL类型。后面可以看到对String,URL和URLComponents都做了URLConvertible的拓展。以下以String类型的拓展为例:

    对String类型的URLConvertible拓展

    可以看出这个方法只是利用对象自身来生成可用的URL,利用协议这种做法是为了实现多态。

    查看文件的属性定义可以看到,下面还有一个URLRequestConvertible协议,定义了一个用来返回URLRequest的asURLRequest函数,由URLRequest实现拓展。这个的目的与URLConvertible一样,就不细说了。

    Alamofire.swift中的协议与拓展

    在URLRequestConvertible下面还有一个URLRequest的拓展,这里要注意一下。

    URLRequest拓展

    这个拓展中新定义了一个初始化方法,真正需要注意的是第二个adapt函数,这个函数给予了开发者自己自己配置request的接口。adapter函数接收一个RequestAdapter的对象,RequestAdapter实际上是一个协议,这里就不截图了,RequestAdapter在协议中定义了一个adapter函数,这个函数接收一个URLRequest对象,返回一个URLRequest对象。

    当我们想实现自定义的request的时候,传入一个实现了RequestAdapter拓展的对象即可。

    接下来就是功能性的函数了,也是使用Alamofire主要调用的函数,但是往下一看,你会发现这些函数全是这种画风:

    这里我们终于讲到本文的重点了————SessionManager!

    SessionManager是真正的管理者,所有Alamofire的外部调用都是调用SessionManager里的方法。接下里我们看一下SessionManager.swift文件里的内容。

    首先SessionManager里面定义了一个静态的default实例,进行了configuration以及headers的一些基本定义。如果想对headers在原有基础上进行一些拓展的话,直接在这个文件里的defaultHTTPHeaders里面添加就可以了。

    Alamofire的调用,实际上都是对SessionManager里的default实例的调用。

    SessionManager里还有很多其他属性以及初始化方法,这里都暂且不表,其中有一些后面有涉及的时候会讲解,有兴趣的朋友可以去看一下。这里我们直接把目光锁定在实例方法上。SessionManager主要有三套方法:request, download以及upload。

    request

    根据前一章NSURLSession基础,我们知道,所有的利用URLSession进行网络请求的本质是启动URLSessionTask。所以可以看到所有的方法最后都会走到DataRequest.resume()。request系列函数共有两个公有函数,如下。

    request公有函数

    可以看出,第一个request方法,实际上是对request(_ urlRequest:URLRequestConvertible)的二次封装,利用调用者传入的参数生成URLRequest后,调用request(_ urlRequest:URLRequestConvertible)。

    DataRequest.Requestable是定义在DataRequest中的一个结构体,这个机构体拥有一个URLRequest变量和一个返回URLSessionTask的task函数。

    于是我们可以看出,在request(_ urlRequest:URLRequestConvertible)中,先利用传入的参数生成task,再利用这个task生成request,将这个request加入到SessionDelegate中,然后检查startRequestsImmediately变量(默认为true),如果为true,调用request.resume()启动请求。

    这里有人可能有疑惑了,既然传入的参数调用asURLRequest方法时就已经返回了一个request,为什么还要用task重新生成一个呢?为什么是由request调用resume函数而不是task呢?

    我们先来看一下用task生成request的函数定义,这个函数定义在Request类中,是Alamofire中所有request的总基类。

    从上图可以看出,利用这个函数生成的request根据传入的task初始化了taskDelegate。只有这种request加入sessionDelegate才有意义,可以通过sessionDelegate来处理请求的回调。这也是为什么要用task重新生成一个request来加入delegate的原因。

    那么为什么用request来调用resume而不是task呢?

    实际上request是没有resume函数的,这里的resume是被封装在Request中的自定义函数。

    自定义的resume函数

    在resume函数中会检查request的task是否被挂起,如果没有就调用task的resume函数。这里比较有意思的是任务开启后会发送一个通知,但你会发现在Alamofire中没有任何地方接收这个通知,这个通知其实是发送给第三方调用者的。如果你有任务开启后要马上执行的动作,你就可以在代码中接收这个通知。在Alamofire的高级使用中我们会讲到这里。

    关于Request和SessionDelegate的代码,我们会在以后进行阅读。下一篇将讲解SessionManager中的upload与download方法。

    相关文章

      网友评论

        本文标题:【swift源码阅读】Alamofire-Part2:Sessi

        本文链接:https://www.haomeiwen.com/subject/ycicbttx.html