【Warming】:AFNetworking 奇葩问题旨在针对奇葩问题提出奇葩的解法,部分验证并在实际中用到,但不保证有隐性问题。
之前都是通过键值对的形式进行网络请求,接口那边在新项目中对POST/PUT/DELETE突然用到了加密后的text/plain格式的raw数据形式,是一种新的挑战。先后尝试了两种方法。最后抛弃了第一种,不知道具体原因,此种方法对DELETE方法失效,可能我对HTTP请求挖的不够深,也可能是没有细看AFHTTPSesstionManger类理解不够透彻,但第二种对所有的请求都有效。就没细究这个问题了。
先展示一下两种方法共同的部分
+ (instancetype)sharedPostAndPutClient{
static SPNetworkClient * client = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
client = [[SPNetworkClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
client.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
client.requestSerializer.timeoutInterval = 10;
client.responseSerializer = [AFJSONResponseSerializer serializer];
[client.requestSerializer setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
});
return client;
}
-
方法1、在请求的开始加setQueryStringSerializationWithBlock,代码如下
[[SPNetworkClient sharedPostAndPutClient].requestSerializer setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id _Nonnull parameters, NSError * _Nullable __autoreleasing * _Nullable error) { // 返回数据(对paramters进行加密后的字符串) return 加密后的字符串; }];
-
方法2、抛开AFHTTPSesstionManager对各个请求方法的封装,利用更底层的-dataTaskWithRequest:completionHandler来进行再封装。代码如下:
- (void)requestWithMethod:(NSString*)method urlString:(NSString*)urlString parameters:(id)paramters success:(void(^)(NSURLSessionDataTask* task, id responseObject))success fail:(void(^)(NSURLSessionDataTask* task, NSError * error))failure{ BOOL isJson = [paramters isKindOfClass:[NSDictionary class]]; NSMutableURLRequest * request = [[SPNetworkClient sharedPostAndPusClient].requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:urlString relativeToURL:[SPNetworkClient sharedPostAndPusClient].baseURL] absoluteString] parameters:isJson?paramters:nil error:nil]; if (!isJson) { request.HTTPBody = [paramters dataUsingEncoding:NSUTF8StringEncoding]; } __block NSURLSessionDataTask * dataTask = nil; dataTask = [[SPNetworkClient sharedPostAndPusClient] dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (!error) { if (success) { success(dataTask,responseObject); } }else{ if (failure) { failure(dataTask,error); } } }]; [dataTask resume]; }
- 加入了参数Method,这样就可以兼容所有的接口,可以对上层需要的接口形式再封装。
- 其中对传入的paramters进行了判断,从而决定是以request方法的paramters进行数据传递还是以HTTPBody的形式进行传递。