AFNetworking
1.1、AFNetworking简介
for short:AFN
是什么 ?:a delightful HTTP framework for iOS, macOS, watchOS, and tvOS.
开发语言:Objective-C
官方主页:http://afnetworking.com
源码仓库:https://github.com/AFNetworking/AFNetworking
1.2、使用CocoaPods安装AFNetworking

step1、查询AFNetworking的版本

pod search AFNetworking

step2、把查询到的依赖信息复制到Podfile文件中,示例

pod 'AFNetworking', '~> 3.2.1'

step3、安装

pod install
1.3、ATS配置

iOS9引入了ATS(App Transport Security)特性。 它要求App内访问的网络必须使用HTTPS协议。

但是苹果公司也意识到,在短时间内让开发者改成HTTPS协议是不现实的, 所以就设置了一个开关,这个开关允许开发者依然使用HTTP协议,给开发者一个调整的时间。

具体做法是:在项目根目录下有一个Info.plist文件,以文本文件的方式打开,加入如下的配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

这样就可以正常访问了。

1.4、导入头文件
#import "AFNetworking.h"
1.5、HEAD请求

示例:

NSString *url = @"https://fpliustorage.blob.core.chinacloudapi.cn/blog/images/user-avatar.png";

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];

[http HEAD:url parameters:nil
  success:^(NSURLSessionDataTask * _Nonnull task) {
    NSLog(@"onSuccess()");
    NSHTTPURLResponse *response = (NSHTTPURLResponse*)task.response;
    NSDictionary *headers = response.allHeaderFields;
    id eTagObj = [headers valueForKey:@"Etag"];
    if (eTagObj && ![NSNull isEqual:eTagObj]) {
        NSLog(@"eTag = %@", eTagObj);
    }
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"onError()");
}];
1.6、GET请求

示例:

NSString *url = @"http://www.wanandroid.com/article/list/0/json";

NSDictionary *query = @{ @"cid" : @"294" };

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];

[http GET:url parameters:query progress:nil
  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"onSuccess()");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"onError()");
}];

这里的query参数必须是NSDictionary,如果不需要参数,可以传入nil

1.7、POST FORM请求

示例:

NSString *url = @"https://www.wanandroid.com/user/login";

NSDictionary *requestBody = @{ @"username": @"fpliu", @"password": @"123456" };

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];

[http POST:url parameters:requestBody
  progress:^(NSProgress * _Nonnull uploadProgress) {
    NSLog(@"onProgress = %@", uploadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"onSuccess()");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"onError() error = %@", error);
}];

这里的requestBody参数必须是NSDictionary

POST请求的请求体FORM格式的时候,http.requestSerializer参数的值必须是AFHTTPRequestSerializer,这也是默认值,所以,我们可以不用自己设置, 它会把NSDictionary解析成FORM格式,并且会自动添加Content-Type请求头的值为application/x-www-form-urlencoded

1.8、POST JSON请求

示例:

NSString *url = @"https://www.wanandroid.com/user/login";

NSDictionary *requestBody = @{ @"username": @"fpliu", @"password": @"123456" };

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];
http.requestSerializer = [AFJSONRequestSerializer serializer];

[http POST:url parameters:requestBody
  progress:^(NSProgress * _Nonnull uploadProgress) {
    NSLog(@"onProgress = %@", uploadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"onSuccess()");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"onError() error = %@", error);
}];

这里的requestBody参数必须是NSDictionary类型, 并且,必须设置AFJSONRequestSerializer这个, 因为它会把NSDictionary解析成JSON格式,并且会自动添加Content-Type请求头的值为application/json

1.9、POST XML请求

示例:

NSString *url = @"https://www.wanandroid.com/user/login";

NSString *xml = @"<root><username>fpliu</username><password>123456</password></root>";

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody: [xml dataUsingEncoding:NSUTF8StringEncoding]];

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];

NSURLSessionDataTask *task = [http dataTaskWithRequest:request
  uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
    NSLog(@"onUploadProgress = %@", uploadProgress);
} downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
    NSLog(@"onDownloadProgress = %@", downloadProgress);
} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
    NSLog(@"onComplete() responseObject = %@, error = %@", responseObject, error);
}];
[task resume];

POST请求的请求体XML格式的时候, 请求头中必需设置Content-Typeapplication/xml

1.10、POST Multipart请求

示例:

NSString *url = @"https://www.wanandroid.com/user/login";

AFHTTPSessionManager *http = [[AFHTTPSessionManager alloc] init];

[http POST:url parameters:nil
  constructingBodyWithBlock:^(id  _Nonnull formData) {
      NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
      NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
      NSString *filePath = [resourceBundle pathForResource:@"user-avatar" ofType:@"png"];
      NSLog(@"filePath = %@", filePath);

      long currentTimeSeconds = [[NSDate date] timeIntervalSince1970];
      NSLog(@"currentTimeSeconds = %ld", currentTimeSeconds);

      NSString *fileName = [NSString stringWithFormat:@"%ld.png", currentTimeSeconds];
      [formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"file" fileName:fileName mimeType:@"image/png" error:nil];
} progress:^(NSProgress * _Nonnull downloadProgress) {
    NSLog(@"onProgress = %@", downloadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"onSuccess()");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"onError()");
}];
1.11、自动处理Cookie
[http.requestSerializer setHTTPShouldHandleCookies:YES];
1.12、自动处理响应体为gzip压缩的数据

示例:

[http.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];

只要在请求头中设置Accept-EncodinggzipAFN就能正确处理了。

1.13、统一打印HTTP协议的日志

AFN的所有请求和响应的日志信息可以帮助我们快速定位问题。

我们可以使用AFNetworkingLogger进行打印。