iOS_使用NSURLSessionDataDelegate的代理方法下载数据

来源:互联网 发布:sql新增字段语句 编辑:程序博客网 时间:2024/04/29 14:36

转载自iOS_使用NSURLSessionDataDelegate的代理方法下载数据 作者 Sponge_CMZ



目录(?)[+]

  • 说明:

    • 本文将介绍NSURLSessionDataDelegate, 使用NSURLSessionDataDelegate方法实现下载数据. 博文底部会对文中所使用的方法有详细的介绍, 如果感兴趣可以仔细阅读.

    • session 类型 : default session.

    • session的创建方法: + sessionWithConfiguration:delegate:delegateQueue:

    • task 类型: data task. 

    • 代码中所使用到的接口(例: http://c.3g.163.com/photo/api/list/0096/4GJ60096.json) 都具有时效性, 建议测试时使用一个可以提供数据的新接口.

  • 文章中尽量不使用或少使用封装, 目的是让大家清楚为了实现功能所需要的官方核心API是哪些(如果使用封装, 会在封装外面加以注释)

  • 此文章由 @春雨 编写. 经 @Scott,@黑子 审核. 若转载此文章,请注明出处和作者

iOS_NSURLSessionDataDelegate

核心API

Class :

  • NSURLSession
  • NSURLSessionConfiguration
  • NSURLSessionTask 
    • NSURLSessionDataTask
    • NSURLSessionDownload

Delegate :

  • NSURLSessionDelegate
  • NSURLSessionTaskDelegate
  • NSURLSessionDataDelegate
  • NSURLSessionDownloadDelegate

涉及的API :

  • NSURLSession
/** 创建NSURLSession对象的类方法. */+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue/** 通过URL, 返回一个数据任务. */- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url/** 通过request请求, 返回一个数据任务. */- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDataDelegate
/**  告诉delegate已经接受到服务器的初始应答, 准备接下来的数据任务的操作. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler/** 告诉delegate已经接收到部分数据. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data/** 告诉delegate, data task 已经转变成download task. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • NSURLSessionTaskDelegate
/** 告诉delegate, task已经完成. */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
  • 1
  • 2
  • 1
  • 2
  • NSURLSessionDownloadDelegate
/** 告诉delegate, download task已经完成. */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
  • 1
  • 2
  • 1
  • 2

功能实现

思路 :

  1. 正常实现data任务的下载.
  2. data任务转成download任务, 完成下载.
  3. 取消data任务下载.

Code :

一. 正常实现data任务的下载.

步骤1 : 

/** 签订代理. */@interface ViewController ()<NSURLSessionDelegate,  NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>/** 设置一个NSMutableData类型的对象, 用于接收返回的数据. */@property (nonatomic, retain) NSMutableData *allData;@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

步骤3 : 创建会话和任务

- (void)handleData /*-> 自己定义的一个方法. */{     /** 1. 创建NSURLSessionConfiguration类的对象, 这个对象被用于创建NSURLSession类的对象. */          NSURLSessionConfiguration *configura = [NSURLSessionConfiguration defaultSessionConfiguration];    /**     * 2. 创建NSURLSession的对象.     * 参数一 : NSURLSessionConfiguration类的对象.(第1步创建的对象.)     * 参数二 : session的代理人. 如果为nil, 系统将会提供一个代理人.     * 参数三 : 一个队列, 代理方法在这个队列中执行. 如果为nil, 系统会自动创建一系列的队列.     * 注: 只能通过这个方法给session设置代理人, 因为在NSURLSession中delegate属性是只读的.     */    NSURLSession *session = [NSURLSession sessionWithConfiguration:configura delegate:self delegateQueue:nil];    /** 3. 创建URL. */    NSURL *url = [NSURL URLWithString:@"http://c.3g.163.com/photo/api/list/0096/4GJ60096.json"];    /** 4. 创建request. */    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    /** request请求方式为: GET. 如果是POST, 还需要设置HTTPBody属性. */    /** 5. 创建数据类型的任务. */    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];    /** 6. 开始任务. */    [dataTask resume];    /** 7. 在session中的所有任务都完成之后, 使session失效. */   [session finishTasksAndInvalidate];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

注 : 使用- dataTaskWithURL:方法创建data task, 去掉步骤3中的4. 将5替换成下面的代码. 此方法有局限性, 只能用于GET请求方式.

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];
  • 1
  • 2
  • 1
  • 2

步骤4 : 实现代理方法

  1. 接收到返回信息时(还未开始下载), 执行的代理方法.
/**  * NSURLSessionDataDelegate方法实现.  * completionHandler block块内的参数 disposition 是一个枚举值: *  * typedef NS_ENUM (NSInteger,NSURLSessionResponseDisposition ) {   NSURLSessionResponseCancel = 0, /**-> 取消任务. */   NSURLSessionResponseAllow = 1,  /**-> 任务正常进行. */    NSURLSessionResponseBecomeDownload = 2 /**-> 从data task 转换成 download task, 并调用  - URLSession:dataTask:didReceiveResponse:completionHandler: 代理方法. */};  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{    /** a. 初始化allData属性(步骤1中设置的属性). */    self.allData = [NSMutableData data];    /** b. 让任务继续正常进行.(如果没有写这行代码, 将不会执行下面的代理方法.) */    completionHandler(NSURLSessionResponseAllow);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2 . 接收返回的数据

/** NSURLSessionDataDelegate方法实现. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{    /** 接收返回的数据. */    [self.allData appendData:data];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3 . 任务完成之后调用

/**  * NSURLSessionTaskDelegate方法实现. * 任务完成加载数据之后调用的代理方法. */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{    /** 处理数据. */    NSError *er = nil;    id result = [NSJSONSerialization JSONObjectWithData:self.allData options:NSJSONReadingMutableContainers error:&er];    NSLog(@"result: %@", result);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

二. data任务转成download任务, 完成下载.

1 . 当转换成download task时, 会下载资源数据到磁盘文件上, 我们不需要自己接收数据了.

2 . 我们还需要签订NSURLSessionDownloadDelegate.

3 . 改变步骤4.

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{    /** 把data task 转换成 download task. */  completionHandler(NSURLSessionResponseBecomeDownload);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 注: 当data task 转换成 download task 时, 我们必须调用NSURLSessionDataDelegate中的 
    -URLSession:dataTask:didBecomeDownloadTask: 方法. 
    步骤4中的 2 变成如下代码
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask{    /** 此方法内可以不写任何代码, 但必须被调用. 否则将不会执行下面的代理方法. */}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 注: 因为已经转换成download task, 所以接下来将调用NSURLSessionDownloadDelegate的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{            /** 从提供的URL中读取数据. */        NSData *data = [NSData dataWithContentsOfURL:location];        /** 处理数据. */        NSError *er = nil;        id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&er];        NSLog(@"result: %@", result);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

三. 取消data任务下载.

步骤4 :

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{     /** 取消data task 的下载. 之后将不会执行任何的代理方法了. */    completionHandler(NSURLSessionResponseCancel);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

    • iOS_NSURLSessionDataDelegate
      • 核心API
      • 功能实现
        • 思路 
        • Code 
          • 一 正常实现data任务的下载
          • 二 data任务转成download任务 完成下载
          • 三 取消data任务下载
    • API 官方注释

API 官方注释

  • NSURLSession
/**  * @brief  Creates a session with the specified session configuration, delegate, and operation queue. * * @param  <configuration>  A configuration object that specifies certain behaviors,                             such as caching policies, timeouts, proxies, pipelining, TLS versions to support, cookie policies, and credential storage. *  * @param  <delegate>   A session delegate object that handles requests for authentication and other session-related events.                        This delegate object is responsible for handling authentication challenges, for making caching decisions, and for handling other session-related events.                         If nil, the class uses a system-provided delegate and should be used only with methods that take completion handlers. * * @param  <queue>  A queue for scheduling the delegate calls and completion handlers.                     If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls. *  */+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
/**  * @brief  Creates an HTTP GET request for the specified URL. * * @param  <url>     The http or https URL to be retrieved. *  * @return   The new session data task. */- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
/**  * @brief  Creates an HTTP request based on the specified URL request object. * * @param  <request>     An object that provides request-specific information such as the URL, cache policy, request type, and body data or body stream. *  * @return   The new session data task. */- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDataDelegate
/**  * @brief  Tells the delegate that the data task received the initial reply (headers) from the server. * * @param  <session>  The session containing the data task that received an initial reply. * @param  <dataTask>  The data task that received an initial reply.      * @param  <response>  A URL response object populated with headers. * @param  <completionHandler> A completion handler that your code calls to continue the transfer, passing a constant to indicate whether the transfer should continue as a data task or should become a download task.If you pass NSURLSessionResponseAllow, the task continues normally.If you pass NSURLSessionResponseCancel, the task is canceled.If you pass NSURLSessionResponseBecomeDownload as the disposition, your delegate’s URLSession:dataTask:didBecomeDownloadTask: method is called to provide you with the new download task that supersedes the current task. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
/**  * @brief  Tells the delegate that the data task has received some of the expected data. * * @param  <session>  The session containing the data task that provided data. * @param  <dataTask>  The data task that provided data. * @param  <data>  A data object containing the transferred data.  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
/**  * @brief  Tells the delegate that the data task was changed to a download task. * * @param  <session>  The session containing the task that was replaced by a download task. * @param  <dataTask>  The data task that was replaced by a download task. * @param  <data>  The new download task that replaced the data task.  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionTaskDelegate
/**  * @brief  Tells the delegate that the task finished transferring data. * * @param  <session>  The session containing the task whose request finished transferring data. * @param  <task>  The task whose request finished transferring data. * @param  <error>  If an error occurred, an error object indicating how the transfer failed, otherwise NULL.  */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDownloadDelegate
/**  * @brief  Tells the delegate that a download task has finished downloading. (required) * * @param  <session>  The session containing the download task that finished. * @param  <downloadTask>  The download task that finished. * @param  <location>  A file URL for the temporary file. Because the file is temporary, you must either open the file for reading or move it to a permanent location in your app’s sandbox container directory before returning from this delegate method.If you choose to open the file for reading, you should do the actual reading in another thread to avoid blocking the delegate queue.  */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

目录(?)[+]

  • 说明:

    • 本文将介绍NSURLSessionDataDelegate, 使用NSURLSessionDataDelegate方法实现下载数据. 博文底部会对文中所使用的方法有详细的介绍, 如果感兴趣可以仔细阅读.

    • session 类型 : default session.

    • session的创建方法: + sessionWithConfiguration:delegate:delegateQueue:

    • task 类型: data task. 

    • 代码中所使用到的接口(例: http://c.3g.163.com/photo/api/list/0096/4GJ60096.json) 都具有时效性, 建议测试时使用一个可以提供数据的新接口.

  • 文章中尽量不使用或少使用封装, 目的是让大家清楚为了实现功能所需要的官方核心API是哪些(如果使用封装, 会在封装外面加以注释)

  • 此文章由 @春雨 编写. 经 @Scott,@黑子 审核. 若转载此文章,请注明出处和作者

iOS_NSURLSessionDataDelegate

核心API

Class :

  • NSURLSession
  • NSURLSessionConfiguration
  • NSURLSessionTask 
    • NSURLSessionDataTask
    • NSURLSessionDownload

Delegate :

  • NSURLSessionDelegate
  • NSURLSessionTaskDelegate
  • NSURLSessionDataDelegate
  • NSURLSessionDownloadDelegate

涉及的API :

  • NSURLSession
/** 创建NSURLSession对象的类方法. */+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue/** 通过URL, 返回一个数据任务. */- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url/** 通过request请求, 返回一个数据任务. */- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDataDelegate
/**  告诉delegate已经接受到服务器的初始应答, 准备接下来的数据任务的操作. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler/** 告诉delegate已经接收到部分数据. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data/** 告诉delegate, data task 已经转变成download task. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • NSURLSessionTaskDelegate
/** 告诉delegate, task已经完成. */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
  • 1
  • 2
  • 1
  • 2
  • NSURLSessionDownloadDelegate
/** 告诉delegate, download task已经完成. */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
  • 1
  • 2
  • 1
  • 2

功能实现

思路 :

  1. 正常实现data任务的下载.
  2. data任务转成download任务, 完成下载.
  3. 取消data任务下载.

Code :

一. 正常实现data任务的下载.

步骤1 : 

/** 签订代理. */@interface ViewController ()<NSURLSessionDelegate,  NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>/** 设置一个NSMutableData类型的对象, 用于接收返回的数据. */@property (nonatomic, retain) NSMutableData *allData;@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

步骤3 : 创建会话和任务

- (void)handleData /*-> 自己定义的一个方法. */{     /** 1. 创建NSURLSessionConfiguration类的对象, 这个对象被用于创建NSURLSession类的对象. */          NSURLSessionConfiguration *configura = [NSURLSessionConfiguration defaultSessionConfiguration];    /**     * 2. 创建NSURLSession的对象.     * 参数一 : NSURLSessionConfiguration类的对象.(第1步创建的对象.)     * 参数二 : session的代理人. 如果为nil, 系统将会提供一个代理人.     * 参数三 : 一个队列, 代理方法在这个队列中执行. 如果为nil, 系统会自动创建一系列的队列.     * 注: 只能通过这个方法给session设置代理人, 因为在NSURLSession中delegate属性是只读的.     */    NSURLSession *session = [NSURLSession sessionWithConfiguration:configura delegate:self delegateQueue:nil];    /** 3. 创建URL. */    NSURL *url = [NSURL URLWithString:@"http://c.3g.163.com/photo/api/list/0096/4GJ60096.json"];    /** 4. 创建request. */    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    /** request请求方式为: GET. 如果是POST, 还需要设置HTTPBody属性. */    /** 5. 创建数据类型的任务. */    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];    /** 6. 开始任务. */    [dataTask resume];    /** 7. 在session中的所有任务都完成之后, 使session失效. */   [session finishTasksAndInvalidate];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

注 : 使用- dataTaskWithURL:方法创建data task, 去掉步骤3中的4. 将5替换成下面的代码. 此方法有局限性, 只能用于GET请求方式.

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];
  • 1
  • 2
  • 1
  • 2

步骤4 : 实现代理方法

  1. 接收到返回信息时(还未开始下载), 执行的代理方法.
/**  * NSURLSessionDataDelegate方法实现.  * completionHandler block块内的参数 disposition 是一个枚举值: *  * typedef NS_ENUM (NSInteger,NSURLSessionResponseDisposition ) {   NSURLSessionResponseCancel = 0, /**-> 取消任务. */   NSURLSessionResponseAllow = 1,  /**-> 任务正常进行. */    NSURLSessionResponseBecomeDownload = 2 /**-> 从data task 转换成 download task, 并调用  - URLSession:dataTask:didReceiveResponse:completionHandler: 代理方法. */};  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{    /** a. 初始化allData属性(步骤1中设置的属性). */    self.allData = [NSMutableData data];    /** b. 让任务继续正常进行.(如果没有写这行代码, 将不会执行下面的代理方法.) */    completionHandler(NSURLSessionResponseAllow);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2 . 接收返回的数据

/** NSURLSessionDataDelegate方法实现. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{    /** 接收返回的数据. */    [self.allData appendData:data];}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3 . 任务完成之后调用

/**  * NSURLSessionTaskDelegate方法实现. * 任务完成加载数据之后调用的代理方法. */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{    /** 处理数据. */    NSError *er = nil;    id result = [NSJSONSerialization JSONObjectWithData:self.allData options:NSJSONReadingMutableContainers error:&er];    NSLog(@"result: %@", result);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

二. data任务转成download任务, 完成下载.

1 . 当转换成download task时, 会下载资源数据到磁盘文件上, 我们不需要自己接收数据了.

2 . 我们还需要签订NSURLSessionDownloadDelegate.

3 . 改变步骤4.

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{    /** 把data task 转换成 download task. */  completionHandler(NSURLSessionResponseBecomeDownload);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 注: 当data task 转换成 download task 时, 我们必须调用NSURLSessionDataDelegate中的 
    -URLSession:dataTask:didBecomeDownloadTask: 方法. 
    步骤4中的 2 变成如下代码
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask{    /** 此方法内可以不写任何代码, 但必须被调用. 否则将不会执行下面的代理方法. */}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 注: 因为已经转换成download task, 所以接下来将调用NSURLSessionDownloadDelegate的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{            /** 从提供的URL中读取数据. */        NSData *data = [NSData dataWithContentsOfURL:location];        /** 处理数据. */        NSError *er = nil;        id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&er];        NSLog(@"result: %@", result);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

三. 取消data任务下载.

步骤4 :

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{     /** 取消data task 的下载. 之后将不会执行任何的代理方法了. */    completionHandler(NSURLSessionResponseCancel);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

    • iOS_NSURLSessionDataDelegate
      • 核心API
      • 功能实现
        • 思路 
        • Code 
          • 一 正常实现data任务的下载
          • 二 data任务转成download任务 完成下载
          • 三 取消data任务下载
    • API 官方注释

API 官方注释

  • NSURLSession
/**  * @brief  Creates a session with the specified session configuration, delegate, and operation queue. * * @param  <configuration>  A configuration object that specifies certain behaviors,                             such as caching policies, timeouts, proxies, pipelining, TLS versions to support, cookie policies, and credential storage. *  * @param  <delegate>   A session delegate object that handles requests for authentication and other session-related events.                        This delegate object is responsible for handling authentication challenges, for making caching decisions, and for handling other session-related events.                         If nil, the class uses a system-provided delegate and should be used only with methods that take completion handlers. * * @param  <queue>  A queue for scheduling the delegate calls and completion handlers.                     If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls. *  */+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
/**  * @brief  Creates an HTTP GET request for the specified URL. * * @param  <url>     The http or https URL to be retrieved. *  * @return   The new session data task. */- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
/**  * @brief  Creates an HTTP request based on the specified URL request object. * * @param  <request>     An object that provides request-specific information such as the URL, cache policy, request type, and body data or body stream. *  * @return   The new session data task. */- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDataDelegate
/**  * @brief  Tells the delegate that the data task received the initial reply (headers) from the server. * * @param  <session>  The session containing the data task that received an initial reply. * @param  <dataTask>  The data task that received an initial reply.      * @param  <response>  A URL response object populated with headers. * @param  <completionHandler> A completion handler that your code calls to continue the transfer, passing a constant to indicate whether the transfer should continue as a data task or should become a download task.If you pass NSURLSessionResponseAllow, the task continues normally.If you pass NSURLSessionResponseCancel, the task is canceled.If you pass NSURLSessionResponseBecomeDownload as the disposition, your delegate’s URLSession:dataTask:didBecomeDownloadTask: method is called to provide you with the new download task that supersedes the current task. */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
/**  * @brief  Tells the delegate that the data task has received some of the expected data. * * @param  <session>  The session containing the data task that provided data. * @param  <dataTask>  The data task that provided data. * @param  <data>  A data object containing the transferred data.  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
/**  * @brief  Tells the delegate that the data task was changed to a download task. * * @param  <session>  The session containing the task that was replaced by a download task. * @param  <dataTask>  The data task that was replaced by a download task. * @param  <data>  The new download task that replaced the data task.  */- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionTaskDelegate
/**  * @brief  Tells the delegate that the task finished transferring data. * * @param  <session>  The session containing the task whose request finished transferring data. * @param  <task>  The task whose request finished transferring data. * @param  <error>  If an error occurred, an error object indicating how the transfer failed, otherwise NULL.  */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • NSURLSessionDownloadDelegate
/**  * @brief  Tells the delegate that a download task has finished downloading. (required) * * @param  <session>  The session containing the download task that finished. * @param  <downloadTask>  The download task that finished. * @param  <location>  A file URL for the temporary file. Because the file is temporary, you must either open the file for reading or move it to a permanent location in your app’s sandbox container directory before returning from this delegate method.If you choose to open the file for reading, you should do the actual reading in another thread to avoid blocking the delegate queue.  */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
0 0
原创粉丝点击