做网站首页轮播图代码,网站建设成果,做ppt介绍网站,怎么建立网站卖东西前言
学习了Mananger的初始化和以GET请求为例的过程#xff0c;发现整个过程离不开AFHTTPSessionManager和AFURLSessionManger的某些方法。这两个是AFN的重要的网络通信模块内容#xff0c;对它们作揖详细的学习。
AFURLSessionManager和AFHTTPSessionManager都是AFNetwork…前言
学习了Mananger的初始化和以GET请求为例的过程发现整个过程离不开AFHTTPSessionManager和AFURLSessionManger的某些方法。这两个是AFN的重要的网络通信模块内容对它们作揖详细的学习。
AFURLSessionManager和AFHTTPSessionManager都是AFNetworking库中的两个类用于处理网络请求和会话管理
如果只涉及到HTTP请求一般会直接使用AFHTTPSessionManager进行操作。而AFURLSessionManager则提供了更底层的接口适用于特定的定制需求或与NSURLSession相关的操作
1.1 AFURLSessionManger和AFHTTPSessionManager的关系
图解 首先AFURLSessionManger是AFHTTPSessionManager的父类其中AFURLSessionManger内部还包含AFURLSessionManagerTaskDelegate和_AFURLSessionTaskSwizzling
AFHTTPSessionManager本身是对网络请求做了一些简单的封装请求的整个逻辑是分发给AFURLSessionManager或者其他类去做的其内部管理自己的两种序列化工具用来对请求和响应的数据做序列化同时依赖于父类提供的保证安全监控网络状态实现发出HTTP请求的核心功能
AFHTTPSessionManager也可以是AFURLSessionManager的基础上进一步封装专门用于处理基于HTTP协议的网络请求提供了更方便的HTTP请求方法和相关功能如GET、POST等常见的HTTP方法以及请求参数的设置、请求头的配置、数据解析等功能
1.2 AFURLSessionManager
1.2.1 AFURLSessionManger功能
AFURLSessionManager负责生成对应的NSURLSession的实例管理AFNetworkReachabilityManager和AFSecurityPolicy以此一来查看网络的连接情况二来保证请求的安全同时初始化生成一个AFJSONResponseSerializer的实例来序列化HTTP的响应结果
遵守的协议
点击发现他遵守了很多的协议 除此之外还提供了属性和方法用来完成其功能
关键属性
property (nonatomic, strong) id AFURLResponseSerialization responseSerializer;
// 响应序列化// SSL的安全策略
property (nonatomic, strong) AFSecurityPolicy *securityPolicy;/// 网络监控
property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager;概览 核心方法就是生成一个AFURLSessionManager的实例对象上文在以GET请求为例的时候介绍了dataTaskWithRequest其实还有uploadTaskWithRequest和 downloadTaskWithRequest和downloadTaskWithResumeData
uploadTaskWithRequest
点击发现uploadTaskWithRequest存在三个不同的请求方法
uploadTaskWithRequest:(NSURLRequest *)requestfromFile(NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)requestfromData(NSURLSessionUploadTask *)uploadTaskWithStreamedRequest
/// 使用本地的文件请求创建一个NSURLSessionUploadTask
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)requestfromFile:(NSURL *)fileURLprogress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{/// 它调用了request和本地的文件URL路径创建了一个uploadTaskNSURLSessionUploadTask *uploadTask [self.session uploadTaskWithRequest:request fromFile:fileURL];/// 为该uploadTask太溺爱对应的代理 addDelegateForUploadTaskif (uploadTask) {[self addDelegateForUploadTask:uploadTaskprogress:uploadProgressBlockcompletionHandler:completionHandler];}return uploadTask;
}/// 根据指定的HTTP Body请求创建URLSessionUploadTask
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)requestfromData:(NSData *)bodyDataprogress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{NSURLSessionUploadTask *uploadTask [self.session uploadTaskWithRequest:request fromData:bodyData];[self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler];return uploadTask;
}
/// AFURLSessionManager的一个方法用于创建一个基于流的上传任务。具体参数说明如下
/// request上传请求即要上传的数据和上传地址。
/// uploadProgressBlock上传进度回调NSProgress对象用于获取上传进度信息。
/// completionHandler上传完成后的回调包含上传的响应、响应数据和错误信息。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)requestprogress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{/// 使用这个方法创建的上传任务数据是通过流的方式上传的而不是直接读取文件或数据进行上传因此适用于上传大文件或者流数据NSURLSessionUploadTask *uploadTask [self.session uploadTaskWithStreamedRequest:request];[self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler];return uploadTask;
}
uploadTaskWithRequest根据不同的数据创建一个NSURLSessionUploadTask任务最终都会走到AFURLSessionManageraddDelegateForUploadTask为对应的uploadTask设置代理 解析
/// uploadTask要添加代理的上传任务。
/// uploadProgressBlock上传进度回调通过该回调可以获取上传的进度信息。
/// completionHandler上传完成回调包含上传的响应、响应数据和错误信息。
- (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTaskprogress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{/// 创建了一个AFURLSessionManagerTaskDelegate对象作为上传任务的代理将该代理与上传任务关联AFURLSessionManagerTaskDelegate *delegate [[AFURLSessionManagerTaskDelegate alloc] initWithTask:uploadTask];delegate.manager self;delegate.completionHandler completionHandler;/// 将上传任务的描述设置为AFURLSessionManager的taskDescriptionForSessionTasks属性。uploadTask.taskDescription self.taskDescriptionForSessionTasks;/// 最后将代理对象设置为上传任务的代理并设置上传进度回调和上传完成回调[self setDelegate:delegate forTask:uploadTask];delegate.uploadProgressBlock uploadProgressBlock;
}downloadTaskWithRequest
/// 根据指定的请求创建downloadTask
// 参数
/// request下载请求即要下载的资源地址。
/// downloadProgressBlock下载进度回调用于获取下载进度信息。
/// destination下载目标回调用于指定下载文件的存储位置。
/// completionHandler下载完成回调包含下载的响应、文件路径和错误信息。
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)requestprogress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlockdestination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destinationcompletionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
{/// 使用self.session创建一个NSURLSessionDownloadTask对象即创建了一个下载任务。NSURLSessionDownloadTask *downloadTask [self.session downloadTaskWithRequest:request];/// 调用addDelegateForDownloadTask:progress:destination:completionHandler:方法为下载任务添加代理[self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler];return downloadTask;
}downloadTaskWithResumeData
/// 创建重用数据的下载任务根据已经下载的数据ResumeData创建下载任务继续进行下载
/// 官方用于创建一个带有断点续传功能的下载任务并添加相关的代理。// 参数
/// resumeData包含了之前下载任务的断点续传数据用于恢复之前的下载进度。
/// downloadProgressBlock下载进度回调用于获取下载进度信息。
/// destination下载目标回调用于指定下载文件的存储位置。
/// completionHandler下载完成回调包含下载的响应、文件路径和错误信息。
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeDataprogress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlockdestination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destinationcompletionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
{/// 首先使用self.session和提供的断点续传数据resumeData创建一个NSURLSessionDownloadTask对象即创建了一个带有断点续传功能的下载任务。NSURLSessionDownloadTask *downloadTask [self.session downloadTaskWithResumeData:resumeData];/// 调用addDelegateForDownloadTask:progress:destination:completionHandler:方法为下载任务添加代理并传入下载进度回调、目标回调和完成回调。[self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler];return downloadTask;
}
download最终也会调用addDelegateForDownloadTask
解析
/// 该方法 用于为下载任务添加代理和相关的回
/// downloadTask要添加代理的下载任务。
/// downloadProgressBlock下载进度回调用于获取下载进度信息。
/// destination下载目标回调用于指定下载文件的存储位置。
/// completionHandler下载完成回调包含下载的响应、文件路径和错误信息。、
- (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTaskprogress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlockdestination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destinationcompletionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
{AFURLSessionManagerTaskDelegate *delegate [[AFURLSessionManagerTaskDelegate alloc] initWithTask:downloadTask];delegate.manager self;delegate.completionHandler completionHandler;/// 如果提供了destination回调则设置代理的downloadTaskDidFinishDownloading属性为一个代码块该代码块接收NSURLSession、NSURLSessionDownloadTask和下载文件的临时位置作为参数并通过调用destination回调来返回最终的下载文件位置if (destination) {delegate.downloadTaskDidFinishDownloading ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) {return destination(location, task.response);};}/// 设置下载任务的taskDescription属性为self.taskDescriptionForSessionTasks这是用于描述任务的字符串。downloadTask.taskDescription self.taskDescriptionForSessionTasks;[self setDelegate:delegate forTask:downloadTask];delegate.downloadProgressBlock downloadProgressBlock;
}
1.2.2 AFURLSessionMananger遵守的代理
在AFURLSessionMananger的实现文件里面可以发现NSURLSessionTaskDelegateNSURLSessionDataDelegate以及NSURLSessionDownloadDelegate。
需要提前说明的是AFURLSessionManager对这些代理做了一些公共的处理最终转发到自定义的代理AFURLSessionManagerTaskDelegate的3个代理方法中用来负责把每个task对应的数据回调回去
围绕他们三个展开学习 NSURLSessionDownloadDelegate
NSURLSessionDownloadDelegate的方法在AFURLSessionMananger实现了3个。
URLSession:downloadTask:didFinishDownloadingToURL: 在下载任务完成后调用提供下载文件的临时位置URL。可以在此方法中处理下载后的文件移动、保存等操作。URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: 在下载任务进行中定期调用提供下载进度的相关信息包括已写入数据大小和总数据大小。可以在此方法中更新下载进度条等UI元素。URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes: 在恢复下载任务时调用提供已恢复的下载位置和预期的总字节数。
#pragma mark - NSURLSessionDownloadDelegate
/// 在下载任务完成后调用提供下载文件的临时位置URL。可以在此方法中处理下载后的文件移动、保存等操作。
- (void)URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
// 转发代理AFURLSessionManagerTaskDelegate *delegate [self delegateForTask:downloadTask];if (self.downloadTaskDidFinishDownloading) {NSURL *fileURL self.downloadTaskDidFinishDownloading(session, downloadTask, location);if (fileURL) {delegate.downloadFileURL fileURL;NSError *error nil;if (![[NSFileManager defaultManager] moveItemAtURL:location toURL:fileURL error:error]) {[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:error.userInfo];} else {[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidMoveFileSuccessfullyNotification object:downloadTask userInfo:nil];}return;}}if (delegate) {[delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location];}
}
/// 在下载任务进行中定期调用提供下载进度的相关信息包括已写入数据大小和总数据大小。可以在此方法中更新下载进度条等UI元素。
- (void)URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTaskdidWriteData:(int64_t)bytesWrittentotalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{// 转发代理AFURLSessionManagerTaskDelegate *delegate [self delegateForTask:downloadTask];if (delegate) {[delegate URLSession:session downloadTask:downloadTask didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];}if (self.downloadTaskDidWriteData) {self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);}
}
/// 在恢复下载任务时调用提供已恢复的下载位置和预期的总字节数
- (void)URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTaskdidResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes
{// // 转发代理AFURLSessionManagerTaskDelegate *delegate [self delegateForTask:downloadTask];if (delegate) {[delegate URLSession:session downloadTask:downloadTask didResumeAtOffset:fileOffset expectedTotalBytes:expectedTotalBytes];}if (self.downloadTaskDidResume) {self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes);}
}这三个代理方法最终都会进行代理转发到AFURLSessionManagerTaskDelegate中AF中的deleagate是需要对应每个task去私有化处理的对应看看AFURLSessionManagerTaskDelegate中的这三个代理方法都做了什么 吧
ps:别跳转错了
#pragma mark - NSURLSessionDownloadDelegate- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidWriteData:(int64_t)bytesWrittentotalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{// 更新当前下载进度self.downloadProgress.totalUnitCount totalBytesExpectedToWrite;self.downloadProgress.completedUnitCount totalBytesWritten;
}- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes{// 更新当前下载进度self.downloadProgress.totalUnitCount expectedTotalBytes;self.downloadProgress.completedUnitCount fileOffset;
}
/// ‼️下载完成调用
- (void)URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{self.downloadFileURL nil;if (self.downloadTaskDidFinishDownloading) {self.downloadFileURL self.downloadTaskDidFinishDownloading(session, downloadTask, location);if (self.downloadFileURL) {NSError *fileManagerError nil;if (![[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:fileManagerError]) {[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo];} else {[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidMoveFileSuccessfullyNotification object:downloadTask userInfo:nil];}}}
}
在 ‼️ 下载完成时的调用代理方法中AFURLSessionManager和AFURLSessionManagerTaskDelegate中都进行了文件路径的移动而NSURlSession代理的下载路径是所有request公用的下载路径设置之后所有的request都会下载到之前的那个路径。而AFURLSessionManagerTaskDelegate中对应到每一个task中每一个task可以设置自己的下载路径总结这些代理方法在AFURLSessionManager中实现的时候都是对session做一个公共的处理每一个不同的task进行特定的处理时需要将代理转发到AFURLSessionManagerTaskDelegate中在AFURLSessionManagerTaskDelegate的代理中实现
1.3 AFURLSessionManagerTaskDelegate的作用
AFURLSessionManagerTaskDelegate 是 AFNetworking 框架中的一个类用于处理 URLSessionTask 相关的代理回调。它作为 AFURLSessionManager 的任务代理负责处理网络请求任务的进度、完成回调等操作。
具体来说AFURLSessionManagerTaskDelegate 的主要作用包括
处理任务进度通过设置 uploadProgressBlock 和 downloadProgressBlock 属性可以监控上传任务和下载任务的进度并在进度发生变化时执行相应的代码块。处理任务完成回调在任务完成时会执行 completionHandler 属性所指定的代码块将任务的响应、响应数据和错误信息传递给回调函数以便进一步处理任务的结果。处理下载任务的文件保存路径对于下载任务可以通过设置 downloadTaskDidFinishDownloading 属性来指定任务完成后将文件保存的路径。管理任务与代理的关系在创建任务时会将任务与对应的 AFURLSessionManagerTaskDelegate 对象关联起来以确保任务的代理回调能够正确处理。总的来说AFURLSessionManagerTaskDelegate 扮演了一个中间角色连接了 URLSessionTask 和 AFURLSessionManager 之间的交互处理任务的进度、完成回调和其他相关操作提供了更便捷的方式来管理和处理网络请求任务。
2. AFHTTPSessionManager
AFHTTPSessionManager本身是对网络请求做了一些简单的封装请求的整个逻辑是分发给AFURLSessionManager或者其他类去做的其内部管理自己的两种序列化工具用来对请求和响应的数据做序列化同时依赖于父类提供的保证安全监控网络状态实现发出HTTP请求的核心功能
2.1 属性和接口 其实上一章已经很详细的说明了很多AFHTTPSessionManager的内容
AFHTTPSessionManager的一些方法的实现初始化方法最终都会调用到AFURLSessionManager中的初始化方法完成sessionManager的初始化
GET为例
- (NSURLSessionDataTask *)GET:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary NSString *, NSString * *)headersprogress:(nullable void (^)(NSProgress * _Nonnull))downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{/// 调用 dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure: 方法该方法创建一个 NSURLSessionDataTask 数据任务对象用于执行指定的 HTTP GET 请求。将传入的参数传递给该方法以构建请求。NSURLSessionDataTask *dataTask [self dataTaskWithHTTPMethod:GETURLString:URLStringparameters:parametersheaders:headersuploadProgress:nildownloadProgress:downloadProgresssuccess:successfailure:failure];/// 调用 [dataTask resume] 方法启动数据任务使其开始执行。[dataTask resume];/// 返回数据任务对象 dataTask。return dataTask;
参数
URLString:请求的URL值
parameters:根据需求的请求参数
headers:请求头
downloadProgress更新下载进度的对象
success任务成功后执行的Block对象
failure任务失败后执行的Block对象
}一是生成一个dataTask任务二是调用resume开启请求
该类的核心方法dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure: 该方法是生成datatask是AFHTTPSessionManager中的da taTaskWithHTTPMethod方法
在上一章也讲过 很重要
该方法做了两件事情一是对请求参数进行序列化二是调用dataTaskWithRequest方法生成后一个datatask任务最终返回一个datatask
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary NSString *, NSString * *)headersuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{NSError *serializationError nil;/// 使用 self.requestSerializer 对象根据传入的参数构建一个 NSMutableURLRequest 可变请求对象。/// self.requestSerializer请求序列化器/// ‼️‼️ 需要点进去的方法1NSMutableURLRequest *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: 方法来配置任务的上传进度回调、下载进度回调和完成处理程序块。// ‼️ 需要点进去的方法2dataTask [self dataTaskWithRequest:requestuploadProgress:uploadProgressdownloadProgress:downloadProgresscompletionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {if (failure) {failure(dataTask, error);}} else {if (success) {success(dataTask, responseObject);}}}];return dataTask;总结
到此网络通讯模块所做的事情就到此在该模块中主要的任务就是发起网络请求。分成AFURLSessionManger和 AFHTTPSessionManager两部分来做处理。 AFURLSessionManger是AFHTTPSessionManager的父类其中AFURLSessionManger内部还包含AFURLSessionManagerTaskDelegate和_AFURLSessionTaskSwizzlingAFHTTPSessionManager本身是对网络请求做了一些简单的封装请求的整个逻辑是分发给AFURLSessionManager或者其他类去做的其内部管理自己的两种序列化工具用来对请求和响应的数据做序列化同时依赖于父类提供的保证安全监控网络状态实现发出HTTP请求的核心功能
参考AFN源码解析