iOS开发 -------- AFNetworking实现简单的断点下载
一 实现如下效果
二 实现代码
//
// ViewController.m
// AFNetworking实现断点下载
//
// Created by lovestarfish on 15/11/15.
// Copyright © 2015年 S&G. All rights reserved.
//
#define kURL @"http://v.hoto.cn/cc/45/869836.mp4?v=4"
#import "ViewController.h"
#import "AFNetworking.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *progressLabel;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic,strong) AFHTTPRequestOperation *operation; - (IBAction)start:(UIButton *)sender; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // 获取保存下载进度的缓存文件
NSString *txtTempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mvTemp/mv.txt"];
NSLog(@"%@",txtTempPath);
NSFileManager *fileManager = [NSFileManager defaultManager]; // 判断文件夹里面有没有之前的缓存文件
if ([fileManager fileExistsAtPath:txtTempPath]) {
// 有的话继续之前的下载进度下载
self.progressView.progress = [[NSString stringWithContentsOfFile:txtTempPath encoding:NSUTF8StringEncoding error:nil] floatValue];
} else {
// 没有的话进度从0开始
self.progressView.progress = ;
} // 设置显示进度的label内容
self.progressLabel.text = [NSString stringWithFormat:@"%.2f%%",self.progressView.progress * ]; NSLog(@"%@",NSHomeDirectory());
} /**
* 开始下载(下载的时候判断是否已经下载过该文件)
*/
- (IBAction)start:(UIButton *)sender {
// 创建文件管理对象
NSFileManager *fileManager = [NSFileManager defaultManager];
// 视频文件
NSString *mp4Path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/mv/mv.mp4"];
// 视频文件夹
NSString *mvPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/mv"];
//缓存文件夹
NSString *mvTempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mvTemp"]; // 如果存在mp4Path路径则说明已经下载该文件,此时提示用户是否需要重新下载
if ([fileManager fileExistsAtPath:mp4Path]) {// 存在该文件
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"提示" message:@"文件已经存在,是否重新下载" preferredStyle:UIAlertControllerStyleAlert];
// 确定行为
UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"点击了确定");
// 重新下载,需要移除之前的视频文件夹和缓存文件夹
[fileManager removeItemAtPath:mvPath error:nil];//视频文件夹
[fileManager removeItemAtPath:mvTempPath error:nil];//缓存文件夹
[self download:sender];
}]; // 取消行为
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// 点击取消,直接return
NSLog(@"点击了取消");
return ;
}]; // 添加行为到控制器alertC
[alertC addAction:doneAction];
[alertC addAction:cancelAction]; // 模态弹出提示框
[self presentViewController:alertC animated:YES completion:nil];
} else { // 不存在,直接下载
[self download:sender];
}
} /**
* 下载操作
*/
- (void)download:(UIButton *)sender {
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([sender.currentTitle isEqualToString:@"开始下载"]) {
// 如果已经开始下载,将按钮标题置为"暂停下载"
[sender setTitle:@"暂停下载" forState:UIControlStateNormal]; // 下载的url
NSURL *url = [NSURL URLWithString:kURL];
// 获取cache文件夹
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; // 在cache文件夹创建mv文件夹,用来存放下载成功地资料
NSString *folderPath = [cachePath stringByAppendingPathComponent:@"mv"];
// 在缓存文件夹里创建mvTemp文件夹用来临时存放下载信息
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mvTemp"];
// 判断缓存文件夹和视频存放文件夹是否存在,如果不存在,就创建一个文件夹
if (![fileManager fileExistsAtPath:folderPath]) {// 如果不存在视频文件夹
[fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
if (![fileManager fileExistsAtPath:tempPath]) { // 如果不存在缓存文件夹
[fileManager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:nil];
} // 缓存路径(缓存当前下载的容量值)
NSString *tempFilePath = [tempPath stringByAppendingPathComponent:@"mv.temp"]; // 保存重启程序下载的进度(保存当前下载的进度值)
NSString *txtFilePath = [tempPath stringByAppendingPathComponent:@"mv.txt"]; // 文件保存路径
NSString *mvFilePath = [folderPath stringByAppendingPathComponent:@"mv.mp4"]; // 初始化下载字节数为0
unsigned long long downloadedBytes = ;
// 创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
if ([fileManager fileExistsAtPath:tempFilePath]) {//如果存在,说明有缓存文件
// 计算缓存文件的大小
downloadedBytes = [self fileSizeAtPath:tempFilePath];
NSLog(@"%llu",downloadedBytes);
// 创建可变请求
NSMutableURLRequest *mutableRequest = [request mutableCopy];
NSString *requestRange = [NSString stringWithFormat:@"bytes=%llu-",downloadedBytes]; [mutableRequest setValue:requestRange forHTTPHeaderField:@"Range"];
request = mutableRequest;
NSLog(@"==============断点下载");
} if (![fileManager fileExistsAtPath:mvFilePath]) {
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];
self.operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[self.operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:tempFilePath append:YES]]; // 设置下载进度的block
__block ViewController *vc = self;
[self.operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
// 更新进度
vc.progressView.progress = ((float)totalBytesRead + downloadedBytes)/ (totalBytesExpectedToRead + downloadedBytes);
vc.progressLabel.text = [NSString stringWithFormat:@"%.2f%%",self.progressView.progress * ];
// 将进度写入缓存文件
NSString *progress = [NSString stringWithFormat:@"%.3f",((float)totalBytesRead + downloadedBytes) / ( totalBytesExpectedToRead + downloadedBytes)];
[progress writeToFile:txtFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
}]; // 下载完成时调用
[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
//把下载完成的文件转移到保存的路径
[fileManager moveItemAtPath:tempFilePath toPath:mvFilePath error:nil];
//删除保存进度的txt文档
[fileManager removeItemAtPath:txtFilePath error:nil];
[sender setTitle:@"下载完成" forState:UIControlStateNormal];
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) { }]; // 开始操作
[self.operation start];
}
} else {
[sender setTitle:@"开始下载" forState:UIControlStateNormal];
[self.operation cancel];
self.operation = nil;
} } /**
* 计算缓存文件的大小
*
* @param fileAbsolutePath 文件的绝对路径
*
* @return 文件的大小
*/
- (unsigned long long)fileSizeAtPath:(NSString *)fileAbsolutePath {
signed long long fileSize = ;
NSFileManager *fileManager = [NSFileManager new];
if ([fileManager fileExistsAtPath:fileAbsolutePath]) {
NSError *error = nil;
NSDictionary *fileDict = [fileManager attributesOfItemAtPath:fileAbsolutePath error:&error];
if (!error && fileDict) {
fileSize = [fileDict fileSize];
}
}
return fileSize;
} @end
iOS开发 -------- AFNetworking实现简单的断点下载的更多相关文章
- iOS开发网络篇—简单介绍ASI框架的使用
iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...
- iOS开发之常用第三方框架(下载地址,使用方法,总结)
iOS开发之常用第三方框架(下载地址,使用方法,总结) 说句实话,自学了这么久iOS,如果说我不知道的但是又基本上都摸遍了iOS相关知识,但是每次做项目的时候,遇到难一点的地方或者没试过的东西就闷了. ...
- iOS开发UI篇—简单的浏览器查看程序
iOS开发UI篇—简单的浏览器查看程序 一.程序实现要求 1.要求 2. 界面分析 (1) 需要读取或修改属性的控件需要设置属性 序号标签 图片 图片描述 左边按钮 右边按钮 (2) 需要监听响应事件 ...
- iOS开发UI篇—简单介绍静态单元格的使用
iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...
- iOS开发Swift篇—简单介绍
iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...
- 李洪强iOS开发之- 实现简单的弹窗
李洪强iOS开发之- 实现简单的弹窗 实现的效果: 112222222222223333333333333333
- IOS开发苹果官方Sample Code及下载地址
IOS开发苹果官方Sample Code及下载地址 在线浏览地址:https://developer.apple.com/library/ios/navigation/#section=Resourc ...
- iOS开发笔记,简单实现视频音频的边下边播
总是在网上看别人的博文,受益匪浅,从没自己写过,今天分享一点小经验,第一次写技术博客,希望对同行的ios猿们有所帮助. 先介绍一下自己的情况:一年ios开发,http协议不太懂,大约知道断点下载h ...
- ios网络 -- HTTP请求 and 文件下载/断点下载
一:请求 http://www.jianshu.com/p/8a90aa6bad6b 二:下载 iOS网络--『文件下载.断点下载』的实现(一):NSURLConnection http://www. ...
随机推荐
- 松散的css
<style> <p>hello world</p> {} p { color: red; } {} <em style="padding: 4px ...
- 3 Oracle 32位客户端安装及arcgis连接
关于Oracle服务器端安装及配置的过程详见第2篇文章,链接如下:http://www.cnblogs.com/gistrd/p/8494292.html,本篇介绍客户端安装配置及连接arcgis过程 ...
- js中级小知识2
1.面向对象 js一开始就是写网页特效,面向过程的,作者发现这样写不好,代码重复利用率太高,计算机内存消耗太大,网页性能很差.所以作者就收到java和c的影响,往面向对象靠齐.js天生有一个Objec ...
- 线段树合并 || BZOJ 5457: 城市
题面:https://www.lydsy.com/JudgeOnline/problem.php?id=5457 题解: 线段树合并,对于每个节点维护sum(以该节点为根的子树中最大的种类和)和kin ...
- 多对多关联模型,MANY_TOMANY
先分别创建三张表:think_user think_group think_user_group user 表里有id.name字段 group 表里有id.groupName字段 user_ ...
- 17.4-uC/OS-III消息管理(任务消息队列使用)
任务消息队列跟任务信号量一样,均隶属于某一个特定任务, 不需单独创建,任务在则在, 只有该任务才可以接收这个任务消息队列的消息,其他任务只能给这个任务消息队列发送消息, 却不能接收.任务消息队列与(普 ...
- 《linux就该这么学》第十节课:第8章iptables和firewalld
网卡配置: 物理机:192.168.10.1/24 服务器:192.168.10.10/24 客户端:192.168.10.20/24 1.vim /etc/sysc ...
- Unity性能优化之特效合并
特效合并,意思是说将粒子所用的零碎图片,以shader为单位合并成一张图集,好处就是可以降低draw call.试想,合并前每个粒子使用一个material,而每一个material就要占用一个dra ...
- CentOS 7 配置Tomcat9连接MySQL
配置Tomcat 首先安装Tomcat 安装Tomcat分为安装Tomcat和安装JDK两个步骤 JDK( Java Development Kit ) 是Sun Microsystems针对Java ...
- UI框架搭建DAY2
今天的主要任务是完善NormalPanel, 搭建PopupPanel. 在编写PanelManager的过程中,发现了一个bug.昨天把panelPath直接传给了ResourceManager.G ...