AFNnetworking详解

简介: <div id="cnblogs_post_body"> <h1 id="afn">AFN</h1> <h2 id="afn">一、什么是AFN</h2> <ul><li>全称是AFNetworking,是对NSURLConnection的一层封装</li><li>虽然运行效率没有ASI高,但是使用比ASI简单</li><li> <p>在iOS开发中,使用比较广泛</p>

AFN

一、什么是AFN

二、AFN结构

  • NSURLConnection

    • 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基本使用

1.AFHTTPSessionManager

  • 是AFN中最重要的对象之一
  • 封装了HTTP请求的常见处理
  • GET\POST请求
  • 解析服务器的响应数据

创建AFHTTPSessionManager

AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];

AFHTTPSessionManager的GET\POST请求

// GET请求
/*
     http://120.25.226.186:32812/login?username=520it&pwd=520it
     第一个参数: 请求的地址  http://120.25.226.186:32812/login
     第二个参数: 请求的参数  username=520it&pwd=520it
     第三个参数: 请求成功的回调
     第四个参数: 请求失败的回调
     只要利用AFN发送请求, 如果服务器返回的是JSON数据, 那么AFN会自动将JSON转会成OC对象返回给我们
     */
- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure // POST请求 - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

代码示例

// GET
- (void)get2
{
    // 1.创建AFN管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    // 2.利用AFN管理者发送请求
    NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; [manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"请求成功---%@", responseObject); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"请求失败---%@", error); }]; } // POST - (void)post2 { // 1.创建AFN管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // 2.利用AFN管理者发送请求 NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; [manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"请求成功---%@", responseObject); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"请求失败---%@", error); }]; }

2.AFHTTPRequestOperationManager

创建AFHTTPRequestOperationManager

// 1.创建AFN管理者
    // AFHTTPRequestOperationManager内部包装了NSURLConnection
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

AFHTTPRequestOperationManager的GET\POST请求

// GET
- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(id)parameters
                      success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure // POST请求 - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

代码示例

- (void)get
{
    // 1.创建AFN管理者
    // AFHTTPRequestOperationManager内部包装了NSURLConnection
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    // 2.利用AFN管理者发送请求
    NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; [manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"请求成功---%@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"请求失败---%@", error); }]; } - (void)post { // 1.创建AFN管理者 // AFHTTPRequestOperationManager内部包装了NSURLConnection AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 2.利用AFN管理者发送请求 NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; [manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"请求成功---%@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"请求失败---%@", error); }]; }

四、AFN文件下载

// 执行下载文件的方法,可以监控下载进度
- (void)downLoadMonitor
{
    // 1.创建网络管理者
    // AFHTTPSessionManager 基于NSURLSession
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    // 2.利用网络管理者下载数据 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]]; /* destination - targetPath: 系统给我们自动写入的文件路径 - block的返回值, 要求返回一个URL, 返回的这个URL就是剪切的位置的路径 completionHandler - url :destination返回的URL == block的返回的路径 */ /* @property int64_t totalUnitCount; 需要下载文件的总大小 @property int64_t completedUnitCount; 当前已经下载的大小 */ NSProgress *progress = nil; NSURLSessionDownloadTask *downTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename]; return [NSURL fileURLWithPath:path]; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"%@",filePath.absoluteString); }]; /* 要跟踪进度,需要使用 NSProgress,是在 iOS 7.0 推出的,专门用来跟踪进度的类! NSProgress只是一个对象!如何跟踪进度!-> KVO 对属性变化的监听! @property int64_t totalUnitCount; 总单位数 @property int64_t completedUnitCount; 完成单位数 */ // 给Progress添加监听 KVO [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil]; // 3.启动任务 [downTask resume]; } // 收到通知调用的方法 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)object change:(NSDictionary *)change context:(void *)context { NSLog(@"%f",1.0 * object.completedUnitCount / object.totalUnitCount); // 回到主队列刷新UI dispatch_async(dispatch_get_main_queue(), ^{ self.progress.progress = 1.0 * object.completedUnitCount / object.totalUnitCount; }); }

五、AFN序列化

  • 默认是JSON数据,接收类型是JSON

    • 如果接收的类型和返回的类型不匹配会报错
  // 1.创建AFN管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    // 默认请求二进制
    // 默认响应是JSON

    // 告诉AFN,支持接受 text/xml 的数据
    // [AFJSONResponseSerializer serializer].acceptableContentTypes = [NSSet setWithObject:@"text/xml"]; // 告诉AFN如何解析数据 // 告诉AFN客户端, 将返回的数据当做JSON来处理,默认的是以JSON处理 // manager.responseSerializer = [AFJSONResponseSerializer serializer]; // 告诉AFN客户端, 将返回的数据当做XML来处理 // manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; // 告诉AFN客户端, 将返回的数据当做而进行来数据 (服务器返回什么就是什么) manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 

六、AFN文件上传

// formData: 专门用于拼接需要上传的数据
- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
     constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

AFN上传文件代码示例

    // 1.创建网络管理者
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 2.利用网络管理者上传数据
    NSDictionary *dict = @{@"username":@"Syl"}; // formData: 专门用于拼接需要上传的数据 [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock: ^void(id<AFMultipartFormData> formData) { /* Data: 需要上传的数据 name: 服务器参数的名称 fileName: 文件名称 mimeType: 文件的类型 */ UIImage *image =[UIImage imageNamed:@"minion_02"]; NSData *data = UIImagePNGRepresentation(image); [formData appendPartWithFileData:data name:@"file" fileName:@"abc.png" mimeType:@"image/png"]; /* NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/CertificateSigningRequest.certSigningRequest"]; // 任意的二进制数据MIMEType application/octet-stream // [formData appendPartWithFileURL:url name:@"file" fileName:@"abc.cer" mimeType:@"application/octet-stream" error:nil]; [formData appendPartWithFileURL:url name:@"file" error:nil]; */ } success:^void(NSURLSessionDataTask * task, id responseObject) { // 请求成功 NSLog(@"请求成功 %@", responseObject); } failure:^void(NSURLSessionDataTask * task, NSError * error) { // 请求失败 NSLog(@"请求失败 %@", error); }];

七、监控联网状态

1.AFN监控联网状态

联网状态status

// 2.设置监听
    /*
     AFNetworkReachabilityStatusUnknown          = -1,  未识别
     AFNetworkReachabilityStatusNotReachable     = 0,   未连接
     AFNetworkReachabilityStatusReachableViaWWAN = 1,   3G
     AFNetworkReachabilityStatusReachableViaWiFi = 2,  wifi
     */

示例代码

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];

// 提示:要监控网络连接状态,必须要先调用单例的startMonitoring方法
[manager startMonitoring];

[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    NSLog(@"%d", status);
}];

2.Reachability监控联网状态苹果提供,导入这两个类使用

    // 1.检测wifi状态
    Reachability *wifi = [Reachability reachabilityForLocalWiFi];

    // 2.检测手机是否能上网络(WIFI\3G\2.5G)
    Reachability *conn = [Reachability reachabilityForInternetConnection];

    // 3.判断网络状态
    if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi NSLog(@"有wifi"); } else if ([conn currentReachabilityStatus] != NotReachable) { // 没有使用wifi, 使用手机自带网络进行上网 NSLog(@"使用手机自带网络进行上网"); } else { // 没有网络 NSLog(@"没有网络"); }

①判断联网状态

// 用WIFI
// [wifi currentReachabilityStatus] != NotReachable
// [conn currentReachabilityStatus] != NotReachable

// 没有用WIFI, 只用了手机网络
// [wifi currentReachabilityStatus] == NotReachable // [conn currentReachabilityStatus] != NotReachable // 没有网络 // [wifi currentReachabilityStatus] == NotReachable // [conn currentReachabilityStatus] == NotReachable

②实时监听网络状态

#import "ViewController.h"
#import "Reachability.h"

@interface HMViewController () @property (nonatomic, strong) Reachability *conn; @end @implementation HMViewController - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkState) name:kReachabilityChangedNotification object:nil]; self.conn = [Reachability reachabilityForInternetConnection]; [self.conn startNotifier]; } - (void)dealloc { [self.conn stopNotifier]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)checkNetworkState { // 1.检测wifi状态 Reachability *wifi = [Reachability reachabilityForLocalWiFi]; // 2.检测手机是否能上网络(WIFI\3G\2.5G) Reachability *conn = [Reachability reachabilityForInternetConnection]; // 3.判断网络状态 if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi NSLog(@"有wifi"); } else if ([conn currentReachabilityStatus] != NotReachable) { // 没有使用wifi, 使用手机自带网络进行上网 NSLog(@"使用手机自带网络进行上网"); } else { // 没有网络 NSLog(@"没有网络"); } } @end
目录
相关文章
|
小程序 JavaScript 算法
开源轻量级 IM 框架 MobileIMSDK 的微信小程序端已发布!
MobileIMSDK - 微信小程序端是一套基于微信原生 WebSocket 的即时通讯库:
179 0
|
机器学习/深度学习 Web App开发 编解码
最高增强至1440p,阿里云发布端侧实时超分工具,低成本实现高画质
近日,阿里云机器学习PAI团队发布一键端侧超分工具,可实现在设备和网络带宽不变的情况下,将移动端视频分辨率提升1倍,最高可增强至1440p,将大幅提升终端用户的观看体验,该技术目前已在优酷、夸克、UC浏览器等多个APP中广泛应用。
最高增强至1440p,阿里云发布端侧实时超分工具,低成本实现高画质
|
10月前
|
存储 机器学习/深度学习 人工智能
本地部署开源大模型的完整教程:LangChain + Streamlit+ Llama
在过去的几个月里,大型语言模型(llm)获得了极大的关注,这些模型创造了令人兴奋的前景,特别是对于从事聊天机器人、个人助理和内容创作的开发人员。
5728 1
|
8月前
|
Java 应用服务中间件 Maven
SpringBoot启动流程步骤总结
SpringBoot启动流程步骤总结
148 0
|
11月前
|
iOS开发
iOS快速实现环形渐变进度条
进度条相信我们大家都不陌生,往往我们很多时候需要使用到圆形进度条。这篇文章给大家分享了利用ios如何快速实现环形进度条,下面来一起看看。
|
11月前
|
机器学习/深度学习 iOS开发 计算机视觉
iOS MachineLearning 系列(16)—— 几个常用的图片分类CoreML模型
对于图片识别分类的模型来说,其输入和输出都一样,输入都为图像参数,输入为两部分,一部分为最佳预测结果,一部分为可能得预测结果及其可信度。
258 0
|
11月前
|
缓存 图形学 iOS开发
iOS 离屏渲染
iOS 离屏渲染
116 0
|
消息中间件 NoSQL Kafka
Flutter基础widgets教程-Padding篇
Flutter基础widgets教程-Padding篇
208 0
|
前端开发
写给小白的Figma插件开发教程(1)
写给小白的Figma插件开发教程(1)
1347 0