当前位置: 首页 > news >正文

【iOS】AFNetworking

  • 文件构成
  • AFURLSessionManager
  • AFHTTPSessionManager
    • 一次完整的GET请求过程
      • 1. 初始化和配置
      • 2. GET请求
      • 3. 添加请求头的GET
    • POST请求
  • 举例:Spotify内容的获取

Table of contents generated with markdown-toc

文件构成

AFNetworking的构成很简单,主要就四个部分:

  1. Manager : 负责处理网络请求的两个Manager,主要实现都在AFURLSessionManager中。

  2. Reachability : 网络状态监控。

  3. Security : 处理网络安全和HTTPS相关的。

  4. Serialization : 请求和返回数据的格式化器。

AFURLSessionManager

在AFN中,网络请求的manager主要有AFHTTPSessionManager 和 AFURLSessionManager 构成,二者为父子关系。这两个类职责划分很清晰,父类负责处理一些基础的网络代码,并且接受NSURLRequest 对象,而子类则负责处理和http协议有关的逻辑。

类名继承关系主要用途适用场景
AFURLSessionManager基类(直接基于 NSURLSession 封装)管理 session 和 task,偏底层下载、上传、自定义请求、复杂任务管理
AFHTTPSessionManager继承自 AFURLSessionManager封装了常见的 HTTP 请求方法普通 HTTP 请求(GET/POST/PUT/DELETE),业务开发常用

AFHTTPSessionManager

AFNetworking 中使用最高频率的是 AFHTTPSessionManager,负责各种 HTTP 请求的发起和处理,它继承自 AFURLSessionManager,是各种请求的直接执行者。
请添加图片描述

一次完整的GET请求过程

这里以 GET 为例,展示发起一次 GET 请求的具体过程。
AFHTTPSessionManager 支持创建 GET、HEAD、POST、PUT、PATCH、DELETE 等请求,其中 GET 请求支持以下方法发起

- (NSURLSessionDataTask *)GET:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary <NSString *, NSString *> *)headersprogress:(nullable void (^)(NSProgress * _Nonnull))downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"URLString:URLStringparameters:parametersheaders:headersuploadProgress:nildownloadProgress:downloadProgresssuccess:successfailure:failure];[dataTask resume];return dataTask;
}

1. 初始化和配置

首先,要导入AFNetworking头文件
请添加图片描述

默认配置设置:

AFHTTPRequestSerializer请求序列化
AFJSONResponseSerializer用于响应序列化

  1. 初始化Manager:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//本质上是调用:
[[AFHTTPSessionManager alloc] initWithBaseURL:nil sessionConfiguration:nil];
  1. 请求序列化器:

决定请求参数如何拼接/序列化

默认是AFHTTPRequestSerializer(普通HTTP表单)

manager.requestSerializer = [AFJSONRequestSerializer serializer]; //参数转为 JSON
manager.requestSerializer.timeoutInterval = 15; //超时时间
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //自定义Header
  1. 响应序列化器:

决定返回数据如何解析(默认是 AFJSONResponseSerializer,会把 JSON 自动转成 NSDictionary / NSArray。)

manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];

AFHTTPSessionManager使用序列化器在本机对象和网络表示之间进行转换:

requestSerializer属性(类型为AFHTTPRequestSerializer)将参数转换为URL查询字符串或HTTP正文内容
responseSerializer属性(类型为AFHTTPResponseSerializer)将原始响应数据转换为可用的对象
请添加图片描述
默认情况下,AFHTTPSessionManager配置为:
AFHTTPRequestSerializer请求序列化
AFJSONResponseSerializer用于响应序列化

也可以根据API要求自定义:

// For working with JSON APIs
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];// For XML services
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];// For image downloads
manager.responseSerializer = [AFImageResponseSerializer serializer];

2. GET请求

请添加图片描述
示例:提出GET请求:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];// 发起 GET 请求
[manager GET:urlString parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSLog(@"数据如下: %@", responseObject);//接下来可以在这里处理返回的数据
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"错误: %@", error);
}];

URLString(NSString类型):表示要发送GET请求的URL字符串,即请求的目标地址。
parameters(可选的id类型):包含GET请求的参数,这些参数会附加到URL字符串中,以便服务器可以根据这些参数返回相应的数据。它通常是一个NSDictionary或其他数据结构,其中包含键值对,表示请求参数。
headers(可选的NSDictionary类型):包含HTTP请求头的字典。HTTP请求头通常包含与请求相关的信息,例如授权令牌、用户代理、接受的数据类型等。这里的参数允许你自定义请求头。
downloadProgress(可选的NSProgress类型块):一个块对象,用于跟踪下载进度。这个块会在下载数据时被调用,可以用来更新UI或记录下载进度等。
success(可选的块):一个成功回调块,当请求成功完成时会被调用。这个块通常接受两个参数,第一个参数是包含响应数据的NSURLSessionDataTask对象,第二个参数是响应数据,通常是一个NSDictionary或其他数据结构。
failure(可选的块):一个失败回调块,当请求失败时会被调用。这个块通常接受两个参数,第一个参数是包含请求任务信息的NSURLSessionDataTask对象,第二个参数是一个NSError对象,包含了关于请求失败的信息。
在这个方法内部,首先通过调用dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:方法创建一个NSURLSessionDataTask对象,然后使用resume方法开始执行这个任务(发送GET请求),最后返回该任务对象,以便调用者可以对任务进行进一步操作或取消。

详细说说parameters:看着文字可能会一头雾水,我们来句一个例子
在天气预报的请求中我们时常会遇到
请添加图片描述
我们需要自己手动拼接字符串,而使用parameters后,我们可以请添加图片描述
这里补充一个细节问题:APIURL是接口的基本路径,而parameters是传给接口的查询参数或请求体,AFN会自动把parameters序列化并拼接到URL或body,但是前提是必须有一个基础URL来承载这些参数。
至于headers,会在下面讲解。

3. 添加请求头的GET

在HTTP请求中,每个请求头都是一对 键值对,用来给服务器传递额外的信息

HTTP请求示例:

GET /api/data?param1=value1 HTTP/1.1
Host: example.com
Authorization: Bearer BQAG8…
Content-Type: application/json
App-Name: MyApp
App-Key: 123456

里面的Authorization / Content - Type / App-Name / App- Key 都是请求头,他们不属于URL,也不属于请求体,只是告诉服务器如何请求

Header 名称用途
Authorization身份验证。比如 OAuth 的 Bearer token,告诉服务器你是谁,有访问权限。
Content-Type告诉服务器请求体的数据类型,如 JSON、表单或 XML。
Accept告诉服务器你希望返回什么类型的数据,例如 JSON。
User-Agent告诉服务器客户端信息,例如浏览器类型、App 名称。
自定义 Header(如 App-Name, App-Key)自定义数据传递,可用于验证 API Key 或标识请求来源。
-(void) getRequestWithHeader {NSString *urlString = @"http://";AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];manager.responseSerializer = [AFJSONResponseSerializer serializer];[manager.requestSerializer setValue:(nullable NSString *) forHTTPHeaderField:(nonnull NSString *)];[manager GET:urlString parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {NSLog(@"%@", downloadProgress);} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSLog(@"%@",responseObject);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"%@", error);}];
}

Q1 : 前文的Manger基础设置中也能决定返回数据如何解析,和请求头里的Accept是什么关系呢?

Accept请求头,是高速服务器希望接收的数据类型。比如:
application/json → 希望返回 JSON
text/html → 希望返回 HTML
application/xml → 希望返回 XML

而AFN的response Serializer决定了客户端如何解析服务器返回的数据:
AFJSONResponseSerializer → 把返回数据解析成 NSDictionary / NSArray
AFHTTPResponseSerializer → 只返回 NSData
AFXMLParserResponseSerializer → 返回 NSXMLParser

总而言之:Accept决定服务器返回什么格式, 而response Serializer决定客户端如何解析这个格式

Q2:前面说过,在GET请求的Headers是一个请求头的字典,为什么通过request Serializer设置请求头,而headers设置为nil?

通过request Serializer设置的请求头,是给整个manager设置的默认请求头,之后这个manager发出的所有请求(GET / POST / PUT)都会带上这个请求头。
而headers是在单个请求中穿headers参数,仅给这一条GET请求加请求头,和request Serializer不冲突,优先级更高

POST请求

GET请求通常用于获取资源,不改变服务器状态;而POST请求多用于创建和修改资源,可能会改变服务器状态

POST比GET通常会多一个请求体,POST中,参数放在请求体中,服务器通过body解析参数。
而GET的参数全部放在URL上,服务器通过URL解析参数。

#import <AFNetworking/AFNetworking.h>- (void)doPostRequest {//请求 URLNSString *urlString = @"https://api.example.com/v1/login";//请求参数NSDictionary *parameters = @{@"username": @"Tom",@"password": @"123456"};//创建 managerAFHTTPSessionManager *manager = [AFHTTPSessionManager manager];   manager.requestSerializer = [AFJSONRequestSerializer serializer];manager.responseSerializer = [AFJSONResponseSerializer serializer];//可以加请求头[manager.requestSerializer setValue:@"Bearer YOUR_ACCESS_TOKEN" forHTTPHeaderField:@"Authorization"];[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];//发起 POST 请求[manager POST:urlStringparameters:parametersheaders:nilprogress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSLog(@"请求成功: %@", responseObject);}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"请求失败: %@", error);}];
}

举例:Spotify内容的获取

以Spotify为例:查看官方文档是很重要的一环。
我们通过API访问数据,需要一个访问令牌

请添加图片描述
请添加图片描述

由图可知,访问令牌需要我们获取ClientID和secret,此过程在网站内进行,当前跳过。
• -X POST → HTTP POST 请求
• -H → 设置请求头
• -d → 请求体参数(form-urlencoded)
我们按照步骤一步步完成

-(void)fetchAccessTokenWithClientID:(NSString *)clientIDclientSecret:(NSString *)clientSecret {NSString *urlString = @"https://accounts.spotify.com/api/token";NSDictionary *parameters = @{@"grant_type": @"client_credentials",@"client_id": clientID,@"client_secret": clientSecret};AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];manager.requestSerializer = [AFHTTPRequestSerializer serializer];[manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];manager.responseSerializer = [AFJSONResponseSerializer serializer];[manager POST:urlStringparameters:parametersheaders:nilprogress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSString *accessToken = responseObject[@"access_token"];self.accessToken = accessToken;NSLog(@"Access Token: %@", accessToken);}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"Error fetching access token: %@", error);}];
}

运行后得出结果:
请添加图片描述
请添加图片描述
在获取到accessToken后,我们在按照官网的流程,GET到对应信息。

- (void)fetchHotSongWithID:(NSString *)artistIDmarket:(NSString *)market {NSString *urlString = [NSString stringWithFormat:@"https://api.spotify.com/v1/artists/%@/top-tracks?market=%@", artistID, market];AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];[manager.requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@", self.accessToken] forHTTPHeaderField:@"Authorization"];[manager GET:urlString parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSLog(@"Hot songs info: %@", responseObject);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"Error fetching artist info: %@", error);}];
}

因为输入的是贾斯汀比伯的ID 最终我们成功请求到他的信息:
请添加图片描述
请添加图片描述


文章转载自:

http://k3J3wzdh.bhdhL.cn
http://dtP5oxRU.bhdhL.cn
http://bjHH6EvT.bhdhL.cn
http://F69jAYtx.bhdhL.cn
http://j2I8NttZ.bhdhL.cn
http://9EphXHjC.bhdhL.cn
http://c88vHkuV.bhdhL.cn
http://IzOsBh1c.bhdhL.cn
http://Yxpku5vY.bhdhL.cn
http://Gm8fTyq5.bhdhL.cn
http://hLpG6nIN.bhdhL.cn
http://54wlnhGk.bhdhL.cn
http://MtPUzDRc.bhdhL.cn
http://jpGhFf79.bhdhL.cn
http://37edzl82.bhdhL.cn
http://BbownZVr.bhdhL.cn
http://8HkbfPM7.bhdhL.cn
http://33LtO9qe.bhdhL.cn
http://Bf48Ctlv.bhdhL.cn
http://VwzJ3hW9.bhdhL.cn
http://YVu2K5aK.bhdhL.cn
http://fAOlYppe.bhdhL.cn
http://GlAJyZgZ.bhdhL.cn
http://GwMhX9Dt.bhdhL.cn
http://L2aSQzOF.bhdhL.cn
http://1WzGrqPG.bhdhL.cn
http://YcRKYv3R.bhdhL.cn
http://yZYCoKqe.bhdhL.cn
http://xYVV4R5F.bhdhL.cn
http://W9uQ38NN.bhdhL.cn
http://www.dtcms.com/a/381486.html

相关文章:

  • 【Qt】Window环境下搭建Qt6、MSVC2022开发环境(无需提前安装Visual Studio)
  • 惠普打印机驱动下载安装教程?【图文详解】惠普打印机驱动下载官网?电脑连接惠普打印机?
  • 【PHP7内核剖析】-1.1 PHP概述
  • ajax
  • STM32之RTOS移植和使用
  • [VL|RIS] RSRefSeg 2
  • Hadoop伪分布式环境配置
  • Python中的深拷贝与浅拷贝
  • 冒泡排序与选择排序以及单链表与双链表
  • 垂直大模型的“手术刀”时代:从蒙牛MENGNIU.GPT看AI落地的范式革命
  • 【高并发内存池】六、三种缓存的回收内存过程
  • 缓存常见问题与解决方案
  • 【pure-admin】登录页面代码详解
  • 初学鸿蒙笔记-真机调试
  • 反序列化漏洞详解
  • 使用 vue-virtual-scroller 实现高性能传输列表功能总结
  • python 实现 transformer 的 position embeding
  • 003 cargo使用
  • 制作一个简单的vscode插件
  • 【算法详解】:从 模拟 开始打开算法密匙
  • kubeadm搭建生产环境的单master多node的k8s集群
  • RocketMQ存储核心:MappedFile解析
  • 7.k8s四层代理service
  • Stable Virtual Camera:Stability AI等推出的AI模型 ,2D图像轻松转3D视频
  • Golang并发编程及其高级特性
  • 给AI配一台手机+电脑?智谱AutoGLM上线!
  • 怎么在手机上选择一款好用的桌面待办清单工具
  • 傲琪人工合成石墨片:破解智能手机散热困境的创新解决方案
  • LeetCode 刷题【74. 搜索二维矩阵、75. 颜色分类、76. 最小覆盖子串】
  • 【Linux】【实战向】Linux 进程替换避坑指南:从理解 bash 阻塞等待,到亲手实现能执行 ls/cd 的 Shell