文档章节

AFNetWorking用法及缓存处理

珲少
 珲少
发布于 2015/04/02 15:44
字数 1036
阅读 658
收藏 4

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 <AFURLResponseSerialization> * 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请求使用流程就完成了。

 

 

专注技术,热爱生活,交流技术,也做朋友。

——珲少 QQ群:203317592

© 著作权归作者所有

珲少

珲少

粉丝 875
博文 390
码字总数 469911
作品 0
上海
iOS工程师
私信 提问
加载中

评论(3)

wqh_iOS
wqh_iOS

引用来自“wqh_iOS”的评论

博主,我想请教你下,,自己做完缓存后,我向定时把他删除,比如24个小时,之后把缓存清除,这段清除缓存的代码应该写在哪里啊,????程序不可能一直在运行啊。我把程序结束了之后,怎么让他自动执行删除缓存啊。。。

引用来自“珲少”的评论

你做缓存的时候,把每个缓存加一个时间戳,在程序每次启动时进行缓存检查,将24小时之前的缓存文件删除,这样可以达到需求么?
明白了明白了,就是每次启动下,然后获得缓存文件时什么时候创建的,然后把他删掉
珲少
珲少

引用来自“wqh_iOS”的评论

博主,我想请教你下,,自己做完缓存后,我向定时把他删除,比如24个小时,之后把缓存清除,这段清除缓存的代码应该写在哪里啊,????程序不可能一直在运行啊。我把程序结束了之后,怎么让他自动执行删除缓存啊。。。
你做缓存的时候,把每个缓存加一个时间戳,在程序每次启动时进行缓存检查,将24小时之前的缓存文件删除,这样可以达到需求么?
wqh_iOS
wqh_iOS
博主,我想请教你下,,自己做完缓存后,我向定时把他删除,比如24个小时,之后把缓存清除,这段清除缓存的代码应该写在哪里啊,????程序不可能一直在运行啊。我把程序结束了之后,怎么让他自动执行删除缓存啊。。。
关于ios应用引入AFNetworking后编译报错的问题

/Users/rzz/Desktop/iphone-app/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.h:29:1: error: unknown type name 'NS_ASSUME_NONNULL_BEGIN' NS_ASSUME_NONNULL_BEGIN ^ /User......

骑毛驴的王子
2015/11/09
890
0
IOS网络--AFNetworking

http://cocoadocs.org/docsets/AFNetworking/2.5.0/ AFNetworking的用法 提交GET请求和POST请求 AFNetworking是第三方框架,阅者自行去官网上下载、安装。 1>创建AFHTTPRequestOpeartionMan...

求是科技
2015/03/16
0
0
iOS下的Http库AFNetworking

在iOS下开发一直是用ASIHTTPRequest库,ASIHTTPRequest已经停止更新,看了这个文章http://www.oschina.net/news/61416/github-top-100-objective-c-projects (原文https://github.com/Aufr......

vane_
2015/04/11
0
0
OC使用AFNetWorking框架GET方法上传参数格式不是JSON串

iOS的APP端使用AFNetWorking这个框架连接服务器, 项目约定使用GET方法传参, 现在遇到问题是:iOS传的参数要组合成“字典”放入AFNetWorking,然后用AFNetWorking开始请求, 而AFNetWorking会...

Moses_Fu
2015/10/26
1K
0
AFNetworking源码浅析

本文将从最简单的GET请求方法的使用入手,由表及里,逐步探究AFNetworking如何封装处理原生的网络请求。 一、AFNetworking的简单使用 Post、Put、Delete 与此Get类似 二、AFNetworking如何封...

鸿鹄当高远
2018/12/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

[JavaScript]js模块化

没有模块化:<scrpit> CommonJS(服务端):NodeJS AMD(浏览器端):RequireJS等 CMD(浏览器端):Sea.js UMD ES6

Danni3
15分钟前
1
0
拯救你丢失的精度——BigInteger和BigDecimal类(入门)

第三阶段 JAVA常见对象的学习 BigInteger和BigDecimal类 BigInteger类 (一) 构造方法: //针对超过整数范围的运算(整数最大值:2147483647)BigInteger(String val) ####(二) 常用方法: ...

BWH_Steven
17分钟前
1
0
开源 java CMS - FreeCMS2.8 自定义标签 infoSearch

项目地址:http://www.freeteam.cn/ infoSearch 根据参数和搜索关键词提取信息分页对象。 参数 说明 siteid 信息所属站点id num 每页显示数量 order 排序类型 1 固顶有效并降序,发布时间降序...

freeteam
28分钟前
2
0
java思维导图整理

jmm https://www.edrawsoft.cn/viewer/public/s/b0178374373697; redis https://www.edrawsoft.cn/viewer/public/s/5691c269955848 map https://www.edrawsoft.cn/viewer/public/s/b67533638......

流光韶逝
42分钟前
6
0
Gnu/Linux 防止暴力扫描及其它

RedHat7 手工脚本: # iptables iptables -A INPUT -i eno16777728 -p tcp -m multiport --destination-port 135,136,137,138,139,445,4899,1900 -j LOG iptables -A INPUT -p tcp -m multip......

晒太阳的小猪
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部