解读Alamofire

作者: JasonWu | 来源:发表于2015-08-17 11:37 被阅读12530次

在开始介绍之前先明确一点,本篇写的不是关于Alamofire是怎么使用的,而是我仔细看了Alamofire框架代码后的一点感受与大家分享。写的不好也请大家见谅。如果是想要学习怎么使用的话还是建议直接阅读github上面的文档Alamofire documentation从基本到高级都讲解的很详细。

Alamofire

对于使用oc的同学来说一定十分熟悉AFNetworking这个框架,因为现在我们的app只要是有关于网络访问的部分大部分都会通过这个框架来进行网络的访问。而本篇要说的Alamofire就是swift版本的AFNetworking拉。所以Alamofire也是进行网络访问的框架。

整体架构

从github上下载Alamofire用Xcode打开可以看到如下的结构目录:

Alamofire目录

其中主要分为3部分:

  1. Alamofire.swift文件
  2. Core核心部分
  3. Features部分

我主要是分析Core部分的代码,而Features部分的代码我只会分析一部分,因为Features部分的代码是大同小异的只要理解了其中一部分的代码是怎么写的其他的只要在稍稍阅读下就可以了,当然每个部分的代码都有其精彩之处。希望大家有时间也可以自己再去阅读下大家多交流交流😊。

Alamofire.swift分析

在Alamofire.swift文件主要有两个功能:1. 提供了整个框架的入口。2. 向整个框架提供了方便的工具方法。

整个Alamofire.swift文件在内容上面也主要分成了两部分:
第一部分:


接口和convenience

在这一部分中主要是定义了两个Convertible协议和一个Convenience方法
两个个Convertible协议代码如下:

URLStringConvertible

这个协议是规定了其他类转化为URLString的方法从而可以使用这个来构造URLRequest。这么做得目的是将个各类的转化方法和方式分散到个各类中各自实现,就可以避免出现一大坨的转化方法,实现代码的美观。同理在接下来的URLRequestConvertible也是这个道理

URLRequestConvertible

接下来就是工具方法了

URLRequest

这个方法是用来构造NSURLRequest的简便方法,其中有一个参数就是URLStringConvitible类型的。所以如果我们自己的某个类也实现了URLStringConvertible协议也是可以通过这个方法构造NSURLRequest的。在有一个Method类型这个类型是


Method

定义在ParameterEncoding.swift文件中。

接下来就是提供了整个框架的入口方法,这里就先不做介绍等下面的Core部分懂了那么这部分就很自然的懂了

Core部分

在正式介绍整个核心部分之前,必须要有NSURLSession的基础知识,因为整个Alamofire框架其实是对NSURLSession进行封装的。如果对这一方面的只是缺乏还是建议先去补充一下,不然的话你会不知道接下来为什么要这么做。

在3个文件中总共是有Manager类、Request类和ParameterEncoding枚举类型。

Manager类:封装了NSURLSession以及相对应的代理方法
Request类: 封装了NSURLSessionTask以及Task的基本的代理方法
ParameterEncodeing:负责对HTTP请求的参数进行编码

框架总体流程是:


发送流程

这个是发送的流程,我们调用Alamofire.swift里的方法,而Alamofire里的方法其实是创建一个Manager调用Manager里的方法将得到的NSURLSessionTask封装成Request实例,发送并且返回Request实例。

得到回复时候的回调

在消息发送成功了,服务器处理好以后,需要将处理好的回复发送回来那么在发送回来的时候首先是调用了Manager的代理方法,然后在Manager中调用Request类的方法,最后才是掉用response方法和progress方法等。

那么在我们进行网络访问的时候一定不是只是发一个Request这么简单,而是有很多个Request那么在有回调的时候Manager是怎么知道是哪个Request的回调呢?那么接下来这就要求我们知道Manager里面是如果工作的。

Manager

先上Manager的图


Manager

属性:

session: NSURLSession类型发送请求并且得到NSURLSessionTask
delegate: session的代理
queue:实现session线程安全的队列
startRequestsImmediately:是否立刻发送请求
backgroundCompletionHandler:后台运行完成后的回调的closure

现在我们看以下Manager的request方法

request

在两个request方法中其中一request方法是先将参数封装成NSURLRequest在调用另一个重载的request方法,并且在封装成URLRequest的时候还对参数进行了编码。
我们的重点是在request(URLRequest:)这个方法这里。这个方法里面先是得到一个NSURLSessionTask然后将Task封装成Request,并将Request的delegate 存入自己的delegate的里面然后放回。
到这里为止Manager在将URLRequest封装成Request的时候就已经将Request的delegate存放到自己的delegate里面,好在后面的时候可以使用。

接下来就是Manage类里面的重头戏,session的代理。

SessionDelegate

先看SessionDelegate类的属性部分,但在此之前先跟大家提一下这个类是Manager的内部类,而且它的修饰符是final,这就意味着这个类是不可被继承的。那为什么是内部类呢?这里就留给大家好好体会😊
在SessionDelegate类里面有字典subdelegates这个就是在request里面用来存放request的delegate的。而下面的subdelegateQueue则是保证对字典的线程安全。在这里我们还注意到SessionDelegate还实现了subscript下标主要是为了存取方便,也顺便吧线程安全的操作一起写入。

同时,我们也可以注意到SessionDelegate实现了所有NSURLSession应该实现的所有协议NSURLSessionDelegate、NSURLSessionTaskDelegate、NSURLSessionDataDelegate和NSURLSessionDownloadDelegate。那么接下来我们看他是怎么实现的

NSURLSessionDelegate
因为太长了所以我只截取了NSURLSessionDelegate部分。大家可以注意到在这里主要有两大块一块是Override Closures部分,另一块是DelegateMethod部分,而且这两块是相互对应的。那么为什么这么做呢?因为可以让使用者对其中一些方法进行自定义同时也建议大家看看这篇文章更轻量的 View Controllers。每一部分Delegate都是以这种形式写的。所以Alamofire给使用者提供了很大的自定义的空间。
Request

同样的Request类在处理上面也是有内部来处理代理的主要结构入下图所示:


Request

在Request里面有两个代理,分别是TaskDelegate和DataTaskDelegate。同样都是内部类,那么为什么要这么分呢?那是因为NSURLSessionTask是有不同的类型的:

NSURLSessionUploadTask:上传任务类型
NSURLSessionDataTask:请求数据类型
NSURLSessionDownloadTask:下载类任务

而我们平常的GET、POST请求就是属于DataTask类型的。而每种类型的Task都有需要实现的协议UploadTask和DataTake所需要实现的协议是
NSURLSessionDataDelegate而DownloadTask所需要实现的协议是NSURLSessionDownloadDelegate。而不管是哪一种类型的Task都需要实现NSURLSessionTaskDelegate。所以在Request的内部类中TaskDelegate是实现了NSURLSessionTaskDelegate,DataTaskDelegate在继承了TaskDelegate的基础上实现了NSURLSessionDataDelegate。那么Download类型的呢?因为Download在一般的app中比Data出现的概率小,所以不应该出现在核心部分,所以Download是以扩展的形式在Features中Download.swift文件中实现的。
所以Request类的核心部分最主要的就是基础的TaskDelegate类是怎么实现的:

TaskDelegate

在TaskDelegate中我们最主要的是关注两个属性一个是task属性和queue属性。task 属性就是NSURLSessionTask类型,所以在这里我们知道Request吧基础Task封装到Delegate里面而外层的Request只是一个提供方便方法的外套而已。另外一个需要关注的属性queue是一个队列。而且大家注意到在队列初始化的时候吧队列的suspended属性设置为true,说明不希望队列里面的任务立刻执行。那么什么时候执行呢?我们直接跳到Delegate的代理方法

complete

在代理方法didCompleteWithError的时候将queue的suspended属性设置成false就是说明现在立刻运行。所到这里的时候我们就已经可以知道这个queue是存放这Request完成请求以后需要完成的东西。那么这个是什么东西呢?

Example

这个东西就是我们在使用Alamofire的时候所调用的.progress方法和response方法等等。在调用这两个方法的时候会将我们需要执行的代码打包成closure存入queue中等拿到了服务器的回复后在让queue运行存放在里面的closure。

所以到这里为止本篇文章的目的已经达到了。因为篇幅有限不可能面面俱到,只能向大家解释基本的流程。至于Features里面的内容大部分是Manager和Request的扩展。建议大家如果感兴趣的话,还是阅读源码比较好。

如果大家有什么不明白的可以问我,文章写的不好勿喷。

相关文章

  • Alamofire解读

    在开始讲解之前,先明确一点,这篇文章不会告诉大家怎么使用Alamofire,主要是自己将Alamofire解读后的...

  • 解读Alamofire

    在开始介绍之前先明确一点,本篇写的不是关于Alamofire是怎么使用的,而是我仔细看了Alamofire框架代码...

  • Alamofire源码解读

    Alamofire源码解读 AFNetworking的作者Matt Thompson 提出了一个新的类似AFNet...

  • Alamofire源码解读

    下方截图是Alamofire.swift中的一个几个便利方法,都是调用Manager单例中相应的方法,便利方法为了...

  • 【源码解读】Alamofire

    Alamofire是AFNetWorking在Swift中版本,其作用和地位就不多做介绍。本文主要记录下Alamo...

  • Alamofire(3)-Request解读

    前面一篇文章分析到了最上面的一层SessionManager,本篇开始分析一下里面的一层Request。 进入Se...

  • Alamofire Response源码解读

    前言 Alamofire设计了2种与Request相对应的Response类型,他们分别是: DefaultDat...

  • Swift开源库

    Network Alamofire:https://github.com/Alamofire/Alamofire ...

  • swift第三方库

    Alamofire https://github.com/Alamofire/Alamofire[http...

  • swift基础框架

    网络 Alamofire[https://github.com/Alamofire/Alamofire]:http...

网友评论

  • 我是派蒙:哥 ,请问这个地址http://220.163.112.195:11009/jeeyczmq/AppLoginSp.do?checkuser&userName=linyu&password=123456,参数要怎么拼?我们还在用.do的后缀接口,userName=linyu&password=123456是参数 ,post和get怎么拼参数,难道只有我一个人用了.do接口,后台拿不到数据吗? 我是小白,求解答啊 要疯了。
  • smkoc:这个框架 写的不错,当作学习swift的模版bi jiao hao
  • specter_hhg:请问,Alamofire它需要去申请消费者密钥 (cunsumer key),有点类似于三方SDK的key,相对于AFNetworking,它增加了什么权限还是功能? 为什么必须去申请这个而AFNetworking不用?这个的作用是什么的?
  • 巴图鲁:不错
  • BeyondChao:不错的文章
  • 我______:有没有一个实例看看,我初学swift不太会用这个在进行二次封装
  • MetaZZZZ:好文章
  • csxfno21:内部类TaskDelegate的定义是这样的,public class TaskDelegate: NSObject { },这个类并没有符合NSSessionTaskDelegate的协议,为什么就能实现NSSessionTaskDelegate方法呢?要使某个类实现协议,不应该是向下面这样定义的么public class TaskDelegate: NSObject,NSSessionTaskDelegate { }
  • iBaron:我想问下,那网络超时怎么设置?设置好了之后怎么调用?我试了一下,设置超时后,无法返回数据,没有设置超时是可以正常返回的

    var alamofireManager : Alamofire.Manager?
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.timeoutIntervalForResource = 2 // seconds

    alamofireManager = Alamofire.Manager(configuration: configuration)
    alamofireManager!.request(.GET, url + getJson(jsonId)!)
    .response { (request, response, data, error) in
    print(request?.HTTPBody)

    print(response)

    print(data)
    let alert = UIAlertController(title: "温馨提醒", message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
    let action = UIAlertAction(title: "确定", style: UIAlertActionStyle.Default, handler: nil)
    alert.addAction(action)
    self.presentViewController(alert, animated: true, completion: nil)
    }
    只有NO1:alamofireManager必须设置成全局的
    Yoon__:@iBaron 请问你解决了没有,我也有这个疑问,只要通过这个方法初始化Manager(configuration: configuration)就访问不成功,报错:NSURLErrorDomain Code=-999 "cancelled"
  • 彭挺:能更新下么, 在xcode7 无法使用

    谢啦
    JasonWu:@彭挺 对不起了,因为工作原因不能及时回复。当时在 Xcode7 下无法使用是因为 swift 语法更新了,现在 Alamofire 早就已经更新到了最新的 swift 语法,虽然语法变了但是主要的逻辑和流程都还是不变的
  • Seizens_Swift:求解怎么实现图片的上传?
    JasonWu:@肉汁萝卜 用NSData传的话是需要和服务器约定好的。可以方便看下代码吗?
    972648b1ca6d:@JasonWu 之前试过用NSData传图片,发现不能用, 只能用fileURL的方式传图,data传其他信息,目前还不知道为什么,也可能用调用方法有问题。。
    JasonWu:@为你撑伞 在Alamofire中上传图片有两种方法一种是Upload还有一种是MultipartFormData,两种方法都是向HTTP请求的body里面放数据,但是upload是一次只能是一个文件,而MultipartFormData是可以一次多个文件的上传。他们的本质都是将文件用NSData表示,添加到HTTPbody里面,然后将回调的函数封装成closure放入Request的delegate的queue里面等待调用的

本文标题:解读Alamofire

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