AFNetwork 3.0 结构及功能介绍

AFNdemo加注释

AFN结构
1.通讯核心类
    1.1 AFURLSessionManager
    1.2 AFHTTPSessionManager 继承于1.1

2.序列化类
    2.1:AFURLRequestSerialization
        2.1.1:AFHTTPRequestSerializer
        2.1.2::AFJSONRequestSerializer
        2.1.3 AFPropertyListRequestSerlizer
    2.2AFURLResponseSerialization
        2.2.1AFHTTPResponseSerialization
        2.2.2AFJSONResponseSerialization
        2.2.3AFXMLParserResponseSerialization
        2.2.4AFXMLDocumentResponseSerialization(macOS)
        2.2.5AFPropertyListResponseSerialization
        2.2.6AFImageResponseSerialization
        2.2.7AFCompoundResponseSerialization
3,辅助类
    3.1AFSecurityPolicy    用于处理网络安全处理策略
    3.2AFNetworkReachabilityManager   网络状态监控

4.UIKit


https://github.com/AFNetworking/AFNetworking        git地址
查看issues  项,使用库中出现问题


NSURLSession 流程
1.创建NSURLSessionConfig 对象
2.用之前创建NSURLSessionConfig对象配置NSURLSession对象
3.用NSURLSession对象创建对应的task对象(每一个请求就是一个task) ,并用resume方法执行
4.用delegate方法 (系统有delegate 返回有AFN封装为block)或completion block 响应网络事件及数据

1. AFURLSessionManager
    1.1 [AFURLSessionManager  manager]
        1.1.1 类方法,不是单利,工厂方法
        1.1.2- (instancetype)initWithBaseURL:(NSURL *)url
           sessionConfiguration:(NSURLSessionConfiguration *)configuration
            1.1.2.1 调用父类的初始化方法 
                configuration  配置是否请求缓存,请求延时时间,允许蜂窝请求,网络请求类型
                operationQueue  自定义的queue决定取消,挂起,继续的主队列
                session :初始化的session 就是这次请求的网络会话绑定task
                AFSecuityPolicy defaultPolicy  无条件信任证书https 认证
                ReachablityManager 网络监控
                lock 保证线程安全
            1.1.2.2 给url 添加”/”保证不会进行二次重定向请求
            1.1.2.3 给requestSerializer(userAgent,Accept-Language 等)、responseSerializer(stringEncoding=NSUTF8StringEncoding) 设置默认值 :
        1.1.3 走默认的manage,是没有对configuation进行处理的,取的是默认值
        1.1.4 manage管理Session, session 会产生不止一个Task
             AFN根据系统给代理提供管理progress 和data 的序列化
            Manage 管理不需要处理的杂事

    1.2  Manage Get
        1.2.1 data TaskWithHttpMethod
            1.2.1.1  NSMutableURLRequest  参数处理, get和post 
            1.2.1.2 dataTask  对SessionDataTaskWithRequest :request处理
            1.2.1.3 task 持有delegate  使用id进行绑定
            1.2..1.4 failure /success block回调
    1.3  [dataTask resume]重写resume 为af_resume 来记录状态

2. 序列化:AFURLRequestSerialization请求 AFURLResponseSerialization响应
    2.1 AFURLRequestSerialization
        2.1.1 request 的产生方式
            2.1.1普通方式:使用指定的HTTP method 和 URLString来构建一个NSMutableURLRequest 对象实例
/**
 使用指定的HTTP method和URLString来构建一个NSMutableURLRequest对象实例
 如果method是GET、HEAD、DELETE,那parameter将会被用来构建一个基于url编码的查询字符串(query url)
 ,并且这个字符串会直接加到request的url后面。对于其他的Method,比如POST/PUT,它们会根
 据parameterEncoding属性进行编码,而后加到request的http body上。
 @param method request的HTTP methodt,比如 `GET`, `POST`, `PUT`, or `DELETE`. 该参数不能为空
 @param URLString 用来创建request的URL
 @param parameters 既可以对method为GET的request设置一个查询字符串(query string),也可以设置到request的HTTP body上
 @param error 构建request时发生的错误
 @return  一个NSMutableURLRequest的对象
 */
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                 URLString:(NSString *)URLString
                                parameters:(id)parameters
                                     error:(NSError *__autoreleasing *)error

            2.1.2构建一个mutipartForm 的request
//构建一个multipartForm的request。并且通过`AFMultipartFormData`类型的formData来构建请求体
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
                                              URLString:(NSString *)URLString
                                             parameters:(NSDictionary *)parameters
                              constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                                                  error:(NSError *__autoreleasing *)error

            2.1.3通过一个Mutipart-From 的request 创建一个普通的request
/*
 通过一个Multipart-Form的request创建一个request。新request的httpBody是`fileURL`指定的文件。
 并且是通过`HTTPBodyStream`这个属性添加,`HTTPBodyStream`属性的数据会自动添加为httpBody
 */
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
                             writingStreamContentsToFile:(NSURL *)fileURL
                                       completionHandler:(void (^)(NSError *error))handler
        2.2 body
            2.2.1 httpBody
            2.2.2 httpBodyStream

        2.3 request 注意点
            2.3.1 组成:请求行+请求头+请求体
            2.3.2 请求拼接  appendPartWithFormData  把参数,请求头,请求体当成一个part
                2.3.2.1 做成这样的头
                    [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"];    
                2.3.2.2 data
                2.3.2.3AFHTTPBodyPart  “header +data+boundary +bodyContentLength+stringEncodeing
                2.3.2.4 最终存到bodyStream
                2.3.2.5 在我们request 的时候 request.HTTPBodyStream=bodyStream
            2.3.3 content的长度计算
            2.3.4 boundary 头部的+ 中间的+ 结尾的
            2.3.5 setHasInitalBoundary
            2.3.6 stream 的open  是在resume 调起task    会触发- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length
    2.2 AFURLResponseSerialization - AFHTTPResponseSerializer
        2.2.1 重要方法 validateResponse  验证内容 +验证状态码
        2.2.2 重要属性 acceptableContentTypes  不包含MIMEType 就会报 -1016错误,acceptableStatusCode   200-299
        2.2.3 子类
            2.2.3.1AFJSONResponseSerialization   AFJSONObjectByRemovingKeysWithNullValues 是否去掉为null的返回值,依赖于是否设置removesKeyWithNullValue
            2.2.3.2AFXMLParserResponseSerialization   xml 解析
            2.2.3.3AFXMLDocumentResponseSerialization(macOS) 
            2.2.3.4AFPropertyListResponseSerialization   NSpropertyListSerialization properListData
            2.2.3.5AFImageResponseSerialization       automaticallyInflatesResponseImage 是否解压
                2.2.3.5.1 AFInflatedImageFromResponseWithDataAtScale iOS需要手动解压图片
                    区分PNG JPG  不能支持cmyk 转为位图
                     AFImageWithDataAtScale创建原格式图片
                    确定 Width height bitsPerComponent 图片的位数
                    过大 不处理直接返回原格式
                    alpha通道进行相应处理
                    画布进行绘制图片
                2.2.3.5.2 AFImageWithDataAtScale 使用af_safeImageWithData获取image
            2.2.3.6AFCompoundResponseSerialization responseSerializers包含多种格式的解析 此功能比较耗性能
    2.3
NSURLRequestCachePolicy  缓存策略
默认缓存策略,如果一个NSCachedURLResponse 对于请求不存在秘书局将会从源端获取,如果请求拥有一个缓存响应,
那么URL加载系统会检查这个响应决定,如果它置顶内容必须重新生效的话,加入内容必须重新生效,将简历一个连向源端
的连接来查看内容是否发生变化。加入内容没有变化,那么像一个就从本地缓存返回数据。如果内容变了,那么数据从远端获取

 NSURLRequestUseProtocolCachePolicy = 0,

URL应该加载源端数据,不使用本地缓存数据
 NSURLRequestReloadIgnoringLocalCacheData = 1,

本地缓存数据。代理和其他中介都要忽视他们的缓存,直接加载源数据
 NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4,

 NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,

置顶已存的缓存数据应该用来响应请求,不管他的生命时长和过期时间。如果在缓存中没有依存数据来响应请求的话,数据从远端加载
 NSURLRequestReturnCacheDataElseLoad = 2,

置顶已存的缓存数据用来满足请求,不管生命市场和过期时间。如果在缓存中没有已存在的数据来响应URL加载请求的话,不用尝试从源端
加载数据,此时认为加载请求失败。这个常量制定了一个类似于离线模式的行为
 NSURLRequestReturnCacheDataDontLoad = 3,

置顶如果已存的缓存数据呗提供它的源端,认为有效则允许使用缓存数据响应请求否则从源端加载数据
 NSURLRequestReloadRevalidatingCacheData = 5,

request  :请求行 +请求头  +请求体
请求行封装    mutableRequest.HTTPMethod = method; //设置请求方式(get、post、put。。。)
请求头封装    mutableObservedChangedKeyPaths 集合中,通过响应式变成,使用KVO 并关闭自动触发,进行手动触发消息
请求体封装

交换方法resume  为af_resume  其中发了通知,保存状态


普通Post  的content_type
  if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
            [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        }

上传图片的:
    [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"];


AF提供序列化  json, (一般使用) xml(智能家居)  image(视频流,直播等)  propteList
    
    


3AFSecurityPolicy    
    3.1.如果是CA证书,一切都不需要操作
    3.2.如果公司是自签证书,就需要操作
    3.3.具体操作
        3.3.1 配置响应的3AFSecurityPolicy     
            3.3.1.1 AFSSLPinningModeCertificate
            3.3.1.2 securityPolicy.allowInvalidCertificates = YES
            3.3.1.3 securityPolicy.validatesDomainName = NO
        
    3.4流程分析
        3.4.1 公钥集合手机
        3.4.2AFN收到身份质询
            3.4.2.1. - (void)URLSession:didReceiveChallenge: completionHandler:
            3.4.2.2 是否验证服务器证书
            3.4.2.3 是否验证域名? 是,创建SecpolicyCreateSSL  否,创建SecPolicyCreateBasicX509
        3.4.3 评估指定证书和策略的信任度:AFServerTrustlsValid 
             : KSecTrustResultUnspecifed
            :KSecTrustResultProceed
        3.4.4证书评估通过,继续判断PinningModde
            AFSSLPinningModeNone 无条件信任,不允许,返回NO
            AFSSLPinningModeCertflcate  对比服务器证书和本地证书
            ADSSLPinningModePublicKey  对比服务器证书和本地证书公钥
            是否包含公钥        
    
4. AFNetworkReachabilityManager
方向:
    1. 监听对象: 域名  地址  —>传输层
    2.监听状态: 网络状态
    3.开始/结束:控制
    4.设置回调
源码:AFNetworkReachabilityManager
    1.初始化 manage  底层对象是SCNetworkReachabilityRef
        1.1+ (instancetype)sharedManager
        1.2+ (instancetype)managerForAddress:(const void *)address根据 socket 地址(sockaddr_in6,ipv6) 来获取一个 ReachabilityManager 的实例 
        1.3+ (instancetype)managerForDomain:(NSString *)domain 根据域名来获取一个manager的实例
    2.AFNetworkReachabilityStatus 状
        AFNetworkReachabilityStatusUnknown          = -1, 不可知
           AFNetworkReachabilityStatusNotReachable     = 0,无网络
              AFNetworkReachabilityStatusReachableViaWWAN = 1,WiFi
              AFNetworkReachabilityStatusReachableViaWiFi = 2,蜂窝

    3.startMonitoring 
        3.1AFNetworkReachabilityStatusBlock 创建一个在每次网络状态改变时的回调
        3.2保存的是回调函数以及相关的一些数据操作SCNetworkReachabilityContext
                 1. 第一个参数 版本号,是传递给 SCDynamicStore (系统配置动态存储库)来创建函数用的。这个结构体的版本号是 0
                         2. 第二个参数  info 一个 C 指针,指向一个用户指定的数据块。(也就是前一步中创建的那个block)
                        3. 第三个参数 是一个函数 目的是对info做retain操作,
                         4. 第四个参数 是一个函数,目的是对info做release操作
                         5. 第五个参数是 一个函数,根据info获取Description字符串
        3.3 SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
            为 SCNetworkReachability添加回调函数 在状态变化的时候会调用这个回调
                   // 这个方法中还要一个回调函数,和一个 SCNetworkReachabilityContext 。回调函数用来当网络状态发生变化时,让系统进行回调。最后一个 context 是和 回调函数相关联的 SCNetworkReachabilityContext (网络可连接上下文)
        3.4 SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
              // 在设置完了回调函数后,将 networkReachability 加入到 runloop中,达到实时监听的目的
                    // SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
                // 将 networkReachability 添加到 某个运行循环上(这里是主循环),然后设定一个模式,在这个模式下都会触发监听。
                // 这里选的是 kCFRunLoopCommonModes 这样当用户操作UI的时候,也会继续监听。这个和NSTimer的使用类似,将定时器添加到这个模式的runloop中时 一些滑动事件就不会中断定时器的计时
        3.5dispatch_async(dispatch_get_global_queue // 在异步线程 发送一次当前的网络状态。
        3.6AFPostReachabilityStatusChange(flags, callback)
            3.6.1 :AFNetworkReachabilityStatusForFlags(flags);修改标书状态
            3.6.2 :block(status);有设置block 就调用并传递状态
            3.6.3:[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo]通知外界
    4.stopMonitoring  
        SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes) 关闭运行循环
5.AF 的图片缓存相关几个类:AFImageCache,AFImageRequestCache,AFAutoPurgingImageCache,AFCachedImage
    5.1AFImageCache  重要方法(实际就是实现了图片的增删查功能):针对非网络请求
        - (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier; 根据ID添加图片到缓存,这里的id是根据图片的url生成的
        - (BOOL)removeImageWithIdentifier:(NSString *)identifier; 根据id移除图片
        - (BOOL)removeAllImages; 移除所有图片
        - (nullable UIImage *)imageWithIdentifier:(NSString *)identifier; 根据id获取图片
    5.2 AFImageRequestCache 这个类相当于AFImageCache 拓展了了一个request
        - (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
        - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
        - (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
    5.3 AFAutoPurgingImageCache
         UInt64 memoryCapacity 总共内存:默认大小为:100 * 1024 * 1024 即100M
         UInt64 preferredMemoryUsageAfterPurge 优先保存的内存量 默认大小为:60 * 1024 * 1024 即60M
            UInt64 memoryUsage 已使用内存
            - (instancetype)init  初始化方法
            //初始化方法 + 设置最大内存和优先保存内存大小
            - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;           
    5.4 AFCachedImage
        UIImage *image  图片
        NSString *identifier  唯一标示,根据图片地址生成
        UInt64 totalBytes    总共大小
        NSDate *lastAccessDate;    最后修改时间,每次使用图片都会更新,清除缓存时也是根据这个字段排序进行清除的
        UInt64 currentMemoryUsage 当前使用内存
6.AF图片下载   AFImageDownloadPrioritization  , AFImageDownloadReceipt , AFImageDownloaderResponseHandler, AFImageDownloaderMergedTask,AFImageDownloader(核心类)
    6.1 AFImageDownloadPrioritization 下载图片优先顺序 
        AFImageDownloadPrioritizationFIFO, 先进先出
               AFImageDownloadPrioritizationLIFO   先进后出
    6.2 ADImageDownloadReceipt 下载凭证
        NSURLSessionDataTask *task  请求task
         NSUUID *receiptID   标示ID
    6.3 AFImageDownloaderResponseHandler
        NSUUID *uuid
        void (^successBlock)(NSURLRequest*, NSHTTPURLResponse*, UIImage*); 成功block
        void (^failureBlock)(NSURLRequest*, NSHTTPURLResponse*, NSError*)失败block
    6.4 AFImageDownloaderMergedTask  处理重复下载的类
        NSString *URLIdentifier; request.URL.absoluteString
        NSUUID *identifier;  [NSUUID UUID]
        NSURLSessionDataTask *task; 创建的请求task
           NSMutableArray <AFImageDownloaderResponseHandler*> *responseHandlers; 重复的创建后放入这个数组中,请求完成后,统一进行返回
    6.5 AFImageDownloader(核心类)
        6.5.1 URLIdentifier = request.URL.absoluteString;
        6.5.2 AFImageDownloaderMergedTask 判断去重
        6.5.3 [self.imageCache imageforRequest:request withAdditionalIdentifier:nil];读取缓存
        6.5.4:[ sessionManager dataTaskWithRequest: completionHandler: 进行网络请求
            6.5.4.1 成功后:在AFImageDownloaderMergedTask取出相同的链接请求直接回调回去
            6.5.4.2 [strongSelf.imageCache addImage:responseObject forRequest:request withAdditionalIdentifier:nil];保存缓存
            6.5.4.3 根据URL 进行回调出去数据
            6.5.4.4 下载数-1 ,并查看并发队列中是否有请求,并进行触发
        6.5.5 AFImageDownloaderResponseHandler 生成新的回调 相同url的直接生成一个回调block ,并加入队列中,下载后,根据队列统一进行回调
        6.5.6 AFImageDownloaderMergedTask
             NSString *URLIdentifier 请求链接
            NSUUID *identifier;
            NSURLSessionDataTask *task;请求的task
            NSMutableArray <AFImageDownloaderResponseHandler*> *responseHandlers 共同的响应的数组,成功后,从这里面取数据
        6.5.7 AFImageDownloadReceipt 移除task 处理主要依赖 :
            找到AFImageDownloaderMergedTask中receiptID 匹配的回调 
            removeMergedTaskWithURLIdentifier 移除
            关联请求NSString *URLIdentifier = imageDownloadReceipt.task.originalRequest.URL.absoluteString; 

7.UIKit   
    7.1UIButton+AFNetworking
        //图片下载器
        + (AFImageDownloader *)sharedImageDownloader;
        //设置用于下载图像的共享图像下载器
        + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader
        //根据状态取消按钮图片下载
        - (void)cancelImageDownloadTaskForState:(UIControlState)state;
        //根据状态取消按钮背景图片下载
        - (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state;
        //根据链接填充按钮
        - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url;
        //根据图片链接填充按钮 可放置占位图
        - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage;
        //根据请求request给按钮填充图片
        - (void)setImageForState:(UIControlState)state
          withURLRequest:(NSURLRequest *)urlRequest
        placeholderImage:(nullable UIImage *)placeholderImage
                 success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
                 failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
        //填充背景图片
        - (void)setBackgroundImageForState:(UIControlState)state withURL:(NSURL *)url;
        //填充背景图片可添加占位图
        - (void)setBackgroundImageForState:(UIControlState)state
                           withURL:(NSURL *)url
                  placeholderImage:(nullable UIImage *)placeholderImage;
            //根据请求填充图片可添加占位图,并保护成功失败回调,这个需要注意的是,需要在成功后,给button 赋值Image,不会自动赋值
            - (void)setBackgroundImageForState:(UIControlState)state
                    withURLRequest:(NSURLRequest *)urlRequest
                  placeholderImage:(nullable UIImage *)placeholderImage
                           success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
                           failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;    
    7.2 UIImage+ AFNetworking
        //根据二进制流生成安全图片
        + (UIImage*) safeImageWithData:(NSData*)data;
    7.2 UIImageView+ AFNetworking
        //图片下载器
        + (AFImageDownloader *)sharedImageDownloader;
        //取消图片下载器器执行的任何图像操作(如果存在)
        - (void)cancelImageDownloadTask;
        //根据URL填充图片
        - (void)setImageWithURL:(NSURL *)url;
        //根据IURL填充图片,可添加占位图
        - (void)setImageWithURL:(NSURL *)url
       placeholderImage:(nullable UIImage *)placeholderImage;
            //根据请求request 填充图片
        - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
              placeholderImage:(nullable UIImage *)placeholderImage
                       success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
                       failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
    7.3UIWebView+AFNetworking.h
        //根据请求request 加载 并返回进度,成功,失败回调
        - (void)loadRequest:(NSURLRequest *)request
           progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
            success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
            failure:(nullable void (^)(NSError *error))failure;
        //根据请求request  + 内容的MIMEType(默认即可,可不添加)+响应文本编码(utf-8 ,utf-16等)
    - (void)loadRequest:(NSURLRequest *)request
           MIMEType:(nullable NSString *)MIMEType
   textEncodingName:(nullable NSString *)textEncodingName
           progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
            success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
            failure:(nullable void (^)(NSError *error))failure;
 

猜你喜欢

转载自blog.csdn.net/ZhaiAlan/article/details/106350366