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 productionGithub地址
https://github.com/AFNetworking/AFNetworking