. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection be followed and this method will not be called. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask ---- 3. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:( ---- 4. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64 ---- 5. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError
. */ - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; @end 该类为UIKit框架的UIRefreshControl initWithActivityRefreshControl:(UIRefreshControl *)refreshControl; // 用于.h中方法的转发实现 - (void)setRefreshingWithStateOfTask:(NSURLSessionTask refreshControl; } return self; } ---- 接口的转发实现 转发实现主要采用下面这个方法 - (void)setRefreshingWithStateOfTask:(NSURLSessionTask - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { NSNotificationCenter *notificationCenter
- Simply referencing `[NSURLSessionTask class]` will not work. 的class,并不一定返回的是你想要的那个(获取NSURLSessionTask的class目的是为了获取其resume方法) 简单地使用[NSURLSessionTask class]并不起作用。 你需要新建一个NSURLSession,并根据创建的session再构建出一个NSURLSessionTask对象才行。 iOS 8上,NSURLSessionTask是唯一实现了resume和suspend方法的类。 原来这是因为iOS7和iOS8的NSURLSessionTask的继承链不同导致的,而且在iOS7继承链中会有两个类都实现了resume和suspend方法。
NSURLSession * defaultSession = [NSURLSession sessionWithConfiguration:defaultConfiguration]; //添加任务 NSURLSessionTask sessionWithConfiguration:defaultConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionTask NSData *)data{ NSLog(@"=======%@",data); } //接受数据结束 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask 之后应用程序在后台会调用NSURLSesstion代理的如下方法来通知下载结果: //此方法无论成功失败都会调用 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask
NSURLRequest *)request; /* * An NSURLSessionDataTask does not provide any additional * functionality over an NSURLSessionTask provide lexical differentiation from download and upload tasks. */ @interface NSURLSessionDataTask : NSURLSessionTask is a task that represents a download to * local storage. */ @interface NSURLSessionDownloadTask : NSURLSessionTask downloadProgressBlock; } - (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask SessionTask的代理方法NSURLSessionTaskDelegate \- (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask
获取对应的任务完成进度NSProgress - (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task; //根据NSURLSessionTask 获取对应下载任务的进度NSProgress - (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task; /// *task); typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask //定义了一个类AFURLSessionManagerTaskDelegate并实现了NSURLSessionTask的相关协议 //通过名称可以猜测,这个类是用于处理NSURLSessionTask相关代理方法的 //要执行重定向的代理方法 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
success 请求成功的回调 * @param failure 请求失败的回调 * * @return 返回的对象可取消请求,调用cancel方法 */ + (__kindof NSURLSessionTask success 请求成功的回调 * @param failure 请求失败的回调 * * @return 返回的对象可取消请求,调用cancel方法 */ + (__kindof NSURLSessionTask Nullable __autoreleasing * _Nullable error) { return parameters; }]; }]; NSURLSessionTask success 请求成功的回调 * @param failure 请求失败的回调 * * @return 返回的对象可取消请求,调用cancel方法 */ + (__kindof NSURLSessionTask 文件下载具体的方法实现如下: + (NSURLSessionTask *)downloadWithURL:(NSString *)URL fileDir
session会将request封装成一个NSURLSessionTask,然后通过task来控制网络请求的状态(比如开始、取消),以及监测网络请求的进度。如下图所示: ? NSURLSessionTask 上文道,可利用NSURLSession对象将NSURLRequest对象封装成一个NSURLSessionTask,之所以要进行这一层封装,就是为了方便管理网络请求的状态以及监控其网络进程 NSURLSessionTask的状态(state)有如下四种: typedef NS_ENUM(NSInteger, NSURLSessionTaskState) { NSURLSessionTaskStateRunning 的操作有如下三种: - (void)suspend;//挂起 - (void)resume;//恢复 - (void)cancel;//取消 一开始生成一个NSURLSessionTask对象后,该sessionTask 创建一个NSURLSessionConfiguration对象,并进行对应的个性化配置,然后将之传入生成一个NSURLSession; 使用NSURLSession对象将NSURLRequest对象封装成NSURLSessionTask
. */ - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task; @end 将动画状态绑定到指定任务的状态。 initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView; - (void)setAnimatingWithStateOfTask:(NSURLSessionTask OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return notificationObserver; } - (void)setAnimatingWithStateOfTask:(NSURLSessionTask activityIndicatorView = activityIndicatorView; } return self; } - (void)setAnimatingWithStateOfTask:(NSURLSessionTask - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { NSNotificationCenter *notificationCenter
; typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask session); typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task); typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask totalBytesExpectedToSend); typedef void (^AFURLSessionTaskDidCompleteBlock)(NSURLSession *session, NSURLSessionTask - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError
---- AFURLSessionManagerTaskDelegate代理为任务设置进度 主要对应的就是下面这一段代码 - (void)setupProgressForTask:(NSURLSessionTask NSKeyValueObservingOptionNew context:NULL]; 都是self,也就是AFURLSessionManager,来观察NSURLSessionTask change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([object isKindOfClass:[NSURLSessionTask NSString stringWithFormat:@"%p", self]; } - (void)taskDidResume:(NSNotification *)notification { NSURLSessionTask 暂停 - (void)taskDidSuspend:(NSNotification *)notification { NSURLSessionTask *task = notification.object
对于经过302重定向的链接,则需要如下修改: 打开SDWebImageDownloader.m类,修改- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask )(NSURLRequest * _Nullable))completionHandler方法如下: - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask
在网络请求中,真正去执行下载或者上传任务的就是URLSessionTask,我们来看一下它常用的方法: - (void)resume; 当使用NSURLSession创建一个NSURLSessionTask NSURLSessionTask还有个属性,@property (readonly) NSURLSessionTaskState state;此属性标识当前任务的状态,枚举类型 typedef NS_ENUM ,所有NSURLSessionTask的方法或者属性这四个类都有,那么,简单说一下这四个类都是干什么的。 它的大概思路是: 某种限制,续传暂停 将暂停后数据(当前数据)保存起来--_resumeData = resumeData; 条件允许续传时,使用resumeData创建新的NSURLSessionTask - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)
至于绑定的过程,就是以该session task的taskIdentifier为key(taskIdentifier是在创建task的时候NSURLSessionTask为其设置的,不需要手动设置,保证唯一性 方法就是将两者进行绑定,查看其实现代码 - (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask 当task任务完成之后,不管请求成功还是失败,都会执行- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError 从AFN框架中,可以发现AFURLSessionManagerTaskDelegate与NSURLSessionTask都是通过AFURLSessionManager来进行生成、绑定、销毁等管理操作的。
NSURLSessionDataTask /* * An NSURLSessionDataTask does not provide any additional * functionality over an NSURLSessionTask provide lexical differentiation from download and upload tasks. */ @interface NSURLSessionDataTask : NSURLSessionTask @end NSURLSessionDataTask不提供NSURLSessionTask的任何附加功能,它的存在仅仅是为了提供下载和上载任务的词汇区分。 - (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask 最后,就是为任务添加通知观察 [self addNotificationObserverForTask:task]; - (void)addNotificationObserverForTask:(NSURLSessionTask
Nullable error))completionHandler; // 通过task获取其上传进度 - (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task; // 通过ytask获取其下载进度 - (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task )block; - (void)setTaskNeedNewBodyStreamBlock:(nullable NSInputStream * (^)(NSURLSession *session, NSURLSessionTask ,具体实现如下 在NSURLSessionDataDelegate回调时,下面是获取数据完成的代理 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask 再来看AFURLSessionManagerTaskDelegate代理中相关实现 - (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask
API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); */ /* * NSURLSessionTask objects 接着往下面看,再往下就是NSURLSessionTask这个比较核心的类了,后面我们说的四个类(data/upload/download/stream)Task ,其中data、download、stream 是继承自我们要说的NSURLSessionTask这个核心。 嗯,就从最基本的NSURLSessionTask的API开始说起: /* @interface NSURLSessionTask : NSObject <NSCopying, NSProgressReporting 还要三个子类,在API中前面的两个子类我就没有什么还能说的了,因为都包含在了NSURLSessionTask中,唯一有一个需要我们说一下的,就是在NSURLSessionDownloadTask中有一个方法是父类中没有的
// 上传 @interface NSURLSessionUploadTask : NSURLSessionDataTask @interface NSURLSessionDataTask : NSURLSessionTask // 下载 @interface NSURLSessionDownloadTask : NSURLSessionTask 给大家贴出来就是想让大家注意下这个结构。 if ([keyPath isEqualToString:NSStringFromSelector(@selector(state))]) { if ([(NSURLSessionTask
发现NSURLSession存在leak,最后发现必须session请求完成后,立即释放,代码如下: - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask
1、NSURLRequest 2、NSURLSession 3、NSURLSessionTask 以及它的三个子类:NSURLSessionDataTask/NSURLSessionDownloadTask - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willBeginDelayedRequest:( - (void)URLSession:(NSURLSession *)session taskIsWaitingForConnectivity:(NSURLSessionTask *)task - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError