AFHTTPRequestOperationManager:内部封装的是 NSUrlConnection,网络请求管理类,用来负责发送网络请求,是使用最多的一个类.
AFHTTPSessionManager :内部封装的是 NSUrlSession,网络请求管理类,用来负责发送网络请求,
一些主要的工具类:
AFNetworkReachabilityManager.h :实时监测网络状态改变的管理类.
AFSecurityPolicy.h :HTTPS 需要使用.
AFURLRequestSerialization: 数据解析的时候会使用.
AFHTTPRequestSerializer: 万能解析器/对服务器返回的数据不做任务处理.
AFJSONResponseSerializer: JSON解析器.
AFXMLParserResponseSerializer: XML解析器.
AFHTTPRequestOperationManager对NSURLConnection的封装.
AFHTTPSessionManager对NSURLSession的封装
1.创建管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
2.设置管理者的数据解析类型,默认为 json 格式的解析,可手动修改为其他类型,如 XML:
manager.responseSerializer = [AFXMLParserResponseSerializer serializer]
3.1 首先要明确发送的是什么类型的请求(GET/POST/HEAD...)
3.2 AFN 3.0之后的网络接口相比之前的网络接口多了一个参数:网络进度.
参数:
1. urlString: 网络接口地址.
2. parameters: 参数字典.key:服务器接收普通参数的key值,value就是参数内容.
3. progress: 网络进度
4. success: 成功回调
5. failure: 失败回调
3.3 AFN根据 response.MIMEType 来判断服务器返回数据的类型. 如果类型不匹配,但是又是JSON数据,解决方案:
1.改变解析器类型为:万能解析器 ---> 手动解析JSON
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
2.改变判断条件的类型,以使类型匹配,acceptableContentTypes默认情况下无 text/plain 类型
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain",nil];
typedef void(^ProgressBlock) (NSProgress* progress);
typedef void(^SuccessBlock) (NSURLSessionDataTask *task, id responseObject);
typedef void(^FailureBlock) (NSURLSessionDataTask *task, NSError *error);
===========
AFHTTPRequestOperationManager
get请求
- (void)get{
//1获取manager
AFHTTPRequestOperationManager *manager =[AFHTTPRequestOperationManagermanager];
/*
1.访问的地址
2.参数
3.成功的回调
4.失败的回调
*/
[manager GET:@"http://127.0.0.1/demo.json"parameters:nilsuccess:^(AFHTTPRequestOperation*_Nonnull operation, id _Nonnull responseObject) {
//responseObject返回的数据,已经自动的json反序列化
NSLog(@"%@",[responseObjectclass]);
} failure:^(AFHTTPRequestOperation *_Nullable operation,NSError * _Nonnull error) {
}];
}
______________________________________________________
//get请求带参数
- (void)get2{
//1获取manager
AFHTTPRequestOperationManager *manager =[AFHTTPRequestOperationManagermanager];
/*
1.访问的地址
2.参数
3.成功的回调
4.失败的回调
*/
//?username=111&password=111
[manager GET:@"http://127.0.0.1/login.PHP"parameters:@{@"username":@"11",@"password":@"222"}success:^(AFHTTPRequestOperation*_Nonnull operation,id _Nonnull responseObject) {
//responseObject返回的数据,已经自动的json反序列化
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *_Nullable operation,NSError * _Nonnull error) {
}];
}
_________________________________________________________
//post带参数请求
- (void)post{
//1获取manager
AFHTTPRequestOperationManager *manager =[AFHTTPRequestOperationManagermanager];
/*
1.访问的地址
2.参数
3.成功的回调
4.失败的回调
*/
//?username=111&password=111
[manager POST:@"http://127.0.0.1/login.php"parameters:@{@"username":@"11",@"password":@"222"}success:^(AFHTTPRequestOperation*_Nonnull operation,id _Nonnull responseObject) {
//responseObject返回的数据,已经自动的json反序列化
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *_Nullable operation,NSError * _Nonnull error) {
}];
}
_________________________________________________________
//post请求上传文件
-(void)uploadfiles{
AFHTTPRequestOperationManager *manager =[AFHTTPRequestOperationManagermanager];
/*
1.访问的地址
2.参数
3.constructingBodyWithBlock 构建请求体,把要发送的数据放到里面
4.成功的回调
5.失败的回调
*/
[manager POST:@"http://127.0.0.1/upload/upload-m.php"parameters:@{@"username":@"itcast"}constructingBodyWithBlock:^(id<AFMultipartFormData> _NonnullformData) {
NSURL *fileURL = [[NSBundlemainBundle]URLForResource:@"1.JPG"withExtension:nil];
[formData appendPartWithFileURL:fileURL name:@"userfile[]"error:NULL];//这里的name要和服务器的name一样.fileURLname是本地文件,这个方法多次使用,可以实现多文件上传(改一下URL即可).
} success:^(AFHTTPRequestOperation *_Nonnull operation, id _Nonnull responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *_Nullable operation,NSError * _Nonnull error) {
}];
}
____________________________________________________________
以文件流的方式上传到服务器:
//上传用户头像
+(void)uploadpersonimageUserWithURL:(NSString *)url paramas:(NSDictionary *)params image:(UIImage *)image success:(void (^)(id responseObject))success failure:(void (^)(id error))failure{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
manager.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html" @"image/jpeg",@"image/png",nil];
[manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
manager.requestSerializer.timeoutInterval = 20;
[manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];//设置超时
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSData *imageDatas =UIImagePNGRepresentation(image);
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.png", str];
//上传的参数(上传图片,以文件流的格式)
/*该方法的参数
1. appendPartWithFileData:要上传的照片[二进制流]
2. name:对应网站上[upload.php中]处理文件的字段(比如upload)
3. fileName:要保存在服务器上的文件名
4. mimeType:上传的文件的类型
*/
[formData appendPartWithFileData:imageDatas
name:@"file"
fileName:fileName
mimeType:@"image/png"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
//打印下上传进度
NSLog(@"上传进度%@",uploadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if(responseObject){
NSLog(@"上传用户头像--%@",responseObject);
success(responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NPrintLog(@"上传用户头像 %@ ", error);
}];
}
________________________________________________________________________________________________
AFHTTPSessionManager----------以前的方法
typedef void(^ProgressBlock) (NSProgress* progress);
typedef void(^SuccessBlock) (NSURLSessionDataTask *task, id responseObject);
typedef void(^FailureBlock) (NSURLSessionDataTask *task, NSError *error);
get方法请求
- (void)get{
//1.manager
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
[manager GET:@"http://127.0.0.1/demo.json"parameters:nilsuccess:^(NSURLSessionDataTask*_Nonnull task, id _Nonnull responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask *_Nullable task, NSError*_Nonnull error) {
}];
}
________________________________________________________________________________________________
post方法请求
- (void)post{
//1.manager
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
[manager POST:@"http://127.0.0.1/login.php"parameters:@{@"username":@"11",@"password":@"222"}success:^(NSURLSessionDataTask*_Nonnull task,id _Nonnull responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask *_Nullable task, NSError*_Nonnull error) {
}];
}
________________________________________________________________________________________________
//downloadTaskWithRequest:下载文件,带进度
-(void)downloadFile{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://127.0.0.1/1.mp4"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
/*
1.请求
2.进度
3.下载的目的地需要自己制定下载路径 通过block返回
4.完成回调
*/
NSProgress *progress;
[[manager downloadTaskWithRequest:requst progress:&progress destination:^NSURL *_Nonnull(NSURL *_Nonnull targetPath,NSURLResponse * _Nonnull response) {
//存到temp目录中,这是设置下载的路径
NSString *path = [NSTemporaryDirectory()stringByAppendingPathComponent:response.suggestedFilename];
NSURL *url = [[NSURLalloc] initFileURLWithPath:path];
return url;
} completionHandler:^(NSURLResponse *_Nonnull response, NSURL* _Nullable filePath, NSError * _Nullable error) {
NSLog(@"%@",filePath);
}] resume];
//输出进度 KVO添加观察者
/*
1.谁观察
2.观察的key
3.选项
*/
[progress addObserver:selfforKeyPath:@"fractionCompleted"options:NSKeyValueObservingOptionNewcontext:nil];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
//观察方法
/*
1.要观察的key
2.要观察的对象
3.新值的变化
4.其他参数
*/
//判断监控的对象类型
if([object isKindOfClass:[NSProgressclass]]){
NSProgress *progress = object;
//打印进度
// NSLog(@"%f",progress.fractionCompleted);
NSLog(@"%@",progress.localizedDescription);
}
}
_____
________________________________________________________________________________________________
**********************************
typedef void(^ProgressBlock) (NSProgress* progress);
typedef void(^SuccessBlock) (NSURLSessionDataTask *task, id responseObject);
typedef void(^FailureBlock) (NSURLSessionDataTask *task, NSError *error);
AFHTTPSessionManager----------更新后的方法*************************
#import "ViewController.h"
#import <AFNetworking.h>
@interfaceViewController ()
@property(nonatomic,strong)NSURLSessionDownloadTask *downloadTask;
@property(nonatomic,strong)NSData *resumeData;
@property(nonatomic,strong)AFURLSessionManager *manager;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selfget];
}
//0--get--------
@interface NetworkTools : AFHTTPSessionManager
+ (instancetype)sharedTools {
staticCZNetworkTools *tools;
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//
NSURL *baseURL = [NSURLURLWithString:@"http://c.m.163.com/nc/"];
NSURLSessionConfiguration *config = [NSURLSessionConfigurationdefaultSessionConfiguration];
//设置请求的超时时长
config.timeoutIntervalForRequest =15;
tools = [[selfalloc]initWithBaseURL:baseURLsessionConfiguration:config];
});
return tools;
}
-(void)get{
[[CZNetworkTools sharedTools] GET:baseURL后面的路径 parameters:nil progress:^(NSProgress *_Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
}];
}
//----1---get
- (void)get{
//1.manager
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
//2.待超时时间
NSURLSessionConfiguration *config = [NSURLSessionConfigurationdefaultSessionConfiguration];
config.timeoutIntervalForRequest = 50.0;
AFHTTPSessionManager *manager = [[AFHTTPSessionManageralloc]initWithSessionConfiguration:config];
manager.securityPolicy = [AFSecurityPolicypolicyWithPinningMode:AFSSLPinningModeNone];//安全策略 AFSSLPinningModeCertificate(校验证书)
manager.securityPolicy.allowInvalidCertificates =YES;//客户端是否信任非法证书
manager.securityPolicy.validatesDomainName =NO;//不验证证书的域名
manager.responseSerializer.acceptableContentTypes=[NSSetsetWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"text/xml",@"text/plain; charset=utf-8",nil];
manager.responseSerializer = [AFHTTPResponseSerializerserializer];
//序列化器的类型
// manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializerserializer];
[manager GET:@"http://121.43.187.220"parameters:nilprogress:^(NSProgress *_Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {
//1.******如果后台的数据是标准的JSON格式,得到的数据就是字典,可以直接使用;只有最上面的节点是数组和字典才能用JSON解析;
如果后台返回的数据类型是application/json,text/json;
用dictionary接收就是字典,
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];
用NSString 接收就是字符串;
NSString *jsonStr=[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];
2.*******==如果JSON带转义符号,可以先转成data,再序列化
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
====response返回如下数据:---如果有转义符号,先转成data类型,然后再序列化
cards = "[{\"cvn\":\"123\",\"idno\":\"341126197709218366\",\"name\":\"\U53e4\U53e4\U60d1\U60d1\",\"expiry\":\"1117\",\"card_no\":\"6221558812340000\",\"last_time\":\"2017-09-15 15:04:25\",\"last_amount\":1},{\"cvn\":\"123\",\"idno\":\"341126197709218366\",\"name\":\"\U53e4\U53e4\U60d1\U60d1\",\"expiry\":\"1111\",\"card_no\":\"622262226222\"}]";
NSData *data=[responseObject[@"cards"]dataUsingEncoding:NSUTF8StringEncoding];
NSArray *dict=[NSJSONSerializationJSONObjectWithData:data
options:NSJSONReadingMutableLeaveserror:nil];
//3.********=======如果请求的是网页数据:(如果后台返回的数据类型不是application/json,text/json;)
NSString *str=[[NSString alloc]initWithData:responseObject
encoding:NSUTF8StringEncoding];//网页二进制数据转换成字符串,(AFHttpSerialization是万能解析,后台返回任何的格式都能解析;)
NSLog(@"---responseStr---%@",str);
NSData *data=[str dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *responseObject=[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments error:nil];
//4.*********如果后台的数据不是标准的JSON格式,就需要用下面的方法自己解析;
===== responset返回的是十六进制的数据: //先序列化成字符串,再转成data类型,再序列化
NSString *getLoginstr=[NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingAllowFragmentserror:&err];
NSData* jsonData = [getLoginstr dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array =[NSJSONSerialization JSONObjectWithData:jsonData
options:kNilOptionserror:&err];
} failure:^(NSURLSessionDataTask *_Nullable task,NSError * _Nonnull error) {
}];
}
//-------2----post
-(void)postWithThreeBlock{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
manager.securityPolicy = [AFSecurityPolicypolicyWithPinningMode:AFSSLPinningModeNone];//安全策略
manager.securityPolicy.allowInvalidCertificates =YES;
//序列化器的类型
// manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializerserializer];
******accept是请求头的设置,表示服务器可以接受的数据格式(MIME);
contentType是响应头的设置,向服务器请求的数据类型,表示服务端返回的数据格式,也就是客户端可以接受的数据格式;
//下列请求头参数根据你自己的后台接口要求来设置
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[manager.requestSerializer setValue:@"keep-alive" forHTTPHeaderField:@"Connection"];
[manager.requestSerializer setValue:@"zh-cn" forHTTPHeaderField:@"language"];
//如果报接受类型不一致请替换一致text/html或别的
manager.responseSerializer.acceptableContentTypes = nil;
设置向请求内容的类型
[manager.requestSerializer setValue:@"application/json;charset=utf-8"forHTTPHeaderField:@"Content-Type"];//这个和
设置请求内容的长度
[manager.requestSerializer setValue:[NSStringstringWithFormat:@"%ld", (unsignedlong)[jsonStr length]] forHTTPHeaderField:@"Content-Length"];
设置请求的编码类型
[manager.requestSerializer setValue:@"gzip"forHTTPHeaderField:@"Content-Encoding"];
//可以序列化的类型------向服务器请求的数据类型,服务器可以接受的数据类型
manager.responseSerializer.acceptableContentTypes=[NSSetsetWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"text/xml",@"text/plain; charset=utf-8",nil];
[manager.requestSerializer setValue:@"text/html;charset=utf-8"
forHTTPHeaderField:@"Content-Type"]; //请求的URL所用的编码类型;如果不设置,默认的是json,客户端发送的数据类型
[manager.requestSerializer
setValue:@"application/json" forHTTPHeaderField:@"Accept"];//浏览器或客户端可以接受的数据类型,
[manager POST:@"http://121.43.187.220"parameters:nilprogress:^(NSProgress *_Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask *_Nullable task,NSError * _Nonnull error) {
}];
}
//-----3-----post
-(void)postWithFourBlock{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
[manager POST:@"http://121.43.187.220"parameters:nilconstructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//拼接二进制文件数据 第一个参数:要上传文件的url路径
第二个参数:服务器要求的参数名称
第三个参数:这个文件上传到服务器之后叫什么名称
第四个参数:文件的mimetype类型
第五个参数:错误信息
UIImage *image=[UIImageimageNamed:@"test01"];
NSData* imageData =UIImagePNGRepresentation(image);
NSString* sname = [NSStringstringWithFormat:@"img_file[%@]" ,@"1"];
NSString *fileName=[[NSBundlemainBundle]pathForResource:@"test01.png"ofType:nil];//本地文件路径
// //上传图片,以文件流的格式//这里的name要和服务器的name一样.fileName是本地文件路径,这个方法多次使用,可以实现多文件上传(改一下fileName即可)
[formData appendPartWithFileData:imageDataname:snamefileName:fileNamemimeType:@"image/png"];
//**************
// formData appendPartWithFileURL:<#(nonnull NSURL *)#> name:<#(nonnull NSString *)#> fileName:<#(nonnull NSString *)#> mimeType:<#(nonnull NSString *)#> error:<#(NSError *__autoreleasing _Nullable * _Nullable)#>
//****************
// formData appendPartWithFormData:<#(nonnull NSData *)#> name:<#(nonnull NSString *)#>
//**************
// formData appendPartWithFileURL:<#(nonnull NSURL *)#> name:<#(nonnull NSString *)#> error:<#(NSError *__autoreleasing _Nullable * _Nullable)#>
//****************
//*****************
// formData appendPartWithInputStream:<#(nullable NSInputStream *)#> name:<#(nonnull NSString *)#> fileName:<#(nonnull NSString *)#> length:<#(int64_t)#> mimeType:<#(nonnull NSString *)#>
//******************
} progress:^(NSProgress *_Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask *_Nullable task,NSError * _Nonnull error) {
}];
}
//------4------dataTask
-(void)datataskNormal{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
[manager dataTaskWithRequest:requstcompletionHandler:^(NSURLResponse *_Nonnull response, id _Nullable responseObject,NSError *_Nullable error) {
}];
}
//-----5-----dataTask
-(void)dataTaskWithupProgressAndDownProgress{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
[manager dataTaskWithRequest:requstuploadProgress:^(NSProgress *_Nonnull uploadProgress) {
} downloadProgress:^(NSProgress *_Nonnull downloadProgress) {
} completionHandler:^(NSURLResponse *_Nonnull response,id _Nullable responseObject,NSError *_Nullable error) {
}];
}
//----6------upload
-(void)uploadTaskNormal{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
[manager uploadTaskWithStreamedRequest:requstprogress:^(NSProgress *_Nonnull uploadProgress) {
} completionHandler:^(NSURLResponse *_Nonnull response,id _Nullable responseObject,NSError *_Nullable error) {
}];
}
//-----7-----upload
-(void)uploadTaskWithFromData{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
UIImage *image=[UIImageimageNamed:@"test01"];
NSData* imageData =UIImagePNGRepresentation(image);
[manager uploadTaskWithRequest:requstfromData:imageDataprogress:^(NSProgress *_Nonnull uploadProgress) {
} completionHandler:^(NSURLResponse *_Nonnull response,id _Nullable responseObject,NSError *_Nullable error) {
}];
}
//-----8-----upload
-(void)uploadWIithfromFile{
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
NSString *fileName=[[NSBundlemainBundle]pathForResource:@"test01.png"ofType:nil];
NSURL *fileUrl=[NSURLURLWithString:fileName];
[manager uploadTaskWithRequest:requstfromFile:fileUrlprogress:^(NSProgress *_Nonnull uploadProgress) {
} completionHandler:^(NSURLResponse *_Nonnull response,id _Nullable responseObject,NSError *_Nullable error) {
}];
}
//-------9------download
-(void)download{
NSURLSessionConfiguration * configuration = [NSURLSessionConfigurationdefaultSessionConfiguration]; //配置有三种模式,后台,缓存,鉴权安全
//*****AFURLSessionManager是AFHTTPSessionManager的父类******
AFURLSessionManager * manager = [[AFURLSessionManageralloc]initWithSessionConfiguration:configuration];
self.manager=manager;
NSURL *url =[NSURLURLWithString:@"http://121.43.187.220"];
NSURLRequest *requst = [NSURLRequestrequestWithURL:url];
NSURLSessionDownloadTask *downloadTask= [managerdownloadTaskWithRequest:requstprogress:^(NSProgress *_Nonnull downloadProgress) {
} destination:^NSURL *_Nonnull(NSURL *_Nonnull targetPath, NSURLResponse * _Nonnull response) {
//这里要返回一个NSURL,其实就是文件的位置路径
NSString * path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];
//使用建议的路径suggestedFilename
path = [path stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"%@",path);
return [NSURLfileURLWithPath:path];//转化为文件路径---下载到了这个地方
} completionHandler:^(NSURLResponse *_Nonnull response,NSURL * _Nullable filePath,NSError *_Nullable error) {
//如果下载的是压缩包的话,可以在这里进行解压
NSLog(@"----%@---%ld---%@",error.domain,error.code,error);
//下载成功
if (error ==nil) {
// completion(YES,@"下载完成",[filePath path]);
}else{//下载失败的时候,只列举判断了两种错误状态码
NSString * message =nil;
if (error.code == - 1005) {
message = @"网络异常";
}elseif (error.code == -1001){
message = @"请求超时";
}else{
message = @"未知错误";
}
// completion(NO,message,nil);
}
}];
self.downloadTask=downloadTask;
}
//取消下载
- (void)pauseClicked {
[self.downloadTaskcancelByProducingResumeData:^(NSData *_Nullable resumeData) {
self.resumeData = resumeData;//记录当前下载的数据
self.downloadTask =nil;//吧任务置为空
}];
}
//继续下载
- (void)continueClicked{
[selfdownloadTaskWithResumeData];
self.resumeData =nil;//吧保存的数据置为空
}
//10----download
-(void)downloadTaskWithResumeData{
[self.managerdownloadTaskWithResumeData:self.resumeDataprogress:^(NSProgress *_Nonnull downloadProgress) {
} destination:^NSURL *_Nonnull(NSURL *_Nonnull targetPath, NSURLResponse * _Nonnull response) {
//这里要返回一个NSURL,其实就是文件的位置路径
NSString * path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];
//使用建议的路径suggestedFilename
path = [path stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"%@",path);
return [NSURLfileURLWithPath:path];//转化为文件路径---下载到了这个地方
} completionHandler:^(NSURLResponse *_Nonnull response,NSURL * _Nullable filePath,NSError *_Nullable error) {
}];
}
@end
***********************
___________________________________________________________________________________________
________________________________________________________________________________________________
序列化器
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
//请求的序列化:
请求的数据格式(一般都是 HTTP
二进制数据,RESTful设计风格要求 POST JSON)
self.requestSerializer = [AFHTTPRequestSerializer serializer];
<AFURLRequestSerialization> 请求的数据格式
AFHTTPRequestSerializer HTTP,二进制,默认的
AFJSONRequestSerializer JSON
AFPropertyListRequestSerializer PList
//响应的序列化
//设置对服务器返回数据的解析方式:
1.制定http的序列化器---对应二进制data类型(浏览器返回的是html,不能直接使用json来解析,获得data数据后手动解析),万能解析器,其他类型页可以用 --->要 手动解析JSON
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
2.//XML的序列化器
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
3.//JSON的序列化器
manager.responseSerializer = [AFJSONResponseSerializer serializer];
AFN会根据response.MIMEType来判断服务器返回的数据类型,序列化器也要做相应的设置,
默认无@"text/plain",就要设置AFN接受的数据类型:
[AFJSONResponseSerializer serializer].acceptableContentType = [NSSet setWithObjects:@"text/xml",@"text/json",@"text/javaScript",
@"application/json",@"text/plain",@"text/html",nil];//设置AFN接受的数据类型.
=====================
AFNetworking实现单点续传,(暂停,下载)
A. 定义一个全局的 NSURLSessionDownloadTask:下载管理句柄
由其负责所有的网络操作请求
@interface ViewController ()
{
// 下载句柄
NSURLSessionDownloadTask *_downloadTask;
}
.h文件
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
// 下载文件显示
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
// 下载进度条显示
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@end
.m文件
@interface ViewController ()
{
// 下载句柄
NSURLSessionDownloadTask *_downloadTask;
}
2.利用AFN实现文件下载操作细节
- (void)downFileFromServer{
//远程地址
NSURL *URL = [NSURL URLWithString:@"http://www.baidu.com/img/bdlogo.png"];
//默认配置
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//AFN3.0+基于封住URLSession的句柄
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
//请求
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
//下载Task操作
_downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
// @property int64_t totalUnitCount; 需要下载文件的总大小
// @property int64_t completedUnitCount; 当前已经下载的大小
// 给Progress添加监听 KVO
NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
// 回到主队列刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
// 设置进度条的百分比
self.progressView.progress = 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;
});
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//- block的返回值, 要求返回一个URL, 返回的这个URL就是文件的位置的路径
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
//设置下载完成操作
// filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
NSString *imgFilePath = [filePath path];// 将NSURL转成NSString
UIImage *img = [UIImage imageWithContentsOfFile:imgFilePath];
self.imageView.image = img;
}];
}
3.关于暂停和继续
- (IBAction)stopDownloadBtnClick:(id)sender {
//暂停下载
[_downloadTask suspend];
}
- (IBAction)startDownloadBtnClick:(id)sender {
//开始下载
[_downloadTask resume];
}
4.检测网络状态--优化用户体验
- (void)viewDidLoad {
[super viewDidLoad];
//网络监控句柄
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
//要监控网络连接状态,必须要先调用单例的startMonitoring方法
[manager startMonitoring];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
//status:
//AFNetworkReachabilityStatusUnknown = -1, 未知
//AFNetworkReachabilityStatusNotReachable = 0, 未连接
//AFNetworkReachabilityStatusReachableViaWWAN = 1, 3G
//AFNetworkReachabilityStatusReachableViaWiFi = 2, 无线连接
NSLog(@"%d", status);
}];
//准备从远程下载文件. -> 请点击下面开始按钮启动下载任务
[self downFileFromServer];
}
________________________________________________________________________________________________
AFHTTPSessionManager----------XML解析
如何通过URL获取XML文件:
xml 解析使用AFXMLRequestOperation,需要实现苹果自带的NSXMLParserDelegate委托方法,XML中有一些不需要的协议 格式内容,所以就不能像json那样解析,还得实现委托。我之前有想过能否所有的XML链接用一个类处理,而且跟服务端做了沟通,结果很不方便,效果不 好。XML大多标签不同,格式也不固定,所以就有问题,使用json就要方便的多。
第一步;在.h文件中加入委托NSXMLParserDelegate
第二步;在.m文件方法中加入代码
NSURL *url = [NSURL URLWithString:@"http://113.106.90.22:5244/sshopinfo"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFXMLRequestOperation *operation =
[AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
XMLParser.delegate = self;
[XMLParser setShouldProcessNamespaces:YES];
[XMLParser parse];
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
NSLog(@"%@",error);
}];
[operation start];
第三步;在.m文件中实现委托方法
//在文档开始的时候触发
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"解析开始!");
}
//解析起始标记
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(@"标记:%@",elementName);
}
//解析文本节点
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"值:%@",string);
}
//解析结束标记
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束标记:%@",elementName);
}
//文档结束时触发
-(void) parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"解析结束!");
}
====================
=========AFN中的缓存机制=======
AFNetworking实际上利用了两套单独的缓存机制:
AFImagecache : 继承于NSCache,AFNetworking的图片内存缓存的类。
NSURLCache : NSURLConnection的默认缓存机制,用于存储NSURLResponse对象:一个默认缓存在内存,并且可以通过一些配置操作可以持久缓存到磁盘的类。
AFImageCache是如何工作的?
AFImageCache属于UIImageView+AFNetworking的一部分,继承于NSCache,以URL(从NSURLRequest对象中获取)字符串作为key值来存储UIImage对象。 AFImageCache的定义如下:(这里我们声明了一个2M内存、100M磁盘空间的NSURLCache对象。)
@interface AFImageCache : NSCache// singleton instantiation :
+ (id )sharedImageCache {
static AFImageCache *_af_defaultImageCache =nil;
staticdispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_af_defaultImageCache = [[AFImageCache alloc] init];
// clears out cache on memory warning :
[[NSNotificationCenterdefaultCenter]addObserverForName:UIApplicationDidReceiveMemoryWarningNotificationobject:nilqueue:[NSOperationQueuemainQueue]usingBlock:^(NSNotification *__unused notification) {
[_af_defaultImageCache removeAllObjects];
}];
});
// key from [[NSURLRequest URL] absoluteString] :
staticinline NSString * AFImageCacheKeyFromURLRequest(NSURLRequest *request) {
return [[request URL] absoluteString];
}
@implementation AFImageCache
// write to cache if proper policy on NSURLRequest :
- (UIImage *)cachedImageForRequest:(NSURLRequest *)request {
switch ([request cachePolicy]) {
case NSURLRequestReloadIgnoringCacheData:
case NSURLRequestReloadIgnoringLocalAndRemoteCacheData:
returnnil;
default:
break;
}
return [self objectForKey:AFImageCacheKeyFromURLRequest(request)];
}
// read from cache :
- (void)cacheImage:(UIImage *)image
forRequest:(NSURLRequest *)request {
if (image && request) {
[self setObject:image forKey:AFImageCacheKeyFromURLRequest(request)];
}
}
AFImageCache是NSCache的私有实现,它把所有可访问的UIImage对象存入NSCache中,并控制着UIImage对象应该在何时释放,如果UIImage对象释放的时候你希望去做一些监听操作,你可以实现NSCacheDelegate的 cache:willEvictObject 代理方法。Matt Thompson已经谦虚的告诉我在AFNetworking2.1版本中可通过setSharedImageCache方法来配置AFImageCache,这里是 AFN2.2.1中的UIImageView+AFNetworking文档。
NSURLCache
AFNetworking使用了NSURLConnection,它利用了iOS原生的缓存机制,并且NSURLCache缓存了服务器返回的NSURLRespone对象。NSURLCache的shareCache方法是默认开启的,你可以利用它来获取每一个NSURLConnection对象的URL内容。让人不爽的是,它的默认配置是缓存到内存而且并没有写入到磁盘。为了tame the beast(驯服野兽?不太懂),增加可持续性,你可以在AppDelegate中简单地声明一个共享的NSURLCache对象,像这样:
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:2 * 1024 * 1024
diskCapacity:100 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
设置NSURLRequest对象的缓存策略
NSURLCache 将对每一个NSURLRequest对象遵守缓存策略(NSURLRequestCachePolicy),策略如下所示:
- NSURLRequestUseProtocolCachePolicy 默认的缓存策略,对特定的URL请求使用网络协议中实现的缓存逻辑
- NSURLRequestReloadIgnoringLocalCacheData 忽略本地缓存,重新请请求
- NSURLRequestReloadIgnoringLocalAndRemoteCacheData忽略本地和远程缓存,重新请求
- NSURLRequestReturnCacheDataElseLoad 有缓存则从中加载,如果没有则去请求
- NSURLRequestReturnCacheDataDontLoad 无网络状态下不去请求,一直加载本地缓存数据无论其是否存在
- NSURLRequestReloadRevalidatingCacheData 默从原始地址确认缓存数据的合法性之后,缓存数据才可使用,否则请求原始地址
======用NSURLCache缓存数据到磁盘=====
Cache-Control HTTP Header
Cache-Controlheader或Expires header存在于服务器返回的HTTP response header中,来用于客户端的缓存工作(前者优先级要高于后者),这里面有很多地方需要注意,Cache-Control可以拥有被定义为类似max-age的参数(在更新响应之前要缓存多长时间), public/private 访问或者是non-cache(不缓存响应数据),这里对HTTP cache headers进行了很好的介绍。
继承并控制NSURLCache
如果你想跳过Cache-Control,并且想要自己来制定规则读写一个带有NSURLResponse对象的NSURLCache,你可以继承NSURLCache。下面有个例子,使用 CACHE_EXPIRES来判断在获取源数据之前对缓存数据保留多长时间.(感谢 Mattt Thompson的回复)
@interface CustomURLCache : NSURLCache
static NSString *const CustomURLCacheExpirationKey =@"CustomURLCacheExpiration";
staticNSTimeIntervalconst CustomURLCacheExpirationInterval = 600;
@implementation CustomURLCache
+ (instancetype)standardURLCache {
static CustomURLCache *_standardURLCache =nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_standardURLCache = [[CustomURLCache alloc]
initWithMemoryCapacity:(2 * 1024 * 1024)
diskCapacity:(100 * 1024 * 1024)
diskPath:nil];
}
return _standardURLCache;
}
#pragma mark - NSURLCache
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
NSCachedURLResponse *cachedResponse = [super cachedResponseForRequest:request];
if (cachedResponse) {
NSDate* cacheDate = cachedResponse.userInfo[CustomURLCacheExpirationKey];
NSDate* cacheExpirationDate = [cacheDate dateByAddingTimeInterval:CustomURLCacheExpirationInterval];
if ([cacheExpirationDate compare:[NSDate date]] == NSOrderedAscending) {
[self removeCachedResponseForRequest:request];
returnnil;
}
}
}
return cachedResponse;
}
- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse
forRequest:(NSURLRequest *)request
{
NSMutableDictionary *userInfo = [NSMutableDictionarydictionaryWithDictionary:cachedResponse.userInfo];
userInfo[CustomURLCacheExpirationKey] = [NSDate date];
NSCachedURLResponse *modifiedCachedResponse = [[NSCachedURLResponsealloc]initWithResponse:cachedResponse.responsedata:cachedResponse.datauserInfo:userInfostoragePolicy:cachedResponse.storagePolicy];
[super storeCachedResponse:modifiedCachedResponse forRequest:request];
}
@end
现在你有了属于自己的NSURLCache的子类,不要忘了在AppDelegate中初始化并且使用它。
在缓存之前重写NSURLResponse
-connection:willCacheResponse 代理方法是在被缓存之前用于截断和编辑由NSURLConnection创建的NSURLCacheResponse的地方。对NSURLCacheResponse进行处理并返回一个可变的拷贝对象(代码来自NSHipster blog)
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse {
NSMutableDictionary *mutableUserInfo = [[cachedResponse userInfo] mutableCopy];
NSMutableData *mutableData = [[cachedResponse data] mutableCopy];
NSURLCacheStoragePolicy storagePolicy = NSURLCacheStorageAllowedInMemoryOnly;
// ...
return [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response]
data:mutableData
userInfo:mutableUserInfo
storagePolicy:storagePolicy];
}
// If you do not wish to cache the NSURLCachedResponse, just return nil from the delegate function:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse {
returnnil;
}
禁用NSURLCache
可以禁用NSURLCache,只需要将内存和磁盘空间设置为0就行了.
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0
diskCapacity:0
diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
AFNetworking利用的系统自有类存储,我们可以修改其源代码:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
这一句代码是清除所有的URL缓存Response。
==========上传图片======
+ (void)uploadUrl:(NSString *)url parameter:(NSDictionary *)param withImages:(NSArray *)images succeed:(SucceedBlock)succeed failed:(FailedBlock)failed {
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
manager.requestSerializer = [AFJSONRequestSerializerserializer];
manager.responseSerializer = [AFJSONResponseSerializerserializer];
[manager.requestSerializersetValue:@"application/json"forHTTPHeaderField:@"Accept"];
[manager.requestSerializersetValue:@"application/json;charset=utf-8"forHTTPHeaderField:@"Content-Type"];
manager.requestSerializer.timeoutInterval = 20;
manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"text/plain",@"multipart/form-data",@"application/json",@"text/html",@"image/jpeg",@"image/png",@"application/octet-stream",@"text/json",nil];
// 在parameters里存放照片以外的对象
[manager POST:urlparameters:paramconstructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// formData: 专门用于拼接需要上传的数据,在此位置生成一个要上传的数据体
for (int i =0; i < images.count; i++) {
if ([images[i] isKindOfClass:[UIImageclass]]) {
UIImage *image = images[i];
NSData *imageData = UIImageJPEGRepresentation(image,1);
// 上传文件,文件不允许被覆盖,文件重名
NSDateFormatter *formatter = [[NSDateFormatteralloc]init];
// 设置时间格式
[formatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateString = [formatter stringFromDate:[NSDatedate]];
NSString *fileName = [NSString stringWithFormat:@"%@.jpg", dateString];
/*
*该方法的参数
1. appendPartWithFileData:要上传的照片[二进制流]
2. name:对应网站上[upload.php中]处理文件的字段(比如upload)
3. fileName:要保存在服务器上的文件名
4. mimeType:上传的文件的类型
*/
[formData appendPartWithFileData:imageDataname:@"images"fileName:fileNamemimeType:@"image/jpeg"];
}else {
NSData *soundData = [NSDatadataWithContentsOfFile:images[i]];
[formData appendPartWithFileData:soundDataname:@"audios"fileName:@"audio.caf"mimeType:@"audio/mp3"];
}
}
} progress:^(NSProgress *_Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {
NSDictionary *response = (NSDictionary *)responseObject;
succeed(response);
} failure:^(NSURLSessionDataTask * _Nullable task,NSError *_Nonnull error) {
failed(error);
}];
}
NSJSONReadingMutableContainers:返回可变容器,NSMutableDictionary或NSMutableArray。
NSJSONReadingMutableLeaves:返回的JSON对象中字符串的值为NSMutableString,目前在iOS 7上测试不好用,应该是个bug,参见:
http://stackoverflow.com/questions/19345864/nsjsonreadingmutableleaves-option-is-not-working
NSJSONReadingAllowFragments:允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串。参见:
http://stackoverflow.com/questions/16961025/nsjsonserialization-nsjsonreadingallowfragments-reading
NSJSONWritingPrettyPrinted:的意思是将生成的json数据格式化输出,这样可读性高,不设置则输出的json字符串就是一整行。
发送请求后主动取消请求=========
方法一:
// 取消请求// 仅仅是取消请求, 不会关闭session[self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];// 关闭session并且取消请求(session一旦被关闭了, 这个manager就没法再发送请求)[self.manager invalidateSessionCancelingTasks:YES];self.manager = nil;// 一个任务被取消了, 会调用AFN请求的failure这个block[task cancel];
方法二:
[[[AFURLSessionManager manger]operationQueue] cancelAllOperations];
*****************cookie设置***************
+(void) setUpCookies{
NSArray *arcCookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"kUserDefaultsCookie"]];
if (arcCookies.count != 0) {
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in arcCookies){
if([BaseURL rangeOfString:cookie.domain].location != NSNotFound){
[cookieStorage setCookie: cookie];
}else{
[cookieStorage deleteCookie:cookie];
}
}
}
}
+(void) storeCookies{
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject:cookies];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: cookiesData forKey: @"kUserDefaultsCookie"];
[defaults synchronize];
}
*************安全策略设置***********
/**
https安全请求 自签证书
@return 安全政策
*/
+ (AFSecurityPolicy*)customSecurityPolicy {
// /先导入证书
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];// AFSSLPinningModeCertificate 使用证书验证模式
// if(XBSSSLPinningMode == AFSSLPinningModeNone){
//
// //无证书模式用于调试。允许抓包
//
// }else{
//
// NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"365xbs" ofType:@"cer"];
//
// NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
//
// securityPolicy.pinnedCertificates = [NSSet setWithObject:cerData];
//
// }
securityPolicy.validatesDomainName = NO;
securityPolicy.allowInvalidCertificates = NO;
// allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
return securityPolicy;
}
*****AFN传参数的问题
https://www.jianshu.com/p/4faf19257238
https://www.cnblogs.com/InitialCC/p/5719311.html
//6.普通的原生请求,AFN参数会有问题
-(void)nativeRequestWithUrl:(NSString *)url
params:(NSDictionary *)params
successBlock:(SuccessBlock)successBlock
failureBlock:(FailureBlock)failureBlock{
NSString *jsonstr = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:params options:0 error:nil] encoding:NSUTF8StringEncoding];
AFURLSessionManager *manager=[[AFURLSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *request=[[AFJSONRequestSerializer serializer]requestWithMethod:@"POST" URLString:url parameters:nil error:nil];
request.timeoutInterval=20;
[request setValue:@"application/json;charset=utf-8"
forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json;charset=utf-8"
forHTTPHeaderField:@"Accept"];
//设置body
[request setHTTPBody:[jsonstr dataUsingEncoding:NSUTF8StringEncoding]];
[[manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
} downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
} completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSLog(@"农田数据---%@",responseObject);
}]resume];
}
******有时候后台接受不到参数,需要把字典中嵌套字典转换成字符串,如果AFN的post方法不行,就换AFN其他的方法
NSString *myfieldurl=[NSString stringWithFormat:@"%@%@",BASEURL,@"/farm/api/request?"];
NSDictionary *dic=@{@"userId":self.userid?self.userid:@"4"};
NSString *jsonstr = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dic options:0 error:nil] encoding:NSUTF8StringEncoding];
QMWNWEAKSELF;
NSDictionary *myfielddict=@{@"command":@"fieldsInfo",
@"data":jsonstr,
// @"sign":@"97D2E4D421C33827768E4299910A963C920F49D44EE290153F2A2FD170DDF74D"
};