1 #import "HMViewController.h" 2 3 @interface HMViewController () 4 @property (weak, nonatomic) IBOutlet UIProgressView *progressView; 5 /** 6 * 写数据的文件句柄 7 */ 8 @property (nonatomic, strong) NSFileHandle *writeHandle; 9 /** 10 * 当前已下载数据的长度 11 */ 12 @property (nonatomic, assign) long long currentLength; 13 /** 14 * 完整文件的总长度 15 */ 16 @property (nonatomic, assign) long long totalLength; 17 18 /** 19 * 连接对象 20 */ 21 @property (nonatomic, strong) NSURLConnection *conn; 22 23 /** 24 * 是否在下载 25 */ 26 @property (nonatomic, assign, getter = isDownloading) BOOL downloading; 27 28 - (IBAction)start:(UIButton *)button; 29 @end 30 31 @implementation HMViewController 32 33 - (void)viewDidLoad 34 { 35 [super viewDidLoad]; 36 37 } 38 39 // 按钮文字: "开始", "暂停" 40 - (IBAction)start:(UIButton *)button { // self.currentLength == 200 41 if (self.isDownloading) { // 暂停下载 42 self.downloading = NO; 43 44 [button setTitle:@"开始" forState:UIControlStateNormal]; 45 46 // 取消当前的请求 47 [self.conn cancel]; 48 self.conn = nil; 49 } else { // 开始下载 50 self.downloading = YES; 51 52 [button setTitle:@"暂停" forState:UIControlStateNormal]; 53 54 NSURL *url = [NSURL URLWithString:@"http://192.168.1.200:8080/MJServer/resources/jre.zip"]; 55 // 默认就是GET请求 56 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 57 // 设置请求头信息 58 NSString *value = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength]; 59 [request setValue:value forHTTPHeaderField:@"Range"]; 60 self.conn = [NSURLConnection connectionWithRequest:request delegate:self]; 61 } 62 } 63 64 #pragma mark - NSURLConnectionDataDelegate 代理方法 65 /** 66 * 1. 当接受到服务器的响应(连通了服务器)就会调用 67 */ 68 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 69 { 70 #warning 一定要判断 71 if (self.totalLength) return; 72 73 // 0.文件的存储路径 74 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 75 NSString *filepath = [caches stringByAppendingPathComponent:@"jre.zip"]; 76 77 // 1.创建一个空的文件到沙盒中 78 NSFileManager *mgr = [NSFileManager defaultManager]; 79 // 刚创建完毕的大小是0字节 80 [mgr createFileAtPath:filepath contents:nil attributes:nil]; 81 82 // 2.创建写数据的文件句柄 83 self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath]; 84 85 // 3.获得完整文件的长度 86 self.totalLength = response.expectedContentLength; 87 } 88 89 /** 90 * 2. 当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据) 91 */ 92 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 93 { 94 // 累加长度 95 self.currentLength += data.length; 96 97 // 显示进度 98 double progress = (double)self.currentLength / self.totalLength; 99 self.progressView.progress = progress; 100 101 // 移动到文件的尾部 102 [self.writeHandle seekToEndOfFile]; 103 // 从当前移动的位置(文件尾部)开始写入数据 104 [self.writeHandle writeData:data]; 105 } 106 107 /** 108 * 3. 当服务器的数据接受完毕后就会调用 109 */ 110 - (void)connectionDidFinishLoading:(NSURLConnection *)connection 111 { 112 NSLog(@"connectionDidFinishLoading----"); 113 114 // 清空属性值 115 self.currentLength = 0; 116 self.totalLength = 0; 117 118 // 关闭连接(不再输入数据到文件中) 119 [self.writeHandle closeFile]; 120 self.writeHandle = nil; 121 } 122 123 /** 124 * 请求错误(失败)的时候调用(请求超时\断网\没有网, 一般指客户端错误) 125 */ 126 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 127 { 128 129 } 130 @end