您的位置:首页 > 其它

AFN应用及原理

2016-04-22 18:30 405 查看
AFN框架

注意事项

AFN的请求默认的发送的是二进制,

AFN的响应默认的接收的是JSON

1 AFN内部结构

AFN结构体

- NSURLConnection(iOS9.0废弃了)

+ AFURLConnectionOperation

+ AFHTTPRequestOperation

+ AFHTTPRequestOperationManager(封装了常用的 HTTP 方法)

* 属性

* baseURL :AFN建议开发者针对 AFHTTPRequestOperationManager 自定义个一个单例子类,设置 baseURL, 所有的网络访问,都只使用相对路径即可

* requestSerializer :请求数据格式/默认是二进制的 HTTP

* responseSerializer :响应的数据格式/默认是 JSON 格式

* operationQueue

* reachabilityManager :网络连接管理器

* 方法

* manager :方便创建管理器的类方法

* HTTPRequestOperationWithRequest :在访问服务器时,如果要告诉服务器一些附加信息,都需要在 Request 中设置

* GET

* POST

- NSURLSession
+ AFURLSessionManager
+ AFHTTPSessionManager(封装了常用的 HTTP 方法)
* GET
* POST
* UIKit + AFNetworking 分类
* NSProgress :利用KVO

- 半自动的序列化&反序列化的功能
AFURLRequestSerialization :请求的数据格式/默认是二进制的
AFURLResponseSerialization :响应的数据格式/默认是JSON格式
- 附加功能
+ 安全策略
* HTTPS
* AFSecurityPolicy
+ 网络检测
* 对苹果的网络连接检测做了一个封装
* AFNetworkReachabilityManager


AFN请求序列化和响应反序列化

请求:
AFHTTPRequestSerializer 默认的 传给服务器的就是最普通最普通的二进制
AFJSONRequestSerializer JSON格式的二进制  传给服务器的是JSON格式的二进制
AFPropertyListRequestSerializer 用得非常少,传给服务器的是Plist格式二进制,因为它不能兼容Android用得非常少

响应:
**AFHTTPResponseSerializer 普通的二进制**
**AFJSONResponseSerializer 默认的 ,按照JSON的方式去解析我们的二进制**
AFXMLParserResponseSerializer  SAX返回一个NSXMLParser(XML解析,用的不多)
AFXMLDocumentResponseSerializer (Mac OS X) Dom iOS里面几乎不用
AFPropertyListResponseSerializer 用得非常少 PList
AFImageResponseSerializer  图片,直接用SDWebImage
AFCompoundResponseSerializer 联合的


2 AFN的基本使用

发送GET请求

- (void)getDemo{
//1.创建一个管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.发送网络请求(GET/POST/PUT/DELETE/HEAD)
/**
参数1:请求的字符串
参数2:参数,get不需要参数
参数3:下载进度,一般传入nil
参数4:请求成功的回调
参数5:请求失败的回调
注意:参数4,参数5,是AFN会自动帮我们回调
*/
[manager GET:@"http://localhost/demo.json" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
/**
参数1:task一般没什么用
参数2:responseObject 响应的对象,这个是我们程序员最关心的
**/
NSLog(@"%@----%@",responseObject,[responseObject class]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
/**
参数1:task一般没什么用
参数2:error 方便我们调试
**/
NSLog(@"%@",error);
}];
}


发送POST请求

- (void)postDemo{
//1.创建一个管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.发POST请求
/**
POST参数原先是放在请求体里面

AFN放在parameters,并且的以字典的方式

其实下面就在做这两件事

NSString *postParamStr = @"username=zhangsan&password=zhang";

//2.3 设置请求体
request.HTTPBody = [postParamStr dataUsingEncoding:NSUTF8StringEncoding];
*/
NSDictionary *params = @{
@"username":@"******",
@"password":@"*****"
};
[manager POST:@"http://localhost/login.php" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}


小文件上传

不确定上传类型就写成:application/octet-stream
- (void)fileUpload{
//1.创建管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.发送请求 POST
/**
parameters 接文本参数,并且是以字典的方式
*/
NSDictionary *textDict = @{
@"status":@"大王派我去巡山"
};
[manager POST:@"http://localhost/post/upload-m.php" parameters:textDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//文件的参数,拼接到formData后面

//1.拼接第一个文件
NSURL *fileURL1 = [[NSBundle mainBundle] URLForResource:@"head1.png" withExtension:nil];

/**
参数1:文件的URL
参数2:服务器接收我们head1这个文件的字段名
参数3:保存在服务器上面的名字
参数4:上传文件的类型
*/
[formData appendPartWithFileURL:fileURL1 name:@"userfile[]" fileName:@"head1.png" mimeType:@"image/png" error:NULL];

//2.拼接第二个文件
NSURL *fileURL2 = [[NSBundle mainBundle] URLForResource:@"萌萌哒.jpg" withExtension:nil];

NSData *fileData2 = [NSData dataWithContentsOfURL:fileURL2];

/***
参数1:文件的二进制
参数2:服务器接收我们head1这个文件的字段名
参数3:保存在服务器上面的名字
参数4:上传文件的类型
*/
[formData appendPartWithFileData:fileData2 name:@"userfile[]" fileName:@"ymd.jpg" mimeType:@"application/octet-stream"];
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
NSLog(@"%@---%@",responseObject,[responseObject class]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}


访问HTTPS网站

- (void)AFNHTTPS{
//1.创建一个管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//AFN 2.5.4
/**
manager.securityPolicy.allowInvalidCertificates = YES;
**/

//AFN 2.6.1 包括现在的3.0.4,里面它实现了代理,信任服务器
manager.securityPolicy.validatesDomainName = NO;

//增加它支持的text/html,因为默认情况下不支持
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];

//3.因为https://www.XXXX.com返回回来的是html,所以直接用普通的二进制反序列化
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

//4.发送请求
[manager GET:@"https://www.XXXX.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//NSLog(@"%@",responseObject);
//反序列化成字符串
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

NSLog(@"%@",html);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}


监听网络状态

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

//1.创建一个管理者
#warning 不是监控网络状态的管理者
//    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager manager];

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];

/**
AFNetworkReachabilityStatusUnknown          未知
AFNetworkReachabilityStatusNotReachable     连接不上
AFNetworkReachabilityStatusReachableViaWWAN 蜂窝网络
AFNetworkReachabilityStatusReachableViaWiFi WiFi
*/
//2.设置网络状态改变之后的回调
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"%zd",status);
if (status==AFNetworkReachabilityStatusReachableViaWWAN) {
NSLog(@"停止下载");
}else if(status==AFNetworkReachabilityStatusReachableViaWiFi){
NSLog(@"开始下载");
}
}];

//3.开始监听
[manager startMonitoring];
}


AFN的实例:

(发送一个json格式的内容到服务器,返回类型为字符串类型)

-(void)AFNDemo{
//1.创建一个管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//改请求的方式为JSON格式的二进制
manager.requestSerializer = [AFJSONRequestSerializer serializer];

//2.发送请求 POST
/**
参数parameters
{"name":"xiaohua","age":20};
AFN内部会调用
[NSJSONSerialization dataWithJSONObject:<#(nonnull id)#> options:<#(NSJSONWritingOptions)#> error:<#(NSError * _Nullable __autoreleasing * _Nullable)#>];
把字典转在JSON格式的二进制
*/
NSDictionary *person = @{
@"name":@"kongkong",
@"age":@33
};
//1,因为返回来的是字符串,AFN默认的是json,所以让AFN接收text/plain格式
//manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain", nil];
//      manager.responseSerializer=[AFJSONRequestSerializer serializer];
//改默认的响应化方式,最普通的那种二进制之外,其它你就可以不用设置上面的接收类型,
//因为普通的二进制,那它就可以接收任务类型了
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager POST:@"http://localhost/post/postjson.php" parameters:person progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//NSLog(@"%@",responseObject);
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

NSLog(@"%@",html);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: