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