当前位置: 首页>編程日記>正文

iOS网络编程---根据URL下载网络文件的方法

iOS网络编程---根据URL下载网络文件的方法

下面是源码,注释掉的部分代码是一次性下载的功能(不推荐),正常运行的代码实现了:

- 功能:根据提供的URL下载网络文件

PS:其中有6个关键字,是实现该功能使用到的知识点,我在代码的后面做了必要的归纳和整理。

#define kReceivedTotal @"receivedTotal"
#define kTotal @"total"
#import "ViewController.h"@interface ViewController () <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
{//全局连接对象,用来取消下载NSURLConnection *_connection;double _totalLength;    //获取数据总长度NSMutableData *_totalData;    //接收到的数据double _receiveLength;    //接收到的数据长度//判断是否正在下载BOOL isDownloading;//下载文件路径NSString *_filePath;
}
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];//①:NSUserDefaults类
-------------------    //读取本地化的plist文件,获取已下载数据量和文件总大小NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];_receiveLength = [[userDefault objectForKey:kReceivedTotal] doubleValue];_totalLength = [[userDefault objectForKey:kTotal] doubleValue];//作用:程序退出后会记录退出前下载的情况,下一次进入后会根据上一次退出时的情况改变progress和label的样式if (_totalLength > 0) {double progress = _receiveLength / _totalLength;_progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progress*100];_progressLine.progress = progress;}}- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}#pragma mark - 按钮:点击下载方法
- (IBAction)startDownload:(UIButton *)sender {//如果点击下载按钮立即跳出下载完成,很可能试url有问题。此处找的是QQ音乐上的url,第二天便会更新//isDownloading:用于判断下载状态。进入下载时为YES,下载完成时为NOif (!isDownloading) {NSURL *url = [NSURL URLWithString:@"http://218.205.82.11/mobileoc.music.tc.qq.com/F000003BiKB44LknC0.flac?continfo=122542B50C9B1A0317535549A8AD143E8038EA7648884166&vkey=8078E72D66A07AD5C4B3696E52E8702B0612145B7EFF5BBB77FEAB63A1D6673DE51521C2D4397D8D659204309621EBB8EABA0FFD614A4171&guid=27238e629f2f6ffc850c749439bf81a1824fc41d&fromtag=55&uin=290363831"];//②:NSURLRequest
----------------NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];//通过http下载请求头来设置继续下载的位置NSString *value = [NSString stringWithFormat:@"bytes=%i-", (int)_receiveLength];[request setValue:value forHTTPHeaderField:@"Range"];//NSLog(@"继续下载:%@", request.allHTTPHeaderFields);//③:NSURLConnection
-------------------//发送异步网络请求_connection = [NSURLConnection connectionWithRequest:request delegate:self];//此时正在下载isDownloading = YES;//1.下面是不设置断点续传时的写法:在路径下直接创建单例文件用于保存下载到的数据//④:NSFileManager
-----------------//        //创建空文件来保存下载数据
//        NSString *fileName = @"听爸爸的话.mp3";
//        _filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", fileName];
//        //为路径创建单例
//        [[NSFileManager defaultManager] createFileAtPath:_filePath contents:nil attributes:nil];//2.断点续传的写法//创建临时目录路径_filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/tmp/%@", @"听爸爸的话.mp3"];//NSLog(@"%@", _filePath);//判断临时文件是否存在,如果不存在则创建if (![[NSFileManager defaultManager] fileExistsAtPath:_filePath]) {//先创建临时文件夹NSString *dirPath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/tmp"];[[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];//创建空的临时文件[[NSFileManager defaultManager] createFileAtPath:_filePath contents:nil attributes:nil];}}
}#pragma mark - 按钮:点击暂停下载方法
- (IBAction)cancelDownload:(UIButton *)sender {//取消下载[_connection cancel];//把数据包存入文件[self appendFileData:_totalData];//释放内存_totalData.data = nil;isDownloading = NO;//暂停时,保存已下载数据量和文件总数量到本地,保证程序退出后下次进入仍然可以实现断点续传[self saveUserDefaulst];
}#pragma mark - 文件写入方法
-(void) appendFileData:(NSData *) data {if (data.length == 0 || _filePath.length == 0) {//文件有误return;}//⑤:NSFileHandle
----------------NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:_filePath];[fileHandle seekToEndOfFile];[fileHandle writeData:data];[fileHandle closeFile];
}#pragma mark - NSURLConnectionDelegate
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;//获取响应头NSDictionary *fields = httpResponse.allHeaderFields;//获取下载文件的总长度if (_totalLength == 0) {NSNumber *length = fields[@"Content-Length"];_totalLength = [length doubleValue];}//用于存放下载得到的数据,这是存放在内存中的_totalData = [[NSMutableData alloc] init];
}-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {    
//    double progress = _totalData.length / _totalLength;//根据当前下载的数据包大小来刷新进度条和Label的现实[_totalData appendData:data];_receiveLength += data.length;double progress = _receiveLength / _totalLength;//刷新UIself.progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progress*100];self.progressLine.progress = progress;if (_totalData.length > 500*1024) {[self appendFileData: _totalData];//释放内存_totalData.data = nil;}
}-(void)connectionDidFinishLoading:(NSURLConnection *)connection {//方法1:该写法用于一次性完整下载(不推荐)
//    //下载完成后保存数据到本地
//    NSURL *url = connection.currentRequest.URL;
//    NSString *urlString = url.absoluteString;
//    NSString *fileName = urlString.lastPathComponent;
//    
//    //根据?分割符存放数据到数组
//    NSArray *array = [fileName componentsSeparatedByString:@"?"];
//    //获取文件名
//    fileName = array[0];
//    
//    //获取沙盒路径
//    NSString *filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", fileName];
//    NSLog(@"%@", filePath);
//    
//    //把数据写入文件
//    [_totalData writeToFile:filePath atomically:YES];//方法2:该方法满足了断点下载,虽然增大了开销但是确保了下载的安全性//文件末尾不足500KB大小的数据也要写入文件,所以文件下载“完成”后还要调用一个appendFileData方法[self appendFileData:_totalData];//清楚缓存_totalData.data = nil;self.progressLabel.text = @"下载完成";isDownloading = NO;//将下载完成的文件从临时目录剪切到目的目录NSFileManager *manager = [NSFileManager defaultManager];//确定目录文件路径NSString *targetFilePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", @"听爸爸的话.mp3"];//判断目标文件是否存在,如果存在把旧文件删除,准备剪切操作if ([manager fileExistsAtPath:targetFilePath]) {[manager removeItemAtPath:targetFilePath error:nil];}//剪切方法的限制:不能把已经存在文件覆盖,如果此文件存在,在剪切之前需要先删除[manager moveItemAtPath:_filePath toPath:targetFilePath error:nil];//保存数据[self saveUserDefaulst];//下载完成把已下载数据量和文件总大小清零_receiveLength = 0;_totalLength = 0;
}#pragma mark - NSUserDefaults 保存下载的数据量和文件数据量到本地
-(void) saveUserDefaulst {//下载完成时,保存已下载数据量和文件宗数据量到本地NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];[userDefault setObject:@(_receiveLength) forKey:kReceivedTotal];[userDefault setObject:@(_totalLength) forKey:kTotal];//数据同步写入到plist文件[userDefault synchronize];
}
@end


https://www.fengoutiyan.com/post/15240.html

相关文章:

  • url文件怎么打开 苹果手机
  • 苹果手机如何获取url
  • 苹果url
  • 苹果和安卓怎么传文件
  • ios描述文件
  • 苹果url怎么获取
  • 苹果怎么打开url文件
  • ios133描述文件在哪
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機