MENU

AFNetworking的简单使用

April 14, 2016 • Read: 2032 • Codes

以下代码基于目前(2016.04.14)最新版本3.1。

AFNetworking 的使用简单来说有两种方式,分别为使用AFURLSessionManager和使用AFHTTPSessionManagerAFURLSessionManagerAFHTTPSessionManager为 3.0 版本新添加的类,均以NSURLSession为基础实现。AFURLSessionManager提供了类似于NSURLSessionAPI 的使用方式,AFHTTPSessionManager则继承自AFURLSessionManager,提供了一些封装,使用起来比较简单方便,但没有AFURLSessionManager灵活。

由于 3.0 及以上版本均以NSURLSession为基础实现,NSURLSession并没有提供同步请求相关的 API,所以使用 AFNetworking 发起的网络请求均为异步请求。同步请求可以自行参考- [AFURLSessionManager tasksForKeyPath:]通过引入信号量的方式模仿同步请求。但除非必要,通常情况下请使用异步请求。

各版本的最低系统要求
AFNetworking VersionMinimum iOS TargetMinimum OS X TargetMinimum watchOS TargetMinimum tvOS TargetNotes
3.xiOS 7OS X 10.9watchOS 2.0tvOS 9.0Xcode 7+ is required. NSURLConnectionOperation support has been removed.
2.6 -> 2.6.3iOS 7OS X 10.9watchOS 2.0n/aXcode 7+ is required.
2.0 -> 2.5.4iOS 6OS X 10.8n/an/aXcode 5+ is required. NSURLSession subspec requires iOS 7 or OS X 10.9.
1.xiOS 5Mac OS X 10.7n/an/a
0.10.xiOS 4Mac OS X 10.6n/an/a

(OS X projects must support 64-bit with modern Cocoa runtime).

AFURLSessionManager 的使用

AFURLSessionManager的使用简单来说有以下几步:

  • 创建 SessionManager,或使用已有的 SessionManager
  • 创建 NSURLRequest
  • 使用 SessionManager 创建 NSURLSessionTask 实例,根据情况可以创建 DataTask、DownloadTask、UploadTask 等。
  • 调用 Task 的- resume方法启动 Task。

好了,简单的使用方法如下:

// 创建 SessionManager
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] init];

// 创建 NSURLRequest
NSURL* URL = [NSURL URLWithString:@"https://httpbin.org/get"];
NSURLRequest* request = [NSURLRequest requestWithURL:URL];

// 创建 DataTask
NSURLSessionDataTask *dataTask = [sessionManager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
    // 因为是异步请求,所以这里已经是「另外一个线程了」,后面的代码均为如此。
    NSLog(@"%@", responseObject);
}];

// 发起请求,这一步不!要!忘!记!
[dataTask resume];

下面是稍微详细一点的用法:

1. 初始化 SessionManager

AFURLSessionManager的常用初始化方法:

// 使用 defaultSessionConfiguration
- (instancetype)init;

/**
 创建并返回一个 AFURLSessionManager 实例

 @param |configuration| 如果为 nil,则使用 defaultSessionConfiguration
                        |configuration|的类型在示例后面

 @return 返回一个新创建的 SessionManager
 */
- (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration 

示例:

// 创建 NSURLSessionConfiguration
NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

// 创建 SessionManager
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
Session Configuration 类型
  • defaultSessionConfiguration

为全局的 Session Configuration,所有使用defaultSessionConfiguration的对象均使用同一单例。

defaultSessionConfiguration使用基于文件系统的缓存,并在 keychain 中保存凭证。

  • ephemeralSessionConfiguration

私有的 Session Configuration,仅在内存中缓存数据,且数据仅在 Session 存在期存在。

  • backgroundSessionConfiguration

在 iOS8 及以上可用,另有专门的进程处理数据传输,在当前应用停止运行依然可以继续进行数据传输,而不会中断。其他方面与defaultSessionConfiguration一致。

另外,我们可以调整 Session Configuration 的参数,如:

// 设置请求超时时间为 30s
configuration.timeoutIntervalForRequest = 30;
SessionManager 的简单配置

AFURLSessionManager的默认 Response Serializer 为AFJSONResponseSerializer.

可用的 Response Serializer 有:

  • AFHTTPResponseSerializer
  • AFJSONResponseSerializer
  • AFXMLParserResponseSerializer
  • AFXMLDocumentResponseSerializer
  • AFPropertyListResponseSerializer
  • AFImageResponseSerializer
  • AFCompoundResponseSerializer

例如:

manager.responseSerializer = [AFImageResponseSerializer serializer];

2. 创建一个 NSURLRequest

最简单的创建方法为:

NSURL *URL = [NSURL URLWithString:@"https://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

上面的方法适用于没有参数,或 URL 已经完全指定的情况,在有参数,或需要 POST、JSON 的情况下,使用 AFNetworking 的AFURLRequestSerialization系列序列化类会非常方便。

可用的AFURLRequestSerialization

  • AFHTTPRequestSerializer
  • AFJSONRequestSerializer
  • AFPropertyListRequestSerializer

示例代码:

有如下请求 URL 及参数:

NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{
                              @"foo": @"bar", 
                              @"baz": @[@1, @2, @3]
                            };
使用AFHTTPRequestSerializer拼接 Query String
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];

结果:

  GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3
使用AFHTTPRequestSerializer编码表单请求
NSMutableURLRequest *request = [[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
使用AFJSONRequestSerializer编码表单请求
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];

结果:

POST http://example.com/
Content-Type: application/json

{"foo": "bar", "baz": [1,2,3]}

NSURLRequest 不可修改,但 NSMutableURLRequest 可以进行自定义,如:

// 设置请求超时时间为 10s
request.timeoutInterval = 10;

使用AFURLRequestSerialization系列序列化类创建的均为NSMutableURLRequest

3. 创建Session Task并执行

DataTask:请求数据

DataTask 使用 NSData 与服务器发送和接收数据,适合临时与服务器通信,在 iOS8 以后也支持后台模式。

/**
 使用指定的 NSURLRequest 创建一个 NSURLSessionDataTask 对象
   
 @param |request| 用于创建 NSURLSessionDataTask 的 NSURLRequest 对象
 @param |completionHandler| 在 task 结束时会被执行的 Block,没有返回值。
                            其有三个参数分别为:server response、
                                              使用 response serializer 序列化的 response object、
                                              发生的错误,没有则为 nil。
                                            
 */
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request 
                            completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler;

/**
 使用指定的 NSURLRequest 创建一个 NSURLSessionDataTask 对象

 @param |request| 用于创建 NSURLSessionDataTask 的 NSURLRequest 对象
 @param |uploadProgressBlock| 在上传进度更新时执行的 block。需要注意的是:此 block 在 
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch 到 main queue 中进行。
 @param |downloadProgressBlock| 在下载进度更新时执行的 block。其和|uploadProgressBlock|
                                一样在 session queue 中被调用,而不是 main queue.
 @param |completionHandler| 在task结束时会被执行的 Block,没有返回值。
                            其有三个参数分别为:server response、
                                              使用 response serializer 序列化的 response object、
                                              发生的错误,没有则为 nil。
 */
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                               uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock 
                             downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock 
                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler;

示例:

NSURLSessionDataTask *dataTask = [sessionManager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error: %@", error);
    } else {
        NSLog(@"%@ %@", response, responseObject);
    }
}];
[dataTask resume];
Download Task:下载任务

下载文件,支持后台下载。

/**
 使用指定的 resume data 创建一个 NSURLSessionDownloadTask 对象

 @param |resumeData| 用于创建 NSURLSessionDownloadTask 的|resumeData|
 @param |downloadProgressBlock| 在下载进度更新时执行的 block。需要注意的是:此 block 在
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch到 main queue 中进行。
 @param |destination| 用于决定下载文件的目标路径(保存到...)的 block。
                      其有两个参数,分别为:target path、server response
                      需要返回下载文件的目标路径。
                      下载文件会先保存到缓存文件,在移动到目标路径后缓存文件会被自动删除。
 @param |completionHandler| 在 task 结束时会被执行的 block,没有返回值。
                            其有三个参数分别为:server response、
                                              已下载文件的路径、
                                              发生的错误,没有则为 nil。
 */
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                          destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                    completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
                                      
/**
 使用指定的 NSURLRequest 创建一个 NSURLSessionDownloadTask 对象

 @param |request| 用于创建 NSURLSessionDownloadTask 的 NSURLRequest 对象
 @param |downloadProgressBlock| 在下载进度更新时执行的 block。需要注意的是:此 block 在
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch到 main queue 中进行。
 @param |destination| 用于决定下载文件的目标路径(保存到...)的 block。
                      其有两个参数,分别为:target path、server response
                      需要返回下载文件的目标路径。
                      下载文件会先保存到缓存文件,在移动到目标路径后缓存文件会被自动删除。
 @param |completionHandler| 在 task 结束时会被执行的 block,没有返回值。
                            其有三个参数分别为:server response、
                                              已下载文件的路径、
                                              发生的错误,没有则为 nil。

 需要注意的是:在 iOS 中,如果该 NSURLSessionDownloadTask 为后台任务(SessionManager 使用的
 Configuration 为 backgroundSessionConfiguration ),在 App 结束运行(terminated)后以上的
 block 并不会被执行。
 后台下载任务最好使用`-[AFURLSessionManager setDownloadTaskDidFinishDownloadingBlock:]`
 指定要保存下载文件的目标路径,而不是在|destination|中指定。
 */
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                          destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                    completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;

示例:

NSURLSessionDownloadTask *downloadTask = [sessionManager 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];
Upload Task:上传任务

上传文件,支持后台上传。

/**
 使用指定的 NSURLRequest 及一个本地文件路径创建一个 NSURLSessionUploadTask 对象

 @param |request| 用于创建 NSURLSessionUploadTask的NSURLRequest 对象
 @param |fileURL| 一个用于上传的本地文件路径
 @param |uploadProgressBlock| 在上传进度更新时执行的 block。需要注意的是:此 block 在
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch到 main queue 中进行。
 @param |completionHandler| 在 task 结束时会被执行的 block,没有返回值。
                            其有三个参数分别为:server response、
                                              使用 response serializer 序列化的 response object、
                                              发生的错误,没有则为 nil。
                                             
 @see `attemptsToRecreateUploadTasksForBackgroundSessions`
iOS7.0 的一个 bug,当创建后台上传任务的时候可能返回 nil,这个值为 YES 的时候会尝试重新创建。默认为NO。

 */
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
                                         fromFile:(NSURL *)fileURL
                                         progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
                                completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError  * _Nullable error))completionHandler;

/**
 使用指定的 NSURLRequest 及 HTTP body data 创建一个 NSURLSessionUploadTask 对象

 @param |request| 用于创建 NSURLSessionUploadTask的NSURLRequest 对象
 @param |bodyData| 用于上传的 NSData 对象
 @param |uploadProgressBlock| 在上传进度更新时执行的 block。需要注意的是:此 block在
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch到 main queue 中进行。
 @param |completionHandler| 在 task 结束时会被执行的 block,没有返回值。
                            其有三个参数分别为:server response、
                                              使用response serializer 序列化的 response object、
                                              发生的错误,没有则为 nil。
 */
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
                                         fromData:(nullable NSData *)bodyData
                                         progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
                                completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;

/**
 使用指定的 streaming request 创建一个 NSURLSessionUploadTask 对象

 @param |request| 用于创建 NSURLSessionUploadTask的 NSURLRequest 对象
 @param |uploadProgressBlock| 在上传进度更新时执行的 block。需要注意的是:此 block 在
                              session queue 中被调用,而不是 main queue.更新 UI 时需要
                              dispatch 到 main queue 中进行。
 @param |completionHandler| 在 task 结束时会被执行的 block,没有返回值。
                            其有三个参数分别为:server response、
                                              使用 response serializer 序列化的 response object、
                                              发生的错误,没有则为 nil。
 */
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
                                                 progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
                                        completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;

示例:

// 要上传的文件
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [sessionManager 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];

NSURLSessionUploadTask *uploadTask;
uploadTask = [sessionManager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
    // 非 main queue.
    // 如果你要更新 UI,则需要 dispatching 到 main queue 中进行。
    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];

AFHTTPSessionManager的使用

AFHTTPSessionManager继承自AFURLSessionManager,并在其基础上进行了封装。所以, AFHTTPSessionManager可以使用以上方法。AFHTTPSessionManager使用起来比较简单,仅需两步:

  • 创建 SessionManager,或使用已有的 SessionManager
  • 使用 SessionManager发起网络请求

同样的,简单的使用方法如下:

// 创建 SessionManager
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];

// 使用 SessionManager 发起网络请求
[manager GET:@"https://httpbin.org/get" parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id _Nullable responseObject){
    // 成功
    NSLog(@"%@", responseObject);

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 失败
    NSLog(@"%@", error);
}];

稍微详细一点的用法:

1. 初始化 SessionManager

初始化AFHTTPSessionManager需要两个参数:NSURLSessionConfiguration 和 BaseURL,当然可以根据情况选择一下几个初始化方法:

// baseURL为nil, NSURLSessionConfiguration 使用 defaultSessionConfiguration
+ (instancetype)manager;

// NSURLSessionConfiguration 使用 defaultSessionConfiguration
- (instancetype)initWithBaseURL:(nullable NSURL *)url;

// baseURL为nil
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration;

- (instancetype)initWithBaseURL:(nullable NSURL *)url
           sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;

示例:

// 创建 base URL
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];

// SessionConfiguration
NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 创建 SessionManager
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:configuration];
Session Configuration

SessionConfiguration 的内容同AFURLSessionManager。详见AFURLSessionManager中的SessionConfiguration 部分。

BaseURL

AFHTTPSessionManager内部会使用[NSURL URLWithString:URLString relativeToURL:self.baseURL]得到请求 URL。

示例:

NSURL *baseURL = nil;

[NSURL URLWithString:@"foo" relativeToURL:baseURL];                  // foo
[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];          // foo?bar=baz
[NSURL URLWithString:@"/foo" relativeToURL:baseURL];                 // /foo
[NSURL URLWithString:@"foo/" relativeToURL:baseURL];                 // foo/
[NSURL URLWithString:@"/foo/" relativeToURL:baseURL];                // /foo/
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/


NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];

[NSURL URLWithString:@"foo" relativeToURL:baseURL];                  // http://example.com/v1/foo
[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];          // http://example.com/v1/foo?bar=baz
[NSURL URLWithString:@"/foo" relativeToURL:baseURL];                 // http://example.com/foo
[NSURL URLWithString:@"foo/" relativeToURL:baseURL];                 // http://example.com/v1/foo/
[NSURL URLWithString:@"/foo/" relativeToURL:baseURL];                // http://example.com/foo/
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
SessionManager的简单配置

AFHTTPSessionManager的默认 Request Serializer 为AFHTTPRequestSerializer.

默认 Response Serializer 为AFJSONResponseSerializer.

可用的 Request Serializer 有:

  • AFHTTPRequestSerializer
  • AFJSONRequestSerializer
  • AFPropertyListRequestSerializer

可用的 Response Serializer 有:

  • AFHTTPResponseSerializer
  • AFJSONResponseSerializer
  • AFXMLParserResponseSerializer
  • AFXMLDocumentResponseSerializer
  • AFPropertyListResponseSerializer
  • AFImageResponseSerializer
  • AFCompoundResponseSerializer

示例:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

manager.responseSerializer = [AFImageResponseSerializer serializer];

2.使用 SessionManager 发起网络请求

GET 请求
/**
 发起一个 GET 请求,内部使用 NSURLSessionDataTask

 @param |URLString| 请求 URL
 @param |parameters| 请求参数,会使用 Request Serializer 自动序列化
 @param |downloadProgress| 在下载进度更新时执行的 block。需要注意的是:此 block 在
                           session queue 中被调用,而不是 main queue.更新 UI 时需要
                           dispatch 到 main queue 中进行。
 @param |success| 在请求成功时会被执行的 block,没有返回值。
                  其有两个参数分别为:dataTask、
                                    使用 response serializer 序列化的 response object.
 @param |failure| 在请求失败或解析 response data 出错时会被执行的 block。没有返回值。
                  其有两个参数分别为:dataTask、
                                    发生的错误,可能为网络错误或解析错误。

 @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
 */
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

示例:

NSDictionary *params = @{
                         @"foo": @"bar",
                         @"r":@"100"
                         };

[manager GET:@"https://httpbin.org/get" parameters:params progress:nil success:^(NSURLSessionDataTask *task, id _Nullable responseObject){
    // 成功
    NSLog(@"%@", task.originalRequest.URL);
    NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 失败
    NSLog(@"%@", error);
}];
POST 请求
/**
 发起一个 POST 请求,内部使用 NSURLSessionDataTask

 @param |URLString| 请求 URL
 @param |parameters| 请求参数,会使用 Request Serializer 自动序列化
 @param |uploadProgress| 在上传进度更新时执行的 block。需要注意的是:此 block 在
                         session queue 中被调用,而不是 main queue.更新 UI 时需要
                         dispatch 到 main queue 中进行。
 @param |success| 在请求成功时会被执行的 block,没有返回值。
                  其有两个参数分别为:dataTask、
                                    使用 response serializer 序列化的 response object.
 @param |failure| 在请求失败或解析 response data 出错时会被执行的 block。没有返回值。
                  其有两个参数分别为:dataTask、
                                    发生的错误,可能为网络错误或解析错误。

 @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
 */
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
                                
/**
 执行一个 multipart `POST` 请求,内部使用 NSURLSessionDataTask

 @param |URLString| 请求 URL
 @param |parameters| 请求参数,会使用 Request Serializer 自动序列化
 @param |block| A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol.
 @param |uploadProgress| 在上传进度更新时执行的 block。需要注意的是:此 block 在
                         session queue 中被调用,而不是 main queue.更新 UI 时需要
                         dispatch 到 main queue 中进行。
 @param |success| 在请求成功时会被执行的 block,没有返回值。
                  其有两个参数分别为:dataTask、
                                    使用 response serializer 序列化的 response object.
 @param |failure| 在请求失败或解析 response data 出错时会被执行的 block。没有返回值。
                  其有两个参数分别为:dataTask、
                                    发生的错误,可能为网络错误或解析错误。

 @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
 */
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

示例:

NSDictionary *params = @{
                         @"foo": @"bar",
                         @"r":@"100"
                         };

[manager POST:@"https://httpbin.org/post" parameters:params progress:nil success:^(NSURLSessionDataTask *task, id _Nullable responseObject){
    // 成功
    NSLog(@"%@", task.originalRequest.URL);
    NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 失败
    NSLog(@"%@", error);
}];

其他还有:HEADPUTPATCHDELETE等方法。

Tags: iOS, iOS开发
Archives QR Code Tip
QR Code for this page
Tipping QR Code
Leave a Comment