iOS开发 大文件下载封装

时间:2021-12-09 20:58:35

iOS开发 文件下载

功能:实现文件的断点下载,即暂停,开始

完整源码:   http://download.csdn.net/detail/u010029229/9164147

下载封装类:MyFileDownloader.h MyFileDownloader.m

//
// MyFileDownloader.h
// 大文件下载封装
//
// Created by Qianfeng on 15/10/8.
// Copyright (c) 2015年 xyz. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface MyFileDownloader : NSObject

// 下载文件URL
@property (nonatomic, copy) NSString *url;

// 文件存储路径
@property (nonatomic, copy) NSString *destPath;

// 是否正在下载
@property (nonatomic, readonly, getter=isDownloading) BOOL downloading;

// 用来监听下载进度
@property (nonatomic, copy) void(^progressHandler)(double progress);

// 监听下载完毕
@property (nonatomic, copy) void (^completionHandler)();

// 监听下载失败
@property (nonatomic, copy) void (^failureHandle)(NSError *error);

// 开始下载
- (void)startDownload;

// 暂停下载
- (void)pauseDownload;

@end

//
// MyFileDownloader.m
// 大文件下载封装
//
// Created by Qianfeng on 15/10/8.
// Copyright (c) 2015年 xyz. All rights reserved.
//

#import "MyFileDownloader.h"

@interface MyFileDownloader()<NSURLConnectionDataDelegate>
@property (nonatomic, strong) NSURLConnection *conn; // 链接对象
@property (nonatomic, strong) NSFileHandle *writeHandle; // 写文件句柄
@property (nonatomic, assign) long long currentLength; // 当前文件总长度
@property (nonatomic, assign) long long totalLength; // 文件总长度
@end


@implementation MyFileDownloader

- (void)startDownload {
NSURL *url = [NSURL URLWithString:self.url];
// 默认就是GET请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求头信息
NSString *value = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength];
[request setValue:value forHTTPHeaderField:@"Range"];
self.conn = [NSURLConnection connectionWithRequest:request delegate:self];

_downloading = YES;
}

- (void)pauseDownload {
[self.conn cancel];
self.conn = nil;

_downloading = NO;
}

#pragma mark - NSURLConnectionDataDelegate 代理方法
/**
* 1. 当接受到服务器的响应(连通了服务器)就会调用
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (self.totalLength) return;

// 1.创建一个空的文件到沙盒中
NSFileManager *mgr = [NSFileManager defaultManager];
// 刚创建完毕的大小是0字节
[mgr createFileAtPath:self.destPath contents:nil attributes:nil];

// 2.创建写数据的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.destPath];

// 3.获得完整文件的长度
self.totalLength = response.expectedContentLength;
}

/**
* 2. 当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 累加长度
self.currentLength += data.length;

// 显示进度
double progress = (double)self.currentLength / self.totalLength;
if (self.progressHandler) { // 传递进度值给block
self.progressHandler(progress);
}

// 移动到文件的尾部
[self.writeHandle seekToEndOfFile];
// 从当前移动的位置(文件尾部)开始写入数据
[self.writeHandle writeData:data];
}

/**
* 3. 当服务器的数据接受完毕后就会调用
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 清空属性值
self.currentLength = 0;
self.totalLength = 0;

if (self.currentLength == self.totalLength) {
// 关闭连接(不再输入数据到文件中)
[self.writeHandle closeFile];
self.writeHandle = nil;
}

if (self.completionHandler) {
self.completionHandler();
}
}

/**
* 请求错误(失败)的时候调用(请求超时\断网\没有网, 一般指客户端错误)
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (self.failureHandle) {
self.failureHandle(error);
}
}


@end

控制器源码

//
// ViewController.h
// 大文件下载封装
//
// Created by Qianfeng on 15/10/8.
// Copyright (c) 2015年 xyz. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end


//
// ViewController.m
// 大文件下载封装
//
// Created by Qianfeng on 15/10/8.
// Copyright (c) 2015年 xyz. All rights reserved.
//

#import "ViewController.h"
#import "MyFileDownloader.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic, strong) MyFileDownloader *fileDownloader;
- (IBAction)startDownloader:(id)sender;
@property (weak, nonatomic) IBOutlet UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
self.progressView.progress = 0;
}

- (MyFileDownloader *)fileDownloader
{
if (!_fileDownloader) {
_fileDownloader = [[MyFileDownloader alloc] init];

NSString *url = @"http://10.0.8.8/download/MapKit-LBS项目-FindMe.pdf";


// 需要下载的文件远程URL
_fileDownloader.url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 文件保存到什么地方
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"abc.pdf"];
_fileDownloader.destPath = filepath;
// typeof(10) a = 20; // int a = 20;

__weak typeof(self) vc = self;
_fileDownloader.progressHandler = ^(double progress) {
vc.progressView.progress = progress;
};

_fileDownloader.completionHandler = ^{
NSLog(@"------下载完毕");
};

_fileDownloader.failureHandle = ^(NSError *error){

};
}
return _fileDownloader;
}
- (IBAction)startDownloader:(id)sender {
if (self.fileDownloader.isDownloading) { // 暂停下载
[self.fileDownloader pauseDownload];

[self.button setTitle:@"恢复" forState:UIControlStateNormal];
} else { // 开始下载
[self.fileDownloader startDownload];

[self.button setTitle:@"暂停" forState:UIControlStateNormal];
}
}
@end
在控制器的那两个控件就自己看着办吧。。。