AFNetworking 3.0指南 -- 编写于2017年11月19日
AFNetworking 3.0 是AFNetworking最新最主要的版本,一个愉快的网络开发库,使用于iOS、tvOS、macOS、watchOS。为了保持这个库的可维护性,3.0将移除对现在不推荐使用的基于NSURLConnection的API的所有支持。如果您的项目以前使用这些API,则建议您现在升级到基于NSURLSession的API。本指南将指导您完成该过程。本指南旨在简化使用AFNetworking 2.X将现有应用程序转换为最新API的过程,并解释新功能和更改功能的设计和结构。
使用最低要求:iOS 7,Mac OS X 10.9,watchOS 2,tvOS 9和Xcode 7
AFNetworking 3.0正式支持iOS 7 +,Mac OS X 10.9+,watchOS 2+,tvOS 9和Xcode 7.如果您想在针对旧SDK版本的项目中使用AFNetworking,请查阅自述文件以获取兼容性信息。
NSURLConnection API已被删除
AFNetworking 1.0基于基于NSURLConnection的API构建,AFNetworking 2.0提供了使用基于NSURLConnection的API或基于更新的NSURLSession的API的选项。 AFNetworking 3.0现在完全建立在基于NSURLSession的API基础之上,这降低了后续维护的负担,同时允许支持苹果向NSURLSession提供的未来增强功能的任何附加功能。从Xcode 7开始,NSURLConnection API已被Apple正式弃用。虽然API将继续发挥作用,但不会添加任何新功能,并且Apple已经建议所有基于网络的功能都会利用NSURLSession。
AFNetworking 2.x将继续收到关键的错误和安全修复程序,但不会增加新功能。 Alamofire软件基金会建议将所有项目迁移到基于NSURLSession的API。
删除的类
AFNetworking 3.0中删除了以下类:
- AFURLConnectionOperation
- AFHTTPRequestOperation
- AFHTTPRequestOperationManager
修改的类
以下类包含基于NSURLConnection API的内部实现。他们被重构为使用NSURLSession APIs。
- UIImageView+AFNetworking
- UIWebView+AFNetworking
- UIButton+AFNetworking
使用
AFURLSessionManager
AFURLSessionManager指定一个NSURLSessionConfiguration对象和管理NSURLSession对象,并遵守这些协议<NSURLSessionTaskDelegate>,<NSURLSessionDataDelegate>,<NSURLSessionDownloadDelegate>和<NSURLSessionDelegate>。
建立一个下载任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
}];
[downloadTask resume];
建立一个上传任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Success: %@ %@", response, responseObject);
}
}];
[uploadTask resume];
建立一个具有进度条的多部分上传任务
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
} error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue.
// You are responsible for dispatching to the main queue for UI updates
dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
[progressView setProgress:uploadProgress.fractionCompleted];
});
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
[uploadTask resume];
建议一个数据任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
[dataTask resume];
请求序列化器
请求序列化器从URL字符串创建请求,将参数编码为查询字符串或HTTP正文。
NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};
查询字符串参数编码
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];
GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3
URL表单参数编码
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];
POST http://example.com/
Content-Type: application/x-www-form-urlencoded
foo=bar&baz[]=1&baz[]=2&baz[]=3
JSON参数编码
[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];
POST http://example.com/
Content-Type: application/json
{"foo": "bar", "baz": [1,2,3]}
网络可达性管理器
AFNetworkReachabilityManager监控地址的可达性,以及WWAN和WiFi网络接口的地址。
- 不要使用Reachability来确定是否应发送原始请求。(你应该尝试直接发送它)
- 您可以使用Reachability来确定何时应该自动重试请求。(虽然它可能仍然失败,但是连接可用的可达性通知是重试某件事的好时机)
- 网络可达性是确定请求失败原因的有用工具。(在网络请求失败后,告诉用户他们处于离线状态比向他们提供更加技术性但准确的错误,如“请求超时”更好)
另见WWDC 2012会议706,“网络最佳实践”。
监控网络的可达性
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
安全策略
AFSecurityPolicy通过安全连接评估针对固定的X.509证书和公钥的服务器信任。
将固定的SSL证书添加到您的应用程序有助于防止中间人攻击和其他漏洞。强烈建议处理敏感客户数据或财务信息的应用程序通过HTTPS连接路由所有通信,并配置并启用SSL固定。
允许无效的SSL证书
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy.allowInvalidCertificates = YES; // not recommended for production
Github地址
https://github.com/AFNetworking/AFNetworking