IOS 使用Block二次封装AFNetworking 3.0详解
1. 前言
AFNetworking
是 iOS 开发中常用的网络请求库,其基于 NSURLConnection
和 NSURLSession
,提供了更加简单方便的接口,使得开发者可以方便地进行网络请求。
但是,AFNetworking
中的回调方式为传统的代理方法,不够便捷。为此,我们可以进行二次封装,使用 Block
作为网络请求结果的回调方式,在开发中更为方便。
本文将详细讲解如何使用 Block
二次封装 AFNetworking
,并提供示例说明。
2. 封装过程
2.1 创建网络请求类
先创建一个网络请求类 NetRequest
。这个类提供网络请求的基本功能,包括 GET 请求、POST 请求、上传文件等主要的请求功能。
这个网络请求类可以使用单例模式,保证全局只有一个实例。
@interface NetRequest : NSObject
+ (instancetype)getInstance;
- (void)requestWithMethod:(NSString *)method
url:(NSString *)url
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
@end
2.2 实现网络请求类
在实现网络请求类时,我们需要使用 AFNetworking
中提供的 AFHTTPSessionManager
类。我们可以将这个类的实例作为属性加入到我们的网络请求类中。
@interface NetRequest()
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@end
@implementation NetRequest
+ (instancetype)getInstance {
static NetRequest *request = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
request = [[NetRequest alloc] init];
});
return request;
}
- (instancetype)init {
if (self = [super init]) {
_manager = [AFHTTPSessionManager manager];
_manager.requestSerializer = [AFJSONRequestSerializer serializer];
_manager.responseSerializer = [AFJSONResponseSerializer serializer];
}
return self;
}
- (void)requestWithMethod:(NSString *)method
url:(NSString *)url
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure {
if ([method isEqualToString:@"GET"]) {
[self.manager GET:url
parameters:parameters
headers:nil
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) {
success(task, responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(task, error);
}
}];
} else if ([method isEqualToString:@"POST"]) {
[self.manager POST:url
parameters:parameters
headers:nil
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) {
success(task, responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(task, error);
}
}];
}
}
@end
其中:
GET
请求使用GET
方法,同时对应的成功和失败的回调均使用传入的success
和failure
参数来获取。POST
请求使用POST
方法,同时对应的成功和失败的回调均使用传入的success
和failure
参数来获取。
NetRequest
类的实现完成后,我们就可以使用这个类来进行网络请求了。
2.3 进一步封装
如果我们需要在网络请求中添加其他的功能,例如数据缓存,请求重试等,都可以在 NetRequest
类中进一步实现。
例如:实现一个添加缓存功能的网络请求方法
/**
* GET 请求,支持缓存
* @param url 请求 URL
* @param parameters 请求参数
* @param cache 过期时间,单位为秒,-1 表示永不过期,0 表示不使用缓存,默认为 -1。
* @param success 请求成功回调
* @param failure 请求失败回调
*/
- (void) getWithUrl:(NSString *)url
parameters:(NSDictionary *)parameters
cache:(NSTimeInterval)cache
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
if (cache > 0) {
// 从缓存中获取数据
id responseObject = [CacheManager cacheForKey:url];
if (responseObject) {
if (success) {
success(nil, responseObject);
}
return;
}
}
// 没有从缓存中获取到数据,进行网络请求
[self getWithUrl:url parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
if (cache > 0) {
// 将数据保存在缓存中
[CacheManager setCache:responseObject forKey:url expireTime:cache];
}
if (success) {
success(task, responseObject);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if (failure) {
failure(task, error);
}
}];
}
其中,如果 cache
参数大于 0,我们会先从缓存中获取数据,如果缓存中有数据,就直接返回,并调用成功回调。如果没有缓存数据,就进行网络请求。
3. 示例说明
下面是两个示例,演示如何使用封装好的 NetRequest
类进行网络请求。
示例1:GET 请求
NSDictionary *params = @{@"key1": @"value1", @"key2": @"value2"};
[[NetRequest getInstance] requestWithMethod:@"GET"
url:@"http://httpbin.org/get"
parameters:params
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"%@", responseObject);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"%@", error);
}];
这个请求会向 httpbin.org 发送一个 GET 请求,并将 params
中的参数附加在 URL 后面,请求成功回调中会打印出服务端返回的数据。
示例2:下载文件
NSString *url = @"http://httpbin.org/image/jpeg";
NSURLSessionDownloadTask *task = [[NetRequest getInstance].manager downloadTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"Download Error: %@", error);
} else {
NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileUrl = [documentsDirectoryPath stringByAppendingPathComponent:@"image.jpeg"];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fileUrl] error:nil];
}
}];
[task resume];
这个请求会向 httpbin.org 发送一个下载图片的请求,请求成功后会将图片下载到应用的 document 目录中。
4. 总结
以上就是使用 Block
二次封装 AFNetworking 3.0
的完整攻略。我们可以将这个封装好的网络请求类作为一个通用的工具类,方便项目中的其他模块使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:IOS 使用Block二次封装AFNetworking 3.0详解 - Python技术站