1. 程式人生 > >iOS開發網路篇—檔案下載(暫停和恢復)

iOS開發網路篇—檔案下載(暫停和恢復)

一、Range簡單說明

通過設定請求頭Range可以指定每次從網路下載資料包的大小

Range示例

bytes=0-499 從0到499的頭500個位元組

bytes=500-999 從500到999的第二個500位元組

bytes=500- 從500位元組以後的所有位元組 

bytes=-500 最後500個位元組

bytes=500-599,800-899 同時指定幾個範圍

Range小結

- 用於分隔

前面的數字表示起始位元組數

後面的陣列表示截止位元組數,沒有表示到末尾

, 用於分組,可以一次指定多個Range,不過很少用

二、程式碼示例

複製程式碼
  1 #import "YYViewController.h"
  2 
  3 @interface
YYViewController () 4 //檔案資料 5 @property(nonatomic,strong)NSMutableData *fileData; 6 //檔案控制代碼 7 @property(nonatomic,strong)NSFileHandle *writeHandle; 8 //當前獲取到的資料長度 9 @property(nonatomic,assign)long long currentLength; 10 //完整資料長度 11 @property(nonatomic,assign)long long sumLength; 12 //是否正在下載 13
@property(nonatomic,assign,getter = isdownLoading)BOOL downLoading; 14 //請求物件 15 @property(nonatomic,strong)NSURLConnection *cnnt; 16 //獲取按鈕 17 @property (weak, nonatomic) IBOutlet UIButton *btn; 18 //獲取進度條 19 @property (weak, nonatomic) IBOutlet UIProgressView *progress; 20 //按鈕點選事件 21 - (IBAction)star;
22 23 @end 24 25 @implementation YYViewController 26 27 - (void)viewDidLoad 28 { 29 [super viewDidLoad]; 30 } 31 32 - (IBAction)star { 33 //當下載完成後,點選按鈕文字變為已下載 34 35 //判斷當前是否正在下載 36 if (self.isdownLoading) {//如果當前正在下載,那麼點選按鈕,按鈕變為暫停狀態 37 [self.btn setTitle:@"下載" forState:UIControlStateNormal]; 38 self.downLoading=NO; 39 40 //取消傳送請求 41 [self.cnnt cancel]; 42 self.cnnt=nil; 43 }else 44 {//如果當前沒有下載,那麼點選按鈕,開始或者是繼續下載 45 [self.btn setTitle:@"暫停" forState:UIControlStateNormal]; 46 self.downLoading=YES; 47 //建立下載路徑 48 NSURL *url=[NSURL URLWithString:@"http://192.168.1.53:8080/MJServer/resources/video.zip"]; 49 50 //建立一個請求 51 // NSURLRequest *request=[NSURLRequest requestWithURL:url]; 52 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url]; 53 54 //設定請求頭資訊 55 //self.currentLength位元組部分重新開始讀取 56 NSString *value=[NSString stringWithFormat:@"bytes=%lld-",self.currentLength]; 57 [request setValue:value forHTTPHeaderField:@"Range"]; 58 59 //傳送請求(使用代理的方式) 60 self.cnnt=[NSURLConnection connectionWithRequest:request delegate:self]; 61 // [self.cnnt start]; 62 } 63 } 64 65 #pragma mark- NSURLConnectionDataDelegate代理方法 66 /* 67 *當接收到伺服器的響應(連通了伺服器)時會呼叫 68 */ 69 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 70 { 71 #warning 判斷是否是第一次連線 72 if (self.sumLength) return; 73 74 //1.建立檔案存數路徑 75 NSString *caches=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 76 NSString *filePath=[caches stringByAppendingPathComponent:@"video.zip"]; 77 78 79 80 //2.建立一個空的檔案,到沙盒中 81 NSFileManager *mgr=[NSFileManager defaultManager]; 82 //剛建立完畢的大小是o位元組 83 [mgr createFileAtPath:filePath contents:nil attributes:nil]; 84 85 //3.建立寫資料的檔案控制代碼 86 self.writeHandle=[NSFileHandle fileHandleForWritingAtPath:filePath]; 87 88 //4.獲取完整的檔案長度 89 self.sumLength=response.expectedContentLength; 90 } 91 92 /* 93 *當接收到伺服器的資料時會呼叫(可能會被呼叫多次,每次只傳遞部分資料) 94 */ 95 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 96 { 97 //累加接收到的資料長度 98 self.currentLength+=data.length; 99 //計算進度值 100 double progress=(double)self.currentLength/self.sumLength; 101 self.progress.progress=progress; 102 103 104 //一點一點接收資料。 105 NSLog(@"接收到伺服器的資料!---%d",data.length); 106 //把data寫入到建立的空檔案中,但是不能使用writeTofile(會覆蓋) 107 //移動到檔案的尾部 108 [self.writeHandle seekToEndOfFile]; 109 //從當前移動的位置,寫入資料 110 [self.writeHandle writeData:data]; 111 } 112 113 /* 114 *當伺服器的資料載入完畢時就會呼叫 115 */ 116 -(void)connectionDidFinishLoading:(NSURLConnection *)connection 117 { 118 NSLog(@"下載完畢----%lld",self.sumLength); 119 //關閉連線,不再輸入資料在檔案中 120 [self.writeHandle closeFile]; 121 self.writeHandle=nil; 122 123 //清空進度值 124 self.currentLength=0; 125 self.sumLength=0; 126 127 //設定按鈕文字為“已經下載完成” 128 [self.btn setTitle:@"已經下載完成" forState:UIControlStateNormal]; 129 [self.btn setEnabled:NO]; 130 } 131 /* 132 *請求錯誤(失敗)的時候呼叫(請求超時\斷網\沒有網\,一般指客戶端錯誤) 133 */ 134 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 135 { 136 } 137 @end
複製程式碼

注意:關鍵程式碼

        從self.currentLength位元組部分重新開始讀取

        NSString *value=[NSString stringWithFormat:@"bytes=%lld-",self.currentLength];

        [request setValue:value forHTTPHeaderField:@"Range"];

模擬器執行情況:

程式啟動介面:

點選下載按鈕後,開始下載檔案,此時按鈕的提示文字變為暫停。

下載暫停後,點選下載按鈕,繼續之前的下載。

下載完成後介面效果:

下載完成後,檢視專案沙盒: