* 移動客戶端在和服務器交互的時候,上傳和下載使用十分廣泛。
* 在我們下載文件的時候,我們在點擊暫停的時候可以暫停下載,點擊下載的時候可以繼續下載,這個功能如何實現?
* 下載進度條如何顯示?
* 首先先判斷要判斷要下載的文件在本地沙盒中是否存在。
* 如果存在的話,要判斷下載文件的長度。
* 假設文件長度是500,我們發起下載請求的時候應該從500開始。
* 點擊暫停下載,應該將鏈接斷掉。
* 再次點擊下載的時候,根據下載文件長度,繼續下載。
* 假設我們要下載的文件在服務器的路徑為:http://localhost:8080:down/xcode_6.dmg;
* 我們將要下載的文件方法本地沙盒中。文件命名為:xcode.dmg.
* 獲取文件保存路徑的代碼:(折疊)
1 -(NSString *)getFilePath2 {3 NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];4 NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"];5 return filePath;6 }
* 因為下載的文件比較大,我們需要采取異步請求網絡。
* 異步請求網絡常用的有四個代理方法。
* 發起網絡請求下載。(下載起始點為上次暫停點,判斷上次暫停位置方法是,獲取文件屬性,從屬性中可以查看文件長度,請求點為該長度后面的內容)
* 假設向獲取某個字節的內容,可以使用:
//bytes = 0-499 請求前500個字節的內容
//bytes = 500- 請求500字節之后的內容
//bytes = 500-1000 請求資源中某一范圍的內容
//bytes = 0-1,499-500 請求多個范圍之間的內容
* 進度條過去文件下載進度,可以使用已經下載的文件的字節數/文件的總字節數。
下面為具體的代碼段,里面有詳細的注釋:
#import <UIKit/UIKit.h>@interface ViewController : UIViewController<NSURLConnectionDataDelegate>{ //進度條變量,顯示文件下載進度 IBOutlet UiprogressView *_PRogress; //文件處理,將下載的文件寫入本地沙盒 NSFileHandle *_fileHandle; //url連接,點解暫停,取消連接,點擊下載,開始下載 NSURLConnection *_connection; //已經接收數據大小 long long _receiveSize; //文件總共的大小 long long _totalSize;}//下載按鈕點擊響應函數- (IBAction)download:(id)sender;//暫停按鈕點擊響應函數- (IBAction)pause:(id)sender;@end
- (IBAction)download:(id)sender{ //文件的路徑 NSString *string = @"http://localhost:8080/down/xcode_6.dmg"; //文件的路徑轉化為url NSURL *url = [NSURL URLWithString:string]; //創建可變請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //判斷沙盒路徑下有沒有這個文件,YES表示這個文件已經下載,NO表示還沒有下載 if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]] == YES) { //根據文件的屬性,獲取之前下載數據量是多少 NSDictionary *fileDic = [[NSFileManager defaultManager]attributesOfItemAtPath:[self getFilePath] error:nil]; //文件的長度就是已經下載的數據量 _receiveSize = [fileDic[NSFileSize] longLongValue]; //設置Range,從Range之后的內容開始下載 //bytes = 0-499 請求前500個字節的內容 //bytes = 500- 請求500字節之后的內容 //bytes = 500-1000 請求資源中某一范圍的內容 //bytes = 0-1,499-500 請求多個范圍之間的內容 NSString *bytes = [NSString stringWithFormat:@"bytes=%lld-",_receiveSize]; [request setValue:bytes forHTTPHeaderField:@"Range"]; } //發起異步請求,文件比較法,使用異步請求 _connection = [NSURLConnection connectionWithRequest:request delegate:self];}- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ //分析響應頭 NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; //獲取響應頭,是一個字典 NSDictionary *responseHeader = httpResponse.allHeaderFields; //接收文件總的大小等于已經下載的數據量,加上為下載的數據量 _totalSize = _receiveSize + [responseHeader[@"Content-Length"] longLongValue]; //創建文件管理類 NSFileManager *fileManager = [NSFileManager defaultManager]; //沙盒中不存在要下載的文件,就創建該文件 if ([fileManager fileExistsAtPath:[self getFilePath]] == NO) { [fileManager createFileAtPath:[self getFilePath] contents:nil attributes:nil]; } //根據路徑寫入文件 _fileHandle = [NSFileHandle fileHandleForWritingAtPath:[self getFilePath]];}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //文件比較大的話,需要多次寫入,寫入的話,需要將光標定位到結尾 [_fileHandle seekToEndOfFile]; //將數據寫入到文件 [_fileHandle writeData:data]; //最新接收到數據的大小等于文件中已有的數據,加上剛剛下載的數據量 _receiveSize = _receiveSize + data.length; //計算進度 float jundu = (float)_receiveSize / _totalSize; //使用進度條來表示進度 _progress.progress = jundu;}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ //文件完成傳輸,關閉文件管理 [_fileHandle closeFile];}- (IBAction)pause:(id)sender{ //點擊暫停,取消請求連接 [_connection cancel]; _connection = nil;}-(NSString *)getFilePath{ NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"]; return filePath;}
新聞熱點
疑難解答