网络编程(二)NSURLConnection 实现文件下载上传
1 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 2 { 3 //拼接接收到的数据 4 [self.fileData appendData: data]; 5 } 6 7 - (void)connectionDidFinishLoading:(NSURLConnection *)connection 8 { 9 10 //将文件放入沙盒中,这里选择放入caches 11 NSString *caches = [NSSearchPathForDirectoriesInDomains( NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 12 NSString *filePath = [caches stringByAppendingPathComponent: @"bigDataFile.zip"]; 13 [self.fileData writeToFile: filePath atomically: YES]; 14 15 }
- 大数据量的文件应该放到 tmp 或 Caches 中,因为 Documents,Library/Preferences 都会自动备份到服务器,而 tmp 和 Caches 的区别就是前者会被随机删除后者不会
- 这里有2处效率很低,一是代码拼接出,二是将文件写入沙河,这里把大数据都放在了内存中,如果数据太大就会太占用内存甚至挤爆内存
1 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 2 { 3 4 //文件的存储路径 5 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 6 NSString *filepath = [caches stringByAppendingPathComponent:@"文件.zip"]; 7 8 //再文件存储路径中创建一个空的文件夹用于放置数据 9 NSFileManager *mgr = [NSFileManager defaultManager]; 10 [mgr createFileAtPath:filepath contents:nil attributes:nil]; 11 12 //创建写数据的文件句柄 13 self.handle = [NSFileHandle fileHandleForWritingAtPath:filepath]; 14 15 // 3.获得完整文件的长度 16 self.totalLength = response.expectedContentLength; 17 } 18 19 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 20 { 21 22 // 每次开始写入文件时将 NSFileHandle 移动到文件的尾部 23 [self.handle seekToEndOfFile]; 24 // 从当前移动的位置(文件尾部)开始写入数据 25 [self.handle writeData:data]; 26 } 27 28 - (void)connectionDidFinishLoading:(NSURLConnection *)connection 29 { 30 // 记住最后不再使用时要关闭连接(不再输入数据到文件中) 31 [self.handle closeFile]; 32 self.handle = nil; 33 }
1 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 2 { 3 //可以在响应头中获得文件完整的长度 4 self.totalLength = response.expectedContentLength; 5 } 6 7 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 8 { 9 // 累加每一次获取的数据的长度 10 self.currentLength += data.length; 11 12 // 比较已下载数据和总数据长度,显示进度 13 double progress = (double)self.currentLength / self.totalLength; 14 self.progressView.progress = progress; 15 } 16 17 - (void)connectionDidFinishLoading:(NSURLConnection *)connection 18 { 19 // 清空属性值 20 self.currentLength = 0; 21 self.totalLength = 0; 22 }
1 -(void) startDownloading: (UIButton *) button { 2 3 //根据是否正在下载改变按钮文字 4 if (self.isDownloading) { // 暂停下载 5 6 self.downloading = NO; 7 8 [button setTitle:@"开始下载文件" forState:UIControlStateNormal]; 9 10 // 取消当前的请求 11 [self.connection cancel]; 12 self.connection = nil; 13 14 } else { // 开始下载 15 16 self.downloading = YES; 17 18 [button setTitle:@"暂停下载文件" forState:UIControlStateNormal]; 19 20 NSURL *url = [NSURL URLWithString:@"文件.zip"]; 21 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 22 23 // 设置请求头信息,从上次停止的地方开始下载数据 24 NSString *value = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength]; 25 //设置下载范围 26 [request setValue:value forHTTPHeaderField:@"Range"]; 27 28 self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; 29 } 30 31 }
1 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 2 { 3 if (self.totalLength) return; 4 } 5
- - 符号用于分隔 前面的数字表示起始字节数 ,后面的数组表示截止字节数,没有则表示到末尾
- ,符号用于分组,可以一次指定多个Range
- 引入 libz.dylib 框架:
- 导入类库:
- 解压文件:
1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 2 3 [SSZipArchive unzipFileAtPath: 文件路径 toDestination: 解压位置]; 4 });
- 压缩文件:
1 // 获得 bundle 中所有的png图片路径 2 NSArray *files = [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:nil]; 3 4 // 压缩文件需要存放的路径 5 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 6 NSString *zipFilepath = [caches stringByAppendingPathComponent:@"pngs.zip"]; 7 8 // 压缩文件为 zip 9 [SSZipArchive createZipFileAtPath:zipFilepath withFilesAtPaths:files];
1 // 创建请求 2 NSURL *url = [NSURL URLWithString:@"http://192.168.1.200:8080/MJServer/order"]; 3 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 4 request.HTTPMethod = @"POST"; 5 6 // 设置请求头 7 [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 8 9 // 设置请求体 10 NSDictionary *json = @{ @"username" : @"jack",@"passwd" : @"789",@"age" : @"13"}; 11 12 //将字典转换成 json 数据 13 NSData *data = [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingPrettyPrinted error:nil]; 14 request.HTTPBody = data; 15 16 // 发送请求 17 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 18 19 }];
- 创建请求
- 设置请求头
- 设置请求体
- 发送请求
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。