Article directory
- Preface
- 1. Native network request sending method
- 2.AFN
-
- 2.1 Analysis of the basic architecture of AFN
- 2.2 Take GET as an example to analyze the AFN usage process (AFHTTPSessionManager
- 2.3 Process analysis of Mananger calling GET method
- In this method we need to check two methods, which I have marked.
- requestWithMethod: perform serialization processing
- dataTaskWithRequest: Generate a datatask task
- completionHandler
- Summarize
Preface
Source code library part two.
AFNetworking
This framework is a necessary third-party framework for iOS. Its efficient and concise API makes it the best iOS network request framework. It also makes network requests developed on iOS much easier. For native GET and POST requests, this framework AFNetworking
provides A more convenient method facilitates client-server interaction.
This study is based on the AFNetworking4.0 library. Compared with 3.0, request headers are added, because when writing the project, I also found that whether it is my own backend or the native backend API, I need to write request headers.
The request header (Request Header)
is a part of the information included in the HTTP request and is used to pass additional information and parameters about the request to the server.
1. Native network request sending method
Since NSURLConnection
it has been abandoned, it will be discussed here NSURLSession
. Start with two request methods: GET and POST.
1.1 Native GET
step
- Determine the request path
- Create a variable request object
request
: can be omitted ((request header and request method [Get] are included by default), this step can be omitted). - Create session
session
object - Create a request task based on the session object
datatask
(usedataTaskWithRequest
ordataTaskWithURL
method to create) - Execute Task task
- After getting the response returned by the server, parse the data (XML, JSON, HTTP). If the returned data is in JSON format, use
NSJSONSerialization
the
1.2 Native PSOT
- For the native POST step, there is one more request header than GET, and the request object cannot be omitted in native POST because the request header needs to be added to the request.
- Determine the requested path URL
- Create a variable request object request: cannot be omitted - POST requests need to set request headers
- Set the request header (the created request header needs to be serialized: ensure it is a data format recognized by the server) and the request method POST
- Create session object
- Create a request task datatask based on the session object - (via dataTaskWithRequest)
- Execute Task
- After getting the response returned by the server, parse the data (XML, JSON, HTTP). If the returned data is in JSON format, use NSJSONSerialization for deserialization.
2.AFN
2.1 Analysis of the basic architecture of AFN
The basic architecture of AFN4.0 and 3.0 has not changed much, and the whole is divided into file parts as shown in the figure.
NSURLSession
: The main class of network requests,AFURLSessionManager
encapsulatedNSURLSession
,AFHTTPSessionManager
but its subclasses, which have been optimized for HTTP requestsReachability
: Network status,AFNetworkReachabilityManager
a class used to monitor the current network statusSecurity
: Network security, HTTPS requests must be usedAFSecurityPolicy
Serialization
: Serialization,AFURLRequestSerialization
which is the serialization before the requestAFURLResponseSerialization
and the serialization of the result after the request is completed.UIKit
: Inside are some UIkit extensionsCategory
The relationship between classes is shown in the figure below.
The module division of AFN
- Through the use and the above diagram, it can be seen that the entire AFN is centered around
AFURLSessionManager
. AFNetWorking
It is roughly divided into five major modules, the most core of which is the network communication module, which is mainly used to send and respond to requests.AFNetworkReachabilityManager
It is mainly used to monitor network status, and perform different operations and processing of requests and responses under different network statuses;
in order to ensure the security of network requests, of courseAFSecurityPolicy
, the network security policy module is indispensable, andsessionmanger
is initialized at the same timeAFSecurityPolicy
as network communication during initialization. Information request serialization class- The network communication information serialization module is divided into request serialization and response serialization. The request header and response header are encoded internally. When requesting, the request header is transcoded into a computer-recognizable format. When responding , Transcode the response result and send it back to the client
- Some related extensions of the UIKit library, including UIImageView requests, UIButton requests, etc.
The entire step can also be understood as the following figure
- Network communication module (AFURLSessionManager, AFHTTPSessionManager)
- Network status monitoring module (AFNetworkReachabilityManager)
- Network communication security policy module (AFSecurityPolicy)
- Network communication information serialization module (AFURLRequestSerialization, AFURLResponseSerialization)
- Expansion of the iOS UIkit library (UIKit)
2.2 Take GET as an example to analyze the AFN usage process (AFHTTPSessionManager
Taking the GET request as an example, the following is the code of the request.
- Generate the corresponding sessionManager;
- Call the GET method to make a request;
- The processing results in the GET callback include (task progress, result of successful request, result of failed request);
2.2.1 How AFN generates the corresponding sessionManager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
Follow the illustrations step by step
First initialize, and then call the methods of the parent class step by step. Let's look at it in sections.
- initialize, call
initWithBaseURL
+ (instancetype)manager {
return [[[self class] alloc] initWithBaseURL:nil];
}
initWithBaseURL
transferinitWithBaseURL:(NSURL *)url sessionConfiguration:
- (instancetype)initWithBaseURL:(NSURL *)url {
return [self initWithBaseURL:url sessionConfiguration:nil];
}
initWithBaseURL:(NSURL *)url sessionConfiguration:
implementation analysis
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
// 最终都会调用父类的方法去实现初始化
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
// Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
//条件判断了URL的路径是否具有长度大于0。它使用了[url path]方法来获取URL的路径,并通过length方法获取路径的长度。
// [[url absoluteString] hasSuffix:@"/"]:这个条件判断了URL的绝对字符串表示是否以斜杠("/")结尾。它使用了[url absoluteString]方法获取URL的绝对字符串表示,并通过hasSuffix:方法检查字符串是否以斜杠结尾。
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
// 如果上述两个条件都为真(路径长度大于0且不以斜杠结尾),则执行以下代码块:
// url = [url URLByAppendingPathComponent:@""];:这行代码使用URLByAppendingPathComponent:方法将一个空路径组件追加到原始URL的路径末尾,从而确保URL的路径以斜杠结尾。
url = [url URLByAppendingPathComponent:@""];
}
self.baseURL = url;
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
- Overall, what this code does is it checks if the path of the URL is empty or does not end with a slash, and if the condition is not met, appends an empty path component to the end of the path to ensure that the path of the URL ends with a slash.
2.2.2. Initialization of AFURLSessionManager
From the last call above, self = [super initWithSessionConfiguration:configuration];
we can see that AFHTTPSessionManager
the initialization method at the end will eventually call the initialization method of its parent class initWitchSessionConfiguration
and return a sessionManager
method; then, we need to take a look at what the parent class, that is, AFURLSessionManager
has done with its initialization.
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
if (!configuration) {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
/*
NSURLSessionConfiguration是用于配置NSURLSession的类。它提供了一系列属性和方法,用于定制和管理会话(session)的行为和特性。
defaultSessionConfiguration:返回一个默认的会话配置,可用于创建默认的NSURLSession实例。
*/
}
self.sessionConfiguration = configuration;
/// 初始化操作队列 并设置为串行队列 设置最大并发操作数
self.operationQueue = [[NSOperationQueue alloc] init];
/// ‼️队列的最大并发操作数设置为1,这里的并发操作数值的是回调代理的线程并发数。
/// ‼️在多线程编程中,操作队列(operation queue)是用于管理操作(operation)的一种机制。操作队列可以用来异步执行一系列任务,并控制它们的并发性。
/// 通过将最大并发操作数设置为 1,即 maxConcurrentOperationCount = 1,可以确保操作队列中的操作按顺序依次执行,而不会并发执行。这意味着每个操作将在上一个操作完成后才会开始执行。
self.operationQueue.maxConcurrentOperationCount = 1;
/// AFJSONResponseSerializer 用来序列化HTTP的响应
self.responseSerializer = [AFJSONResponseSerializer serializer];
/// 初始化SSI需要的 AFSecurityPolocy用来保证请求的安全性
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
#if !TARGET_OS_WATCH
/// AFNetWorkRarchability Manager 查看网络连接情况
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif
/// ‼️初始化可变任务字典 任务task的id作为key 代理对象作为value
/// self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];是用来将每一个请求任务和自定义的AFURLSessionManagerTaskDelegate来建立映射的;(需要深入研究,代理和这里的关系,以及利用KVO的思想实现的相关)
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
// 锁的初始化并命名
self.lock = [[NSLock alloc] init];
self.lock.name = AFURLSessionManagerLockName;
/// ‼️ 在初始化的时候获取当前session中的所有task,为它们重新设置一遍代理;一般来说初始化的session中的task应该是为空的,这里这么做的主要目的是为了防止从后台回来的时候初始化session,对于一些后台之前的请求任务没有重设代理导致崩溃的问题
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
for (NSURLSessionDataTask *task in dataTasks) {
[self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
}
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
[self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
}
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
[self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
}
}];
return self;
}
- Initialize the current session configuration, operation queue, lock,
AFNetworkReachabilityManager
,AFSecurityPolicy
request serialization and variable task dictionary used to store tasks and other attributes; - Get all unfinished tasks in the current session and set agents for them;
- requires attention! ️Place:
-
self.mutableTaskDelegatesKeyedByTaskIdentifier
Is a mutable dictionary attribute used to associate a task identifier with the corresponding task delegate object
-
- ‼ ️In multi-threaded programming, the operation queue is a mechanism used to manage operations. Operation queues can be used to execute a series of tasks asynchronously and control their concurrency.
-
- By setting the maximum number of concurrent operations to 1, that is, maxConcurrentOperationCount = 1, you can ensure that the operations in the operation queue are executed in order and not concurrently. This means that each operation will not start executing until the previous operation has completed.
2.2.3 Three types of agents for tasks
For different tasks, how AFN completes network requests, uses getTasksWithCompletionHandler
: method to obtain all tasks in the current session (session), and adds the corresponding task delegation object to each task.
The execution flow of the code is as follows:
- Call
getTasksWithCompletionHandler:
a method that accepts a completion handler block as a parameter. - In the completion handler block, you will receive three parameters
dataTasks
,uploadTasks
anddownloadTasks
, which respectively represent the data task, upload task and download task in the current session. - Use a
for-in
loop to iterate over the array, performing the following operationsdataTasks
for each task of type:NSURLSessionDataTask
- Call
addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:
the method, passing the task and corresponding parameters to the method. - This method will add a task delegate object for the data task and set callbacks for upload and download progress and task completion as needed.
- Call
- Use a
for-in
loop to iterate over the array, performing similar operationsuploadTasks
for each type of task:NSURLSessionUploadTask
- Call
addDelegateForUploadTask:progress:completionHandler:
the method, passing the task and corresponding parameters to the method. - This method will add a task delegate object for the upload task, and set callbacks for upload progress and task completion as needed.
- Call
- Use a
for-in
loop to iterate over the array, performing similar operationsdownloadTasks
for each type of task:NSURLSessionDownloadTask
- Call
addDelegateForDownloadTask:progress:destination:completionHandler:
the method, passing the task and corresponding parameters to the method. - This method will add a task delegation object to the download task, and set callbacks for the download progress, file saving path, and task completion as needed.
- Call
Through getTasksWithCompletionHandler
methods, the appropriate task delegation object can be associated with each task, and the execution process of the task can be tracked and processed.
2.2.3.1 setDelegate method
View the source code of these three proxy methods.
By observing the implementation of the three proxy methods, they will be called in the end.setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask *)task
An implementation of a method that sets the corresponding task delegate object setDelegate:forTask:
for a given .NSURLSessionTask
AFURLSessionManagerTaskDelegate
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
forTask:(NSURLSessionTask *)task
{
/// 首先,通过使用 NSParameterAssert 宏进行断言,确保 task 和 delegate 参数非空。这是一种防御性编程的做法,以确保传入的参数符合预期,避免在后续使用过程中出现问题。
NSParameterAssert(task);
NSParameterAssert(delegate);
/// 接下来,通过调用 [self.lock lock] 来获取一个锁,确保在多线程环境中对 self.mutableTaskDelegatesKeyedByTaskIdentifier 字典的操作是线程安全的。
[self.lock lock];
/// 将 delegate 任务委托对象与 task.taskIdentifier 任务标识符关联,并将其存储在 self.mutableTaskDelegatesKeyedByTaskIdentifier 字典中。使用 @(task.taskIdentifier) 将任务标识符转换为 NSNumber 对象作为字典的键。
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
/// 调用 [self addNotificationObserverForTask:task] 方法,为任务添加通知观察者,以便在任务执行过程中获取相关通知,如任务完成、进度更新等。
[self addNotificationObserverForTask:task];
/// 最后,通过调用 [self.lock unlock] 释放锁,确保线程安全的访问完成。
[self.lock unlock];
}
The function of this method is to associate the specified task delegation object with the task and store it in the dictionary for subsequent use. This makes it easy to track and manage the delegate objects associated with each task for task status tracking, result processing, or other related operations.
2.2.4 Summary of how AFN generates the corresponding sessionManager
session
At this point, for all the current ones obtained during initialization task
, the agents have been reset for them. Return to initWitchSessionConfiguration
the method to return the current object, return upward, and generate AFHTTPSessionManager *sessionMange
an r object;
2.3 Process analysis of Mananger calling GET method
Let’s take GET as an example and look at the diagram first.
2.3.1 Execution process of GET method
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(nullable id)parameters
headers:(nullable NSDictionary <NSString *, NSString *> *)headers
progress:(nullable void (^)(NSProgress * _Nonnull))downloadProgress
success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
/// 调用 dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure: 方法,该方法创建一个 NSURLSessionDataTask 数据任务对象,用于执行指定的 HTTP GET 请求。将传入的参数传递给该方法以构建请求。
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
URLString:URLString
parameters:parameters
headers:headers
uploadProgress:nil
downloadProgress:downloadProgress
success:success
failure:failure];
/// 调用 [dataTask resume] 方法启动数据任务,使其开始执行。
[dataTask resume];
/// 返回数据任务对象 dataTask。
return dataTask;
参数:
URLString:请求的URL值
parameters:根据需求的请求参数
headers:请求头
downloadProgress:更新下载进度的对象
success:任务成功后执行的Block对象
failure:任务失败后执行的Block对象
}
The execution flow of the code is as follows:
- Receive the incoming
URLString
,parameters
,headers
,downloadProgress
,success
andfailure
parameters, which respectively represent the requested URL string, request parameters, request headers, download progress callback, success callback and failure callback. - Call
dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:
the method, which creates aNSURLSessionDataTask
data task object for performing the specified HTTP GET request. Pass incoming parameters to this method to build the request. - Call
[dataTask resume]
the method to start the data task so that it can begin execution. - Returns the data task object
dataTask
.
Through this code, you can easily initiate a GET request, and you can customize the request URL, parameters, request headers, etc. by passing in parameters. At the same time, you can specify download progress callback, success callback and failure callback to handle the result and status of the request. Finally, the in the code [dataTask resume]
starts the task, causing it to begin executing.
Generate dataTask method
dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:
This method is to generate datatask and is the da methodAFHTTPSessionManager
intaTaskWithHTTPMethod
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable id)parameters
headers:(nullable NSDictionary <NSString *, NSString *> *)headers
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
NSError *serializationError = nil;
/// 使用 `self.requestSerializer` 对象根据传入的参数构建一个 `NSMutableURLRequest` 可变请求对象。
/// self.requestSerializer:请求序列化器
/// ‼️‼️ 需要点进去的方法1
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
for (NSString *headerField in headers.keyEnumerator) {
[request setValue:headers[headerField] forHTTPHeaderField:headerField];
}
/// // 如果在构建请求过程中出现了 `serializationError` 错误,即请求参数序列化错误,则会执行相应的错误处理逻辑。
if (serializationError) {
if (failure) {
/// 如果存在 `failure` 失败回调,则将错误通过异步方式回调到主队列上。
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
}
return nil;
}
/// 创建一个 `NSURLSessionDataTask` 数据任务对象
__block NSURLSessionDataTask *dataTask = nil;
/// 并调用 `dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:` 方法来配置任务的上传进度回调、下载进度回调和完成处理程序块。
// ‼️ 需要点进去的方法2
dataTask = [self dataTaskWithRequest:request
uploadProgress:uploadProgress
downloadProgress:downloadProgress
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
if (failure) {
failure(dataTask, error);
}
} else {
if (success) {
success(dataTask, responseObject);
}
}
}];
return dataTask;
}
dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:
implementation of the method. This method is used to create a NSURLSessionDataTask
data task object and configure the relevant parameters of the request.
The execution flow of the code is as follows:
- Receive the incoming
method
,URLString
,parameters
,headers
,uploadProgress
,downloadProgress
,success
andfailure
parameters, which respectively represent the requested HTTP method, URL string, request parameters, request header, upload progress callback, download progress callback, success callback and failure callback. - Use the object to construct a mutable request object
self.requestSerializer
based on the parameters passed in .NSMutableURLRequest
The requested URL will be spliced and converted according toURLString
and .self.baseURL
The request parameters and error object will berequestWithMethod:URLString:parameters:error:
returned by the method. - Traverse
headers
the key-value pairs in the dictionary, use the key as the request header field, and the value as the request header value, andsetValue:forHTTPHeaderField:
set it to the request object through the method. - If an error occurs during the construction of the request
serializationError
, that is, a request parameter serialization error, the corresponding error handling logic will be executed. If there isfailure
a failure callback, the error will be called back to the main queue asynchronously. - Create a
NSURLSessionDataTask
Data Task object and calldataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
the method to configure the task's upload progress callback, download progress callback, and completion handler blocks. - Returns the data task object
dataTask
.
In this method we need to check two methods, which I have marked.
- One is
requestWithMethod
serialization processing -
- Reasons for serialization processing: HTTP network requests are based on network transmission of byte streams. Serialization can convert an object into a byte encoding to facilitate transmission on the network or other storage processing. When used, Deserialize it; to put it simply, for the sake of unification , we can use our own methods to save objects, but at the bottom level we only provide a mechanism to save the object state. Therefore, we need to serialize when storing to keep it consistent with the provided, and deserialize it when reading to get the form we want;
- One is to
dataTaskWithRequest
generate data tasks
requestWithMethod: perform serialization processing
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
error:(NSError *__autoreleasing *)error
{
/// 首先进行参数断言,确保传入的 method 和 URLString 不为 nil
NSParameterAssert(method);
NSParameterAssert(URLString);
/// 使用 NSURL 的 URLWithString: 方法将 URLString 转换为 NSURL 对象,然后进行参数断言,确保 url 不为 nil。
NSURL *url = [NSURL URLWithString:URLString];
NSParameterAssert(url);
/// 创建一个可变的 NSMutableURLRequest 请求对象,使用 initWithURL: 方法将 url 作为初始化参数,并将 method 赋值给请求对象的 HTTPMethod 属性。
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];
mutableRequest.HTTPMethod = method;
///遍历 AFHTTPRequestSerializerObservedKeyPaths() 方法返回的被观察的键路径,通过ketPath检查 self.mutableObservedChangedKeyPaths 是否包含该键路径,如果包含,则将 self 对象的对应键路径的值设置为请求对象的对应键路径的值。存到mutableRequest中
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) {
[mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath];
}
}
/// 调用 requestBySerializingRequest:withParameters:error: 方法,将请求对象和参数进行序列化,返回一个经过序列化处理的请求对象。如果出现错误,会将错误对象赋值给传入的 error 参数。
mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy];
///mutableCopy: 将序列化后的请求对象转换为可变的副本,并返回该对象。
return mutableRequest;
}
dataTaskWithRequest: Generate a datatask task
- (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 {
/// 接收一个 NSURLRequest 对象作为请求参数,并使用该请求对象创建一个 NSURLSessionDataTask 对象,即 dataTask。
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
/// 调用 self 对象的 addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler: 方法,为 dataTask 添加代理、上传进度回调、下载进度回调和完成处理块。这些参数分别是 uploadProgressBlock、downloadProgressBlock 和 completionHandler。
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
return dataTask;
}
AFURLSessionManager
The implementation of the class dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
method. This method is used to create an NSURLSessionDataTask
object and add a proxy and related progress callbacks and completion handling blocks to the task.
completionHandler
completionHandler
Is a callback closure used to process the results returned after the network request is completed. It is defined as(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))
- Where
response
is the response object of the request,responseObject
is the response body data (can be NSData, NSDictionary, etc.),error
is the error message that occurs during the request process, such as network unavailability, request timeout, etc. - In
dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
, when the network request is completed, this closure will be called to process the request result.
Summarize
After completing the above processing, the generated dataTask is finally returned to the GET method, so that we finally get the task in GET that we can send the request to, and finally call the system method [dataTask resume]; initiate a network request;
AFURLSessionManager and the many proxies it complies with are called when we make network requests. Next, we will learn about AFURLSessionManager and its proxy parsing.