iOS AFN框架(二)的使用和有关序列化器的问题--缓存机制------

 

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 = [[NSURLallocinitFileURLWithPath: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"
                                };


 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

liyubao160

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值