AFNetworking的使用

AFNetworking

一、早前的几个网络框架

1、ASI框架: HTTP终结者.很牛, 但是有BUG, 已经停止更新.
2、MKNetworkKit (印度人写的).
3、AFN一直还在更新.

AFNetworking的出现:MAC/iOS设计的一套网络框架.(为了简化网络操作)

地址:https://github.com/AFNetworking/AFNetworking
AFN专注与网络数据传输,以及网络中多线程的处理.

二、AFNetworking的使用

1、AFN特性 :

登录传参数时,传递字典即可.(键名为参数名,键值为参数值).
自动到子线程中执行,执行完后返回主线程.
返回的结果自动序列化为NSDictionary.

2、使用AFN注意 :

AFHTTPRequestOperationManager封装了通过HTTP协议与Web应用程序进行通讯的常用方法.(这个实例化的时候不是单例, 因为没有shared字) 包括创建请求/响应序列化/网络监控/数据安全. 方法等都是以AF开头的.

3、AFN能做的 (网络中的都涵盖了):

GET/POST/PUT/DELETE/HEAD请求.
JSON数据解析/Plist数据解析.(不支持XML数据解析)
POSTJSON.
上传/下载.
断点续传(AFDownLoadRequestOpreation)
图片缓存到本地(AFCache)

4、使用步骤 : (可参考说明文档)

1.首先需要实例化一个请求管理器AFHTTPRequestOperationManager.
2.设置请求的数据格式:默认是二进制.(不是可改)
AFHTTPRequestSerializer(二进制)
AFJSONRequestSerializer(JSON)
AFPropertyListRequestSerializer(Plist)

3.设置响应的数据格式:默认是JSON.(不是可改)

AFHTTPResponseSerializer(二进制)
AFJSONResponseSerializer(JSON)
AFPropertyListResponseSerializer(Plist)
AFXMLParserResponseSerializer(XML)
AFImageResponseSerializer(Image)
AFCompoundResponseSerializer(组合的)
4.如果响应者的MIMEType不正确,就要修改acceptableContentTypes.
5.调用方法,发送响应的请求(GET/POST…).

关于修改AFN源码:

通常序列化时做对text/plan等的支持时,可以一劳永逸的修改源代码,在acceptableContentTypes中修改即可。

三、AFNetworking的使用代码片段

判断网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#pragma -mark 判断网络
-(void)reach
{
/**
AFNetworkReachabilityStatusUnknow = -1,//未知
AFNetworkReachabilityStatusNotReachable = 0, //无连接
AFNetworkReachabilityStatusReachableViaWWAN = 1, // 3G,花钱
AFNetworkReachabilityStatusReachableViaWiFi = 2, //WiFi
*/
//如果要检测网络状态的变化,必须要用检测管理者的单利startMonitoring
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
//检测网络连接的单利,网络变化时回调方法
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"---%ld",status);
}];
}
#pragma -mark iOS7和Mac OS 10.9以后出得
-(void)sessionDownload
{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//基于NSUrlSessionManager的(iOS7+。Mac OS 10.9+,以前的版本用AFHTTPRequestOpreationManager)
AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:config];
NSString *urlString = FILE_REMOTE_URL;
urlString=[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlString];
NSLog(@"urlString=%@",urlString);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSLog(@"request=%@",request);
//创建一个下载任务
NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
//指定下载文件保存的路径
NSLog(@"target=%@-suggest=%@",targetPath,response.suggestedFilename);
//将下载文件保存在Document路径中
NSString *FileDoc =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *path = [FileDoc stringByAppendingPathComponent:response.suggestedFilename];
//URLWithString返回的是网络的URL,如果使用本地URL,需要注意
NSURL *fileUrl1 = [NSURL URLWithString:path];
NSURL *fileUrl = [NSURL fileURLWithPath:path];
NSLog(@"fileUrl1-%@,fileUrl-%@",fileUrl1,fileUrl);
return fileUrl;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
//下载完成的方法
NSLog(@"filePath=%@,errer=%@",filePath,error);
NSData *data=[NSData dataWithContentsOfURL:filePath];
UIImage *image=[UIImage imageWithData:data];
UIImageView *imageView=[[UIImageView alloc]initWithImage:image];
imageView.backgroundColor=[UIColor redColor];
imageView.frame=CGRectMake(10, 20, 140, 200);
[self.view addSubview:imageView];
}];
[task resume];//开始任务
}
/**
* AFN原来的下载文件方法,现在仍然可以用
*
* @param string aUrl 请求文件地址
* @param string aFilePath 保存地址
* @param string aFileName 文件名
* @param int aTag标识
*/
-(void)downFileWithUrl:(NSString *)aUrl savePath:(NSString *)aFilePath fileName:(NSString *)aFileName tag:(NSInteger)aTag
{
NSLog(@"-%@-%@-%@",aUrl,aFilePath,aFileName);
NSFileManager *manager=[NSFileManager defaultManager];
//检查本地文件是否存在
NSString *fileName=[NSString stringWithFormat:@"%@/%@",aFilePath,aFileName];
//文件已经存在直接读取
NSLog(@"file=%@",fileName);
if ([manager fileExistsAtPath:fileName])//
{
UIImage *image=[UIImage imageWithContentsOfFile:fileName];
UIImageView *imageView=[[UIImageView alloc]initWithImage:image];
imageView.frame=CGRectMake(170, 20, 140, 200);
[self.view addSubview:imageView];
} else {
//如果没有就创建文件路径
//先创建文件的存放的文件夹路径
if(![manager fileExistsAtPath:aFileName])
{
//创建文件存放的路径
[manager createDirectoryAtPath:aFileName withIntermediateDirectories:YES attributes:nil error:nil];
}
//下载文件
NSURL *url=[NSURL URLWithString:aUrl];
NSURLRequest *request=[NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *opration=[[AFHTTPRequestOperation alloc] initWithRequest:request];
//设置从哪里下载
opration.inputStream=[NSInputStream inputStreamWithURL:url];
//设置下载完了放在那里
opration.outputStream=[NSOutputStream outputStreamToFileAtPath:fileName append:NO];
//设置下载进度
[opration setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
NSLog(@"----%f",(float)totalBytesRead/totalBytesExpectedToRead);
}];
//已完成下载
[opration setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//显示图片
UIImage *image=[UIImage imageWithContentsOfFile:fileName];
UIImageView *imageView=[[UIImageView alloc]initWithImage:image];
imageView.frame=CGRectMake(170, 20, 140, 200);
[self.view addSubview:imageView];
NSLog(@"fileName=%@",fileName);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"下载失败!=%@",error);
}];
[opration start];
}
}
#pragma -mark
-(void)jsonRequest
{
//创建一个请求队列管理者
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes=nil;
//GET只接受JSON
[manager GET:JSON_DIC_URL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
UITextView *textView=[[UITextView alloc]initWithFrame:CGRectMake(10, 230, 140, 200)];
[self.view addSubview:textView];
textView.scrollEnabled = YES;
textView.text=[NSString stringWithFormat:@"%@:%@",[responseObject class],responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败:%@",error);
}];
}
#pragma -mark XML类型数据请求
-(void)XMLRequest
{
//请求过程
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:XML_DIC_URL]];
AFHTTPRequestOperation *Operation=[[AFHTTPRequestOperation alloc]initWithRequest:request];
//添加XML的解析器
Operation.responseSerializer=[AFXMLParserResponseSerializer serializer];
UITextView *textView=[[UITextView alloc]initWithFrame:CGRectMake(170, 230, 140, 200)];
[self.view addSubview:textView];
[Operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
textView.text=[NSString stringWithFormat:@"%@:%@",[responseObject class],responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
textView.text=[NSString stringWithFormat:@"Error=%@",[error localizedDescription]];
}];
[[NSOperationQueue mainQueue] addOperation:Operation];
}
#pragma mark - get/post登录
- (void)getLogin
{
//1.管理器
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//2.设置登录参数
NSDictionary *dict = @{ @"username":@"xn", @"password":@"123" };
//3.请求
[manager GET:@"http://localhost/login.php" parameters:dict success: ^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"GET --> %@, %@", responseObject, [NSThread currentThread]); //自动返回主线程
} failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@", error);
}];
}
/**
* 和上面的GET用法完全一样, 只有一个POST参数不一样
*/
- (void)postLogin
{
//1.管理器
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//2.设置登录参数
NSDictionary *dict = @{ @"username":@"xn", @"password":@"123" };
//3.请求
[manager POST:@"http://localhost/login.php" parameters:dict success: ^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"POST --> %@, %@", responseObject, [NSThread currentThread]); //自动返回主线程
} failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@", error);
}];
}