AFNetWorking用法及缓存处理

简介: AFNetWorking用法及缓存处理

AFNetWorking 在IOS开发中是一个经常会用的第三方开源库,其最好处是维护及时,源码开源。

常用GET与POST请求方法:

POST请求:

//初始化一个请求对象
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString * url = @"你的请求地址";
//dic 为参数字典
[manager POST:url parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {

//请求成功的回调
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//请求失败的回调    
}];

GET请求:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString * url = @"你的请求地址";
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

//请求成功的回调
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//请求失败的回调   
}];

这里有一个地方需要注意,

[AFHTTPRequestOperationManager manager]
这个类方法我们点进源码可以发现:

  • (instancetype)manager {
    return [[self alloc] initWithBaseURL:nil];

}
这里初始化了一个返回了一个新的对象,并不是单例。

使用这样的下载方法,下载完成后的数据AFNetWorking会帮我们自动解析,但是有时候服务器给的数据并不标准,这时我们需要加上这个设置:

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

这样我们将得到原始的HTTP返回给我们数据。

我们再来探究一下,下载成功后,回调方法里的参数到底是什么东西

success:^(AFHTTPRequestOperation *operation, id responseObject)
其中,第二个参数 responseObject 是下载下来的data数据,可直接进行JSON等解析。

第一个参数,是个AFHTTPRequestOperation对象,来看源文件

@interface AFHTTPRequestOperation : AFURLConnectionOperation

@property (readonly, nonatomic, strong) NSHTTPURLResponse *response;

@property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer;

@property (readonly, nonatomic, strong) id responseObject;

@end
可以发现,里面有一个成员便是responseObject,同时,AFHTTPRequestOperation是继承于AFURLConnectionOperation,我们在看看AFURLConnectionOperation这个类:

@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSSecureCoding, NSCopying>

@property (nonatomic, strong) NSSet *runLoopModes;

@property (readonly, nonatomic, strong) NSURLRequest *request;

@property (readonly, nonatomic, strong) NSURLResponse *response;

@property (readonly, nonatomic, strong) NSError *error;

@property (readonly, nonatomic, strong) NSData *responseData;

@property (readonly, nonatomic, copy) NSString *responseString;

@property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding;

@property (nonatomic, assign) BOOL shouldUseCredentialStorage;

@property (nonatomic, strong) NSURLCredential *credential;

@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;

@property (nonatomic, strong) NSInputStream *inputStream;

@property (nonatomic, strong) NSOutputStream *outputStream;

@property (nonatomic, strong) dispatch_queue_t completionQueue;

@property (nonatomic, strong) dispatch_group_t completionGroup;

@property (nonatomic, strong) NSDictionary *userInfo;

  • (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER;
  • (void)pause;
  • (BOOL)isPaused;
  • (void)resume;

看到这里,就离AFNETWorking封装的源头很近了,里面的成员非常多,其中包含了大部分我们需要的信息,可以通过点语法取到,其中有输入输出流,错误信息,请求到的Data数据,以及请求到的字符串数据

responseString
我们可以通过

NSLog ( @"operation: %@" , operation. responseString );
来打印查看请求到的原始信息。

几点注意:

1.关于崩溃url为nil

大多数这样的原因是url中有特殊字符或者中文字符,AFNETWorking并没有做UTF8的转码,需要:

url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
2.添加HttpHead字段的方法

//为这个下载任务HTTP头添加@"User-Agent"字段
[manager.requestSerializer setValue:_scrData forHTTPHeaderField:@"User-Agent"];
//打印头信息

NSLog(@"%@",manager.requestSerializer.HTTPRequestHeaders);

在下载请求中,经常会请求一些不长变化的数据,如果每次APP启动都进行请求,会消耗许多资源,并且有时候缓存的处理,可以大大改善用户体验。

在AFNETWorking中,并没有提供现成的缓存方案,我们可以通过写文件的方式,自行做缓存。

在下载方法中:

[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

    //写缓存
    NSString *cachePath = @"你的缓存路径";//  /Library/Caches/MyCache
    [data writeToFile:cachePath atomically:YES];
            succsee(data);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];

然后在每次下载前,进行如下判断:

NSString * cachePath = @"你的缓存路径";

    if ([[NSFileManager defaultManager] fileExistsAtPath:cachePath]) {
        //从本地读缓存文件
        NSData *data = [NSData dataWithContentsOfFile:cachePath];
        }

有时,我们的下载请求可能是用户的动作触发的,比如一个按钮。我们还应该做一个保护机制的处理,

//初始化一个下载请求数组
NSArray * requestArray=[[NSMutableArray alloc]init];
//每次开始下载任务前做如下判断
for (NSString * request in requestArray) {

    if ([url isEqualToString:request]) {
        return;
    }
}

[requestArray addObject:url];
//下载成功或失败后
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

    [requestArray removeObject:url]
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [requestArray removeObject:url]
}];

至此,一个比较完成AFNETWorking请求使用流程就完成了。

目录
相关文章
|
存储 缓存 负载均衡
OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用
OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用
|
缓存 iOS开发 Go
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
缓存 NoSQL Java
Redis+Caffeine构建高性能二级缓存
大家好,我是摘星。今天为大家带来的是Redis+Caffeine构建高性能二级缓存,废话不多说直接开始~
1967 0
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
1107 25
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
525 1
Redis专题-实战篇二-商户查询缓存
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
2098 3