简介:
AFNetworking是iOS、macOS、watchOS和tvOS的一个令人愉快的网络库。它建立在基础URL加载系统之上,扩展了构建到Cocoa中的强大的网络高级抽象。它有一个模块化的体系结构,具有设计良好、功能丰富的API,使用起来很愉快。
然而,也许最重要的特点是,每天都在使用AFNetworking并为其做出贡献的开发人员组成了一个令人惊叹的社区。AFNetworking为iPhone、iPad和Mac上一些最受欢迎、广受好评的应用提供了动力。
如何开始使用:
• 下载AFNetworking,并试用附带的Mac和iPhone示例应用程序。
• 阅读“入门”指南、常见问题解答或维基上的其他文章。
交流:
• 如果需要帮助,使用"Stack Overflow"(标签 'afnetworking')。
• 如果你想问一个一般性的问题,使用"Stack Overflow"。
• 如果您发现了一个bug,并且能够提供可靠地复现它的步骤,那么就打开一个issue。
• 如果您有特殊请求,请打开一个issue。
• 如果你想贡献,提交一个请求。
安装:
AFNetworking支持在项目中安装库的多种方法。
通过CocoaPods安装:
要使用CocoaPods将AFNetworking集成到Xcode项目中,请在Podfile中指定:
pod 'AFNetworking', '~> 4.0'
通过Swift Package Manager安装:
一旦设置了Swift package,将AFNetworking添加为依赖项与将其添加到Package.swift中的dependencies值一样简单。
dependencies: [
.package(url: "https://github.com/AFNetworking/AFNetworking.git", .upToNextMajor(from: "4.0.0"))
]
注:AFNetworking的Swift包不包含UIKit扩展。
通过Carthage安装:
Carthage是一个分散的依赖关系管理器,它可以构建您的依赖关系,并为您提供二进制框架。要集成AFNetworking,请将以下内容添加到您的Cartfile文件中。
github "AFNetworking/AFNetworking" ~> 4.0
结构:
NSURLSession
• AFURLSessionManager
• AFHTTPSessionManager
Serialization
• <AFURLRequestSerialization>
° AFHTTPRequestSerializer
° AFJSONRequestSerializer
° AFPropertyListRequestSerializer
• <AFURLResponseSerialization>
° AFHTTPResponseSerializer
° AFJSONResponseSerializer
° AFXMLParserResponseSerializer
° AFXMLDocumentResponseSerializer(macOS)
° AFPropertyListResponseSerializer
° AFImageResponseSerializer
° AFCompoundResponseSerializer
Additional Functionality
• AFSecurityPolicy
• AFNetworkReachabilityManager
使用:
AFURLSessionManager
AFURLSessionManager基于指定的NSURLSessionConfiguration对象创建和管理NSURLSession对象,该对象遵从<NSURLSessionTaskDelegate>、<NSURLSessionDataDelegate>、<NSURLSessionDownloadDelegate>和<NSURLSessionDelegate>。
Creating a Download Task
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];
Creating an Upload Task
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];
Creating an Upload Task for a Multi-Part Request, with Progress
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];
Creating a Data Task
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网络接口的地址。
• 不要使用可达性来确定是否应该发送原始请求。
° 你应该试着发送它。
• 你可以使用可达性来确定何时应该自动重试请求。
° 尽管仍然可能失败,但连接可用的可达性通知是重试的好时机。
• 网络可达性是确定请求失败原因的有用工具。
° 在网络请求失败后,告诉用户他们处于离线状态比给他们一个更技术但更准确的错误,例如“请求超时”要好。
共享网络可达性
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
安全策略
AFSecurityPolicy通过安全连接根据固定的X.509证书和公钥评估服务器信任。
向应用程序添加固定SSL证书有助于防止中间人攻击和其他漏洞。强烈建议处理敏感客户数据或财务信息的应用程序通过配置并启用SSL固定的HTTPS连接路由所有通信。
允许使用无效的SSL证书
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy.allowInvalidCertificates = YES; // 不建议用于生产环境
单元测试
AFNetworking在tests子目录中包含一套单元测试。这些测试只需在您想要测试的平台框架上执行测试操作即可运行。
网友评论