将 CocoaPods 安装后,按照 CocoaPods 的使用说明就可以将 AFNetworking 第三方集成到工程中,具体请看上篇博客iOS学习46之第三方CocoaPods的安装和使用(通用方法)
AFNetworking是一个 在iOS开发中 使用非常多网络开源库,是一个轻量级的网络请求API类库。
适用于iOS以及Mac OS X。它构建于在(Apple iOS开发文档) NSURLSession , NSOperation , 以及其他熟悉的Foundation技术之上,核心代码: AFHTTPSessionManager。
它拥有良好的架构,丰富的api,以及模块化构建方式,使得使用起来非常轻松。
官方链接http://cocoadocs.org/docsets/AFNetworking/1.3.0/
AFHTTPSessionManager是核心网络请求的管理类,用于管理 GET 和 POST 请求
AFHTTPSessionManager对象的声明和懒加载代码:
#import "ViewController.h" // 网络的请求头文件 #import <AFNetworking/AFNetworking.h> @interface ViewController () /// 用于网络请求的session对象 @property (nonatomic, strong) AFHTTPSessionManager *session; @end @implementation ViewController // 懒加载 - (AFHTTPSessionManager *)session { if (!_session) { _session = [AFHTTPSessionManager manager]; // 设置请求接口回来的时候,支持什么类型的数据 _session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"application/x-json",@"text/html", nil]; } return _session; } @end
在进行网络监测的时候,首先应该先判断网络监测是否打开,如果没有打开,先要打开监测
- (void)startMonitoring; // 打开网络监测 - (void)stopMonitoring; // 关闭网络监测
接下来就判断当前的网络状态,AFNetworking有几种不同的网络状态
// 几种不同的网络状态 typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1, // 当前网络处于未知状态,手机没有信号 AFNetworkReachabilityStatusNotReachable = 0, // 当前网络处于未连接状态,手机没有开流量或开WiFi AFNetworkReachabilityStatusReachableViaWWAN = 1, // 手机流量网络 AFNetworkReachabilityStatusReachableViaWiFi = 2, // WiFi状态 };
实例代码:
#pragma mark - 网络监测按钮的响应方法 - (IBAction)networkMonitoringAction:(UIButton *)sender { if (!isOPen) { // 打开网络监测的方法 [[AFNetworkReachabilityManager sharedManager] startMonitoring]; isOPen = YES; } else { // 关闭网络监测 [[AFNetworkReachabilityManager sharedManager] stopMonitoring]; isOPen = NO; } // 接下来判断当前是WiFi状态还有3g状态,网络不可用状态 [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusUnknown: NSLog(@"当前网络处于未知状态,手机没有信号"); break; case AFNetworkReachabilityStatusNotReachable: NSLog(@"当前网络处于未连接状态,手机没有开流量或开WiFi"); break; case AFNetworkReachabilityStatusReachableViaWWAN: NSLog(@"手机流量网络"); break; case AFNetworkReachabilityStatusReachableViaWiFi: NSLog(@"WiFi状态"); break; default: break; } }]; }
AFNetworking1.3.0 不再想以前一样一个 GET 请求需要很多的类参与,这里这需要一个 AFHTTPSessionManager 的方法就可以完成
方法:
- (NSURLSessionDataTask *)GET:(NSString *)URLString // get请求的网址 parameters:(id)parameters // 拼接的参数 progress:(void (^)(NSProgress * _Nonnull))downloadProgress // 下载的进度 success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success // 请求成功 failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure // 请求失败
实例代码:
#pragma mark - GET请求的响应方法 - (IBAction)getRequestAction:(id)sender { [self.session GET:@"http://api.yhouse.com/m/city/dynmiclist" // get请求的网址 parameters:nil // 拼接的参数 progress:^(NSProgress * _Nonnull downloadProgress) { // 下载的进度 NSLog(@"下载的进度"); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 请求成功 NSLog(@"请求成功"); // 处理数据... NSDictionary *reusltDict = responseObject[@"data"]; NSArray *resultArray = reusltDict[@"allCity"]; for (NSDictionary *dict in resultArray) { NSLog(@"name = %@", dict[@"name"]); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // 请求失败 NSLog(@"请求失败"); }]; }
同GET请求一样,POST请求也是如此,不过POST请求需要拼接参数,一般情况下参数为一个字典
方法:
- (NSURLSessionDataTask *)POST:(NSString *)URLString // post请求的网址 parameters:(id)parameters // 拼接的参数body progress:(void (^)(NSProgress * _Nonnull))uploadProgress // 上传的进度 success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success // 请求成功 failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure // 请求失败
实例代码:
#pragma mark - POST请求的响应方法 - (IBAction)postRequestAction:(id)sender { NSString *urlStr = @"http://m.taskwedo.com/API/wedo1/wedo.php"; NSMutableDictionary *dict = @{ @"do" : @"pri_memberlist", @"member_id" : @"zpHr2dsRvQQxYJxo2", @"workspace_id" : @"ILfYpE4Dhs2gWcuQx" }.mutableCopy; [self.session POST:urlStr // post请求的网址 parameters:dict // 拼接的参数body progress:^(NSProgress * _Nonnull uploadProgress) { // 上传的进度 NSLog(@"上传的进度"); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 请求成功 NSLog(@"请求成功"); NSDictionary *reusltDict = responseObject[@"res"]; NSArray *keyArray = reusltDict.allKeys; for (NSString *key in keyArray) { NSArray *resultArray = reusltDict[key]; for (NSDictionary *dict in resultArray) { NSLog(@"username = %@", dict[@"username"]); } } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // 请求失败 NSLog(@"请求失败"); }]; }
注意:URL字符串或body体中如果有特殊字符或者中文字符,AFNETWorking并没有做UTF8的转码,需要:
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
commonContent = [commonContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
代码实例:
#pragma mark - POST请求2的响应方法 - (IBAction)postRequest2Action:(id)sender { NSString *urlStr = @"http://m.taskwedo.com/API/wedo1/wedo.php"; NSString *commonContent = @"类模块计划用到第三部分中,待提问、回答积累到一定数量时,便于大家的问题的快速查找,所以提问部分暂时不加入这个"; commonContent = [commonContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; // 当body体或URL中出现汉字时使用 NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setValue:@"" forKey:@"address"]; [dict setValue:commonContent forKey:@"comment"]; [dict setValue:@"add_comment" forKey:@"do"]; [dict setValue:@"task" forKey:@"kind"]; [dict setValue:@"zpHr2dsRvQQxYJxo2" forKey:@"member_id"]; [dict setValue:@"" forKey:@"other"]; [dict setValue:@"55a47e79ec25e3641" forKey:@"task_id"]; [self.session POST:urlStr parameters:dict progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"上传成功"); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"请求成功:%@", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"请求失败"); }]; }