在这里需要两对文件
1.在第一个.h文件内写两个Block参数和一个代理协议
第一个参数:正在下载
typedef void (^Downloading)(long long bytesWritten,float progress);
第二个参数:下载完成
typedef void (^Complete)(NSString *filePath,NSString *url);
自写代理协议及方法
@protocol DownloadDelegate<NSObject>
- (void)didFinishDownload:(NSString *)url
@end
@interface Download :NSObject
设置你声明的代理属性
@property (nonatomic,weak)id<DownloadDelegate>delegate;
自定义init方法,在初始化的时候就去创建一个下载任务
- (instancetype)initWithUrl:(NSString *)url;
开始下载
- (void)startDownload;
暂停下载
- (void)stopDownload;
下载的时候和下载完成会走其中的Block
- (void)downloading:(Downloading)downloading didFinished:(Complete)Complete;
@end
2.在第一个.m文件内实现这些方法
在这里会使用NSURLSession下的一些方法
#import "Download.h"
遵守一个代理
@interface Download ()<NSURLSessionDownloadDelegate>
声明属性
@property (nonatomic,strong) NSURLSession *session;
下载任务
@property (nonatomic,strong) NSURLSessionDownloadTask *task;
正在下载
@property (nonatomic, copy)Downloading downloading;
下载完成
@property (nonatomic,strong) Complete complete;
@end
@implementation Download
写个懒加载
- (NSURLSession *)session{
if (!_session){
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]delegate:self delegateQueue:nil];
}
return _session;
}
自定义init方法,在初始化的时候就去创建一个下载任务
- (instancetype)initWithUrl:(NSString *)url{
if ([super init]) {
// 创建一个下载任务
self.task = [self.session downloadTaskWithURL:[NSURL URLWithString:url]];
}
return self;
}
开始下载
- (void)startDownload{
[self.task resume];
}
暂停下载
- (void)stopDownload{
[self.task suspend];
}
正在下载
这是NSURLSession自带的一个方法,里面的参数downloadTask:下载任务,didWriteData:写入数据,totalBytesWritten:已经写入总的数据,totalBytesExpectedToWrite:预计写的总数据
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
if (self.downloading){
self.downloading(bytesWritten,100*totalBytesWritten/(float)totalBytesExpectedToWrite);
}
}
下载完成
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
// 我们要存放下载文件的路径
NSString *filePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
// 拼接文件的名字,名字是从服务器上获取下来的
NSString *fileName = downloadTask.response.suggestedFilename;
filePath = [filePath stringByAppendingPathComponent:fileName];
// 文件管理器,把临时的文件移动到缓存文件夹下
[[NSFileManager defaultManager] moveItemAtPath:location.path toPath:filePath error:nil];
NSLog(@"%@",filePath);
if (self.complete) {
self.complete(filePath,@"网址");
}
}
下载的时候和下载完成会走其中的Block
- (void)downloading:(Downloading)downloading didFinished:(Complete)Complete {
self.downloading = downloading;
self.complete = Complete;
}
第二个文件的.h内
#import<Foundation/Foundation.h>
@interface DownloadCoreData : NSObject
+ (instancetype)sharedManager;
- (Download *)addDownloadWithUrl:(NSString *)url;
- (Download *)findDownloadWithUrl:(NSString *)url;
- (void)didFinishDownload:(NSString *)url;
@end
第二个文件的.m内
#import "DownloadCoreData.h"
遵守上个文件写的代理
@interface DownloadCoreData ()<DownloadDelegate>
声明一个字典属性
@property (nonatomic,strong)NSMutableDictionary *dic;
@end
@implementation DownloadCoreData
懒加载
- (NSMutableDictionary *)dic{
if (!_dic) {
_dic = [NSMutableDictionary dictionary];
}
return _dic;
}
GCD单例
+ (instancetype)sharedManager {
static DownloadCoreData *handle = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
handle = [[DownloadCoreData alloc]init];
});
return handle;
}
- (Download *)addDownloadWithUrl:(NSString *)url {
Download *download = [[Download alloc]initWithUrl:url];
download.delegate = self;
[download startDownload];
[self.dic setObject:download forKey:url];
return download;
}
- (Download *)findDownloadWithUrl:(NSString *)url {
return self.dic[url];
}
- (void)didFinishDownload:(NSString *)url {
[self.dic removeObjectForKey:url];
}
@end