说明:
- 本文将介绍使用NSURLSessionDownloadDelegate的代理方法实现显示加载进度和断点续传(网络中断情况, 不是退出程序情况. 只要不是退出程序的情况下, 下载失败都可以用本文的方法实现断点续传).
实现功能的方法并不唯一, 大家要灵活使用.
session 类型 : default session.
session的创建方法: + sessionWithConfiguration:delegate:delegateQueue:
task 类型: download task.
代码中所使用到的接口(例:
http://2b2726fb22467.cdn.sohucs.com/55fbb97f13aa9.mp4
) 都具有时效性, 建议测试时使用一个可以提供数据的新接口.请确保Xcode版本在6.4以上.
文章中尽量不使用或少使用封装, 目的是让大家清楚为了实现功能所需要的官方核心API是哪些(如果使用封装, 会在封装外面加以注释)
此文章由 @春雨 编写. 经 @Scott,@黑子 审核. 若转载此文章,请注明出处和作者
iOS_断点续传
核心API
Class :
- NSURLSession
- NSURLSessionConfiguration
- NSURLSessionTask
- NSURLSessionDownload
Delegate :
- NSURLSessionDelegate
- NSURLSessionTaskDelegate
- NSURLSessionDownloadDelegate
涉及的API :
- NSURLSession
/** 创建NSURLSession对象的类方法. */
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue
/** 创建一个download任务, 用于恢复之前取消或者失败的download任务. */
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
/** 创建一个download任务, 用于恢复之前取消或者失败的download任务. 并回调Block块. */
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler
/** 创建一个download任务, 用于恢复之前取消或者失败的download任务. 并带有一个处理任务完成的block块. */
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler
- NSURLSessionDownloadTask
/** 取消download任务, 并回调一个带续传数据的Block块. */
- (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
- NSURLSessionTask
/** 取消任务. */
- (void)cancel
- NSURLSessionDownloadDelegate
/** 告诉delegate, download task已经完成. */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
/** 定期通知代理人下载进度. */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
/** 告诉代理人下载任务已经恢复. */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
- NSURLSessionTaskDelegate
/** 告诉delegate, task已经完成. */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
- NSURLSessionDownloadTask
/** 取消下载并调用回调与恢复数据供以后使用. */
- (void)cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
功能实现
思路 :
- 1 . 下载过程中显示加载进度.
- 2 . 断点续传(网络中断)
注: 判断网络状态.(用于测试) - 4 . 取消下载.
- 5 . 其他方法.
Code :
1. 加载进度 和 2. 断点续传(网络中断)
注: 网络判断部分请查看iOS_AFNetworking_AFNetworkReachabilityManager(检测网络可达性)
#import "ViewController.h"
#import "AFNetworkReachabilityManager.h"
@interface ViewController ()<NSURLSessionDelegate, NSURLSessionDownloadDelegate, NSURLSessionTaskDelegate>
@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask; // 下载任务
@property (nonatomic, strong) NSURLSession *session; // 会话
@property (nonatomic, strong) NSData *resumData; // 续传数据
@property (nonatomic, strong) NSDate *lastDate; // 上次获取到数据的时间.
/** 两个label都是用Storybord创建的. */
@property (weak, nonatomic) IBOutlet UILabel *progressLabel;
@property (weak, nonatomic) IBOutlet UILabel *speedLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self networkState];