AFNetworking笔记

源码:https://github.com/AFNetworking/AFNetworking

关于AFNetworking的请求响应数据序列化

  • requestSerializer 是 AFNetworking 请求参数编码的序列化器,它一共有三种编码格式:(默认二进制的数据格式)
AFHTTPRequestSerializer:(默认)第一种是普通的http的编码格式
也就是这种格式 mid=10&method=userInfo&dateInt=20160818

AFJSONRequestSerializer:第二种也是json编码格式的
也就是这种格式 {"mid":"11","method":"userInfo","dateInt":"20160818"}

AFPropertyListRequestSerializer:第三种编码成pislt格式的参数

注意: AFHTTPRequestSerializer,也就是二进制格式是AFNetworking的默认请求编码格式,因此我们的参数如果是json编码格式,就需要修改请求头的编码格式

一般我们的请求设置过程如下

//实例化AFHTTPSessionManager
 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//通过requestSerializer修改请求的编码格式(默认二进制格式)
 manager.requestSerializer = [AFJSONRequestSerializer serializer];

responseSerializer 是 AFNetworking 响应编码的序列化器,它一共有三种编码格式:(默认直接解析JSON)

self.responseSerializer = [AFJSONResponseSerializer serializer];

AFHTTPResponseSerializer  HTTP

AFJSONResponseSerializer  JSON (默认)

AFXMLParserResponseSerializer XML的解析器(只能返回XMLParser,还需要自己通过代理方法解析 )

AFImageResponseSerializer Image (AFN同样提供了异步加载网络图片的功能 但是:不支持 GIF,只有 SDWebImage 支持)

AFCompoundResponseSerializer 组合

AFXMLDocumentResponseSerializer (Mac OS X) 

AFPropertyListResponseSerializer  PList 

通过下面的代码设置响应解析器:

//实例化AFHTTPSessionManager
 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//通过responseSerializer修改响应的编码格式(默认就是JSON格式)
manager.responseSerializer = [AFJSONResponseSerializer serializer];

acceptableContentTypes 响应可接受类型

AFNetworking的AFJSONResponseSerializer(JSON响应序列化器)中的初始化init方法中的源码:

self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];

( acceptableContentTypes表示可接受的响应的MINE类型,如果不为nil,那么当服务器响应中的Content-Type在里面找不到对应的MINE类型,AFN会在响应的校验方法中返回错误信息:- (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response data:(nullable NSData *)data error:(NSError * _Nullable __autoreleasing *)error; )

服务器一般返回的几种的响应内容:

1、服务端需要返回一段普通文本给客户端,Content-Type="text/plain"
2、服务端需要返回一段HTML代码给客户端 ,Content-Type="text/html"
3、服务端需要返回一段XML代码给客户端 ,Content-Type="text/xml"
4、服务端需要返回一段javascript代码给客户端 Content-Type="text/javascript "
5、服务端需要返回一段json串给客户端 Content-Type="application/json“

因此:由于上面AFJSONResponseSerializer初始化方法代码中,只添加了对@"application/json", @"text/json", @"text/javascript" 三种类型的支持,如果需要添加对text/html类型的支持,应该在创建AFHTTPSessionManager的时候(懒加载),重新设置acceptableContentTypes(不要在源码里面添加,因为会导致pod install之后,又要重新修改),代码如下:

_manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];

综上,常规的AFN网络访问步骤如下

//实例化AFHTTPSessionManager,所有的网络请求,均有manager发起 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 

//如果提交数据是JSON的,需要将请求格式设置为AFJSONRequestSerializer 
manager.requestSerializer = [AFJSONRequestSerializer serializer];
//如果返回格式不是JSON的,那么就根据返回数据格式修改解析器
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

//设置请求头:将token等每次请求需要带的参数封装入请求头
[manager.requestSerializer setValue:TOKEN forHTTPHeaderField:@"token-id"];

监测网络

#pragma mark - 检测网络连接  
- (void)reach  
{  
  /** 
  AFNetworkReachabilityStatusUnknown = -1, // 未知 
  AFNetworkReachabilityStatusNotReachable  = 0,  // 无连接 
  AFNetworkReachabilityStatusReachableViaWWAN = 1,  // 3G 花钱 
  AFNetworkReachabilityStatusReachableViaWiFi = 2,  // 局域网络,不花钱 
  */  

  // 如果要检测网络状态的变化,必须用检测管理器的单例的startMonitoring  
  [[AFNetworkReachabilityManager sharedManager] startMonitoring];  

  // 检测网络连接的单例,网络变化时的回调方法 
  [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {  
    NSLog(@"%d", status);  
  }];  
} 

关于AFNetworking结果回调, 已经帮我们放到主线程了(以下为源码)

失败结果回调一

- (NSURLSessionDataTask *)POST:(NSString *)URLString

 parameters:(id)parameters

 constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block

 progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress

 success:(void (^)(NSURLSessionDataTask *task, id responseObject))success

 failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

{

  NSError *serializationError = nil;

  NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];

  if (serializationError) {

    if (failure) {

      dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{

        failure(nil, serializationError);

      });

    }

  return nil;
}

失败结果回调二

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method

 URLString:(NSString *)URLString

 parameters:(id)parameters

 uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress

 downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress

 success:(void (^)(NSURLSessionDataTask *, id))success

 failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

{

  NSError *serializationError = nil;

  NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];

  if (serializationError) {

    if (failure) {

      dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{

        failure(nil, serializationError);

      });

    }

  return nil;

}

成功结果回调

#pragma mark - NSURLSessionTaskDelegate

- (void)URLSession:(__unused NSURLSession *)session

 task:(NSURLSessionTask *)task

didCompleteWithError:(NSError *)error

{

  __strong AFURLSessionManager *manager = self.manager;

  __block id responseObject = nil;

  __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];

  userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;

  *//Performance Improvement from #2672*

  NSData *data = nil;

  if (self.mutableData) {

    data = [self.mutableData copy];

    *//We no longer need the reference*, *so nil it out to gain back some memory.*

    self.mutableData = nil;

   }

  if (self.downloadFileURL) {

    userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;

  } else if (data) {

    userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;

  }

  if (error) {

    userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;

    dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{

      if (self.completionHandler) {

        self.completionHandler(task.response, responseObject, error);

      }

      dispatch_async(dispatch_get_main_queue(), ^{

        [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];

      });

  });

 } else {

  dispatch_async(url_session_manager_processing_queue(), ^{

        NSError *serializationError = nil;

        responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];

        if (self.downloadFileURL) {

          responseObject = self.downloadFileURL;

        }

        if (responseObject) {

          userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;

        }

        if (serializationError) {

          userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;

        }

        dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{

        if (self.completionHandler) {

          self.completionHandler(task.response, responseObject, serializationError);

        }

        dispatch_async(dispatch_get_main_queue(), ^{

          [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task   userInfo:userInfo];

        });

      });

    });

  }

}

AFNetWorking源码之NSURLSession系列概述
https://huang303513.github.io/2017/04/14/AFNetWorking%E6%BA%90%E7%A0%81%E4%B9%8BNSURLSession%E7%B3%BB%E5%88%97%E6%A6%82%E8%BF%B0.html

AFNetworking3.0后为什么不再需要常驻线程
https://www.jianshu.com/p/b5c27669e2c1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。