[iOS] 网络 - AFNetWorking
[iOS] 网络 - AFNetWorking
文章目录
- [iOS] 网络 - AFNetWorking
- AFNetworking 概述
- AFNetworking的架构
- AFNetworking 的用法
- 基础设置
- 1.初始化Manager
- 2.GET 请求
- 3.POST 请求
- 实践
- 网站中的流程
- 相关代码
AFNetworking 概述
AFNetworking 是一套适用于 iOS,macOS,watchOS 的一个网络库。AFNetworking2.0 之后的版本构建在基于 NSURLSession 的 FoundationURL 加载系统之上。AFNetworking 拓展了 Cocoa 内置的强大的高级网络抽象。
AFNetworking的架构
AFNetworking 的架构主要包含两个部分:
- AFNetworking 的核心功能
- UIKit+AFNetworking 分类功能
在这里我们主要介绍 AFNetWorking 的核心功能,AFNetworking 主要包含 6 个类:
-
AFURLSessionManager
:AFNetworking 的核心类。 -
AFHTTPSessionManager
:AFURLSessionManager
的子类,主要用于 HTTP 请求。 -
AFURLRequestSerialization
:请求序列化器,用于将参数编码为查询字符串、HTTP 正文,并根据需要设置合适的 HTTP 头部字段。 -
AFURLResponseSerialization
:响应序列化器,用于将数据解码为对象,还可以对传入的响应和数据进行验证。 -
AFSecurityPolicy
:通过安全连接评估服务器对固定的 X.509 证书和公钥的信任。 -
AFNetworkReachabilityManager
:监视网络可达性。
下面我先介绍一下 AFNetworking 的一些用法
AFNetworking 的用法
基础设置
1.初始化Manager
所有的请求方法都是 AFHTTPSessionManager 对象调用的,我们可以做一些简单的配置
- (AFHTTPSessionManager *)shareAFNManager{AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];// 超时时间manager.requestSerializer.timeoutInterval = 30.0f;// 设置请求头//[manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];// 设置接收的Content-Typemanager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];return manager;}
在这里我们初始化了 Manager 和请求序列化器还有我们响应序列化器
一般会把这么配置的封装在一个单例类里,专门管理网络请求。但是也同样可以写在 VC 里。
2.GET 请求
- (void)getSpotifyArtistInfoWithID:(NSString *)artistIDtoken:(NSString *)accessTokensuccess:(void(^)(NSDictionary *response))successfailure:(void(^)(NSError *error))failure
{NSString *urlString = [NSString stringWithFormat:@"https://api.spotify.com/v1/artists/%@", artistID];AFHTTPSessionManager *manager = [self afManager];// 设置 Authorization header[manager.requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@", accessToken]forHTTPHeaderField:@"Authorization"];[manager GET:urlStringparameters:nilheaders:nilprogress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {if (success) {success(responseObject);}}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {if (failure) {failure(error);}}];
}
在这里我给的是一个实例我们在请求的时候确实需要设置一个Authorization header 来去告诉服务器我们该怎么请求,这就是一个有请求头的 GET 请求。
3.POST 请求
- (void)doPostRequest
{//创建请求地址NSString *url=@"http://120.76.205.241:8000/news/qihoo?";//构造参数NSDictionary *parameters=@{@"kw":@"白",@"site":@"qq.com",@"apikey":@"你的key"};[[self shareAFNManager] POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {//返回请求返回进度NSLog(@"downloadProgress-->%@",uploadProgress);} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {//请求成功返回数据 根据responseSerializer 返回不同的数据格式NSLog(@"responseObject-->%@",responseObject);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {//请求失败NSLog(@"error-->%@",error);}];}
通过对比发现,基本根上面的GET方法相似。只不过在POST方法中,我们需要把相关的请求参数放到Body中。
实践
这里我也通过使用 spotify 来演示一下 GET & POST 这两个请求
在这个流程中我们首先需要阅读官方的文档,这里我会给出一个流程,一步一步的介绍,与此同时我会介绍我们每一步需要的到底是哪一个请求,以及解释用这段代码的原因。
网站中的流程
上面这个界面是我们点击进入 spotify webAPI 界面的首个界面,这时我们需要点击入门这个紫色的文字进入下面这个界面
这时我们会进入这个界面,如果我们此前没有创建过应用程序,那我们此时点击那个应用程序,请创建一个这行紫色的字,那么我们会进入下面这个画面
这时我们点击您的仪表盘这行紫色的字下面会进入这个创建 app 的画面
这里我是已经创建了一个画面,第一次创建没有该 app,这时我们需要点击创建 app这样就会进入这个画面
填写完上面的信息即可创建一个 app
创建完以后我们会获得这样一个界面
相关代码
在这里我们需要 clientID 还有 client secret 因为这是我们获得 access token 的一个关键步骤。这里引出了 access token ,这个是我们获取 spotify 的 web API 的一种方式,这里获取他我们需要用一个 post 请求来获取对应的 access token ,下面这段代码是使用clientID 还有 client secret 来发送 post 请求的代码。
#import "ViewController.h"
#import <AFNetworking/AFNetworking.h>@interface ViewController ()@property (nonatomic, strong) NSString *accessToken;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];NSString *clientID = @"c4370b7bcb6f44f6aaf9e8b102f90b1c"; // 你的 Spotify 客户端 IDNSString *clientSecret = @"caae12884c9c4843819829313e5ae6dc"; // 你的 Spotify 客户端密钥[self fetchAccessTokenWithClientID:clientID clientSecret:clientSecret];
}// 使用 client_credentials 获取 access_token
- (void)fetchAccessTokenWithClientID:(NSString *)clientIDclientSecret:(NSString *)clientSecret {NSString *urlString = @"https://accounts.spotify.com/api/token";NSDictionary *parameters = @{@"grant_type": @"client_credentials", // 使用客户端凭证流@"client_id": clientID, // 你的 Spotify 客户端 ID@"client_secret": clientSecret // 你的 Spotify 客户端密钥};// 创建 AFHTTPSessionManager 实例AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];// 设置请求头 Content-Type[manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];// 设置响应处理manager.responseSerializer = [AFJSONResponseSerializer serializer];// 发起 POST 请求[manager POST:urlStringparameters:parametersheaders:nilprogress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {// 成功获取 access_tokenNSString *accessToken = responseObject[@"access_token"];self.accessToken = accessToken; // 保存 access_tokenNSLog(@"Access Token: %@", accessToken); // 打印 access_token}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"Error fetching access token: %@", error);}];
}@end
在这里我把 post 请求集成到了 viewController 中,在这里如果想更加完全一点可以加上 Authorization 字段传递 Bearer token。
下面的代码是 GET 请求他用到了单例模式来请求
#import <Foundation/Foundation.h>
#import <AFNetworking/AFNetworking.h>NS_ASSUME_NONNULL_BEGIN@interface NetWorkManager : NSObject
+(instancetype)sharedManager;
- (void)getArtistInfoWithID:(NSString *)artistID token:(NSString *)accessToken success:(void (^)(NSDictionary *response))success failure:(void (^)(NSError *error))failure;
@endNS_ASSUME_NONNULL_END
#import "NetWorkManager.h"
#import <AFNetworking/AFNetworking.h>@implementation NetWorkManager+ (instancetype)sharedManager {static NetWorkManager *instance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[NetWorkManager alloc] init];});return instance;
}// 创建 AFHTTPSessionManager 实例
- (AFHTTPSessionManager *)afManager {AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];manager.requestSerializer = [AFJSONRequestSerializer serializer];manager.requestSerializer.timeoutInterval = 30.0f;manager.responseSerializer = [AFJSONResponseSerializer serializer];manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];return manager;
}// 通过 access_token 获取歌手信息
- (void)getArtistInfoWithID:(NSString *)artistID token:(NSString *)accessToken success:(void (^)(NSDictionary *response))success failure:(void (^)(NSError *error))failure {NSString *urlString = [NSString stringWithFormat:@"https://api.spotify.com/v1/artists/%@", artistID];AFHTTPSessionManager *manager = [self afManager];// 设置请求头,Authorization 字段带上 Bearer token[manager.requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@", accessToken] forHTTPHeaderField:@"Authorization"];[manager GET:urlStringparameters:nilheaders:nilprogress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {// 成功,返回歌手数据if (success) {success(responseObject);}} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {// 失败,返回错误if (failure) {failure(error);}}];
}@end
这里使用了一个单例模式,使用单例模式我们就可以在任意一个位置调用,而且不需要再一次创建减少了内存的消耗。
这里是我请求出来的 accesstoken 还有歌手的 json 文件
下面我给出一个流程基本覆盖了 GET 和 POST 请求
- 创建 AFHTTPSessionManager 实例:
- 使用 AFHTTPSessionManager 创建实例是必须的,因为它封装了所有的 HTTP 请求逻辑。
- 设置请求头(可选,依据需求):
- Content-Type:通常,对于 GET 请求,不需要设置 Content-Type,因为 GET 请求一般不包含请求体,Content-Type 主要用于 POST 请求。除非接口需要特定的请求头(比如某些 API 可能要求),否则可以跳过这一步。
- Authorization:如果接口需要身份验证(如 Spotify API),则必须设置 Authorization 头部。这是 必需的,尤其是当你需要访问受保护资源时。
- 设置响应处理(responseSerializer):
- 你需要设置适当的 responseSerializer,比如 AFJSONResponseSerializer 用来解析 JSON 格式的响应。
- 如果接口返回的是 JSON 格式的数据,你的代码已经正确地设置了 responseSerializer 为 AFJSONResponseSerializer。
- 发起 GET 请求:
- 使用 manager GET 发起 GET 请求。你会传入请求的 URL 和可能的参数。
- GET 请求的参数一般放在 URL 中,因此 参数应该通过 URL 拼接,或者通过 parameters 字典来传递。
- 成功和失败的回调处理:
- 成功回调 (success):在请求成功时,处理返回的数据。
- 失败回调 (failure):处理请求失败时的错误信息。