XMNetworking源码阅读学习

闲话不说了,今天来学习XcodeMen team的轻量级网络库XMNetworking

前阵子看源码的时候,还是有点懵逼,自动昨天自己画了思维导图,对网络层的结构分析了一下,今天再来看,发现就豁然开朗了,感觉挺好的

XMConst 文件

一个定义全局文件变量文件,用结构体定义了上传、下载、普通三种请求方式,6种请求方法,3种请求序列化的方式,4种回应序列化的方式,三大类请求block(单个请求、批量请求、链式请求)以及一个用来对请求回应做处理的通用block,这应该都是好理解的。

XMRequest

XMRequest文件定义了XMRequest、XMBatchRequest、XMChainRequest、XMUploadFormData四个类。

XMRequest 主要是提供请求的配置信息,也就是请求方法、头部、URL、请求和回应序列化方式、超时时间等,还有另外几个 readonly 修饰的block类型属性,这几个block会在请求落地时候调用并返回业务数据。还有用语上传数据的 uploadFormDatas 属性,这个属性规定了数组里的对象必须是uploadFormDatas 对象。还提供了几个快速添加 uploadFormData的方法

XMBatchRequest、XMChainRequest 并没有使用继承的方式,而是采用了组合。这两个请求类通过持有XMRequest 对象作为属性来获得XMRequest对象的特征,同时又可以自己衍生自己的特性。

XMUploadFormData为上传请求的数据对象,并提供了多个类方法来创建新对象
整体来说,XMRequest文件提供的都是请求起飞的配置。

XMCenter

XMCenter文件定义了两个类,分别是XMCenter和XMConfig。
XMConfig类是XMCenter的配置类,而这些XMCenter配置信息,又被间接提供到了request手里。

XMCenter类是整个框架的核心类,并且是个单例类。将通过请求的流程来分析源码。
1、 - (void)setupConfig:(void(^)(XMConfig *config))block;
方法提供的config对象完成XMCenter的基本配置信息,这样XMCenter单例对象将能直接使用这些配置。
2、 - (void)setResponseProcessBlock:(XMCenterResponseProcessBlock)block;
这个方法将用来处理返回的response,注意,这个block会在返回成功之前调用,我们可以通过这个block来处理请求成功,但是业务出现错误的情况,并且创建一个NSError实例传递给block,这样在回调的block中,就直接走 FailureBlock,而不走SuccessBlock。也就是劫持response,主动改变response走向。
3、接下来就是一连串的便利请求发起方法,但这些请求发起方法的下一层,就是参数最后的那个方法,也就是这个

- (NSUInteger)sendRequest:(XMRequestConfigBlock)configBlock
           onProgress:(nullable XMProgressBlock)progressBlock
            onSuccess:(nullable XMSuccessBlock)successBlock
            onFailure:(nullable XMFailureBlock)failureBlock
           onFinished:(nullable XMFinishedBlock)finishedBlock;

其余调起请求的方法,只是在这个方法上封装了一层,并且固定了一些参数,所以叫做便利方法。这个方法的实现如下

    XMRequest *request = [XMRequest request];
    XM_SAFE_BLOCK(configBlock, request);
    [self xm_processRequest:request onProgress:progressBlock onSuccess:successBlock onFailure:failureBlock onFinished:finishedBlock];
    return [self xm_sendRequest:request];

这个方法的实现了,生成了一个XMRequest实例request,并且通过XM_SAFE_BLOCK(configBlock, request);调用configBlock(这个是request的配置block,不要别错看成XMcenter),将调起这个接口时候,配置的request信息(接口名字、请求方法、参数等),填充到这request实例上来。
4、再接下来就是通过为接口调起时配置的request做修饰,可能是新的参数、Header,URL等这些。
5、处理完了request,那就是带着request起飞了,也就是这个方法:
- (NSUInteger)xm_sendRequest:(XMRequest *)request 这个方法的实现,将调用另外 XMEngine 来实现真正的起飞。并且通过block来接收回调处理。返回值将和对应的请求task相互绑定,用于取消请求的操作。
6、回调方法有成功和失败两种。但在执行回调时候,是在一个私有线程,也就是XCenter自己的线程种callbackQueue。并且失败的回调还有机会再次让request起飞。
7、回调函数之行完成之后,就需要清理回调的block,回调的block是和request成员,所有需要调用request的 - (void)cleanCallbackBlocks方法,置空与回调相关block(successBlock ;failureBlock ; finishedBlock ;progressBlock 。
8、链式请求和批量请求,过程都差不多,只在请求发起时候稍有差别。

整个流程差不多这样了,在看看代码,应该是没问题了。并且,作者的注释本来还有使用方法也写得很清楚了。

XMEngine

XMEngine是请求的发起者,它的下层是依赖于AFNetworking。并且,也是一个单例类。
这里应该是延续上面的第5步操作:
5.1 XMEngine对象拿到request对象,通过request的属性,确认请求方式是上传、下载还是普通请求、请求方法、序列化方式、超时时间、业务参数以及全局参数(Header、agent等),并使用AFHTTPRequestSerializer 的实例对象 生成NSMutableURLRequest类型的URLRequest。如果出现序列化失败,那么将会直接进入失败的回调函数中。(作者这里处理序列化失败回调时候,使用了一个异步线程)
5.2 调用AFNetkworking 的sessionManager 并且请求飞起来。这其中,通过objc的runtime的 关联对象方法OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) 给起飞的请求task将request绑定到了task,算是添加了一个属性吧。
5.3 通过task的identifier,从sessionManager的tasks数组中,找到对应identifier的task,进行改任务的取消操作。这个过程,这这通过 信号量(dispatch_semaphore_...)机制做了线程安全的处理。

总结

对这个轻量级的网络框架分析就差不多这样了,总结一下自己对这个框架的认识:
1、这个框架属于集中型的设计,请求都是通过XMCenter进行调度
2、大量使用了block(简直废话),所以有时候看起来的确有点跳,习惯就好了
3、框架也是组织request,request起飞,response落地三步走,所以从这个方向去理解,就容易多了
4、感谢作者的贡献,看源码还是好处多多,学习了!
5、有理解错误的地方,欢迎指正

你可能感兴趣的:(XMNetworking源码阅读学习)