一、文件下载
重点:NSURLConnection的代理方法不是NSURLConnectionDelegate,而是NSURLConnectionDataDelegate
1.下载小文件,只适合几百k,1、2M的文件
//1.设置网址 //2.加载请求 //3.设置代理 //4.实现代理方法下载文件 NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1492791082124&di=fc642407b4ec19430334653a9b873cff&imgtype=0&src=http%3A%2F%2Fi0.szhomeimg.com%2FUploadFiles%2FBBS%2F2006%2F10%2F24%2F27567833_1950.442.jpg"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; 代理实现 #pragma mark ---NSURLConnectionDelegate - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"下载失败%@",error); } //下载响应 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ //获取文件大小 _totalSize = response.expectedContentLength; } //下载数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //拼接数据 [_mudata appendData:data]; //获取当前进度 NSLog(@"%f",1.0*_mudata.length/_totalSize); } //下载完成 - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"1.jpg"]; [_mudata writeToFile:fullPath atomically:YES]; }
缺点:[_mudata appendData:data],会使内存暴涨,而且下载完毕后内存不会下降
2.通过句柄来下载大文件
#pragma mark ---------------------- #pragma mark NSURLConnectionDataDelegate -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"didReceiveResponse"); //1.得到文件的总大小(本次请求的文件数据的总大小) self.totalSize = response.expectedContentLength; //2.写数据到沙盒中 self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"]; //3.创建一个空的文件 [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil]; //4.创建文件句柄(指针) self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath]; } -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { //1.移动文件句柄到数据的末尾 [self.handle seekToEndOfFile]; //2.写数据 [self.handle writeData:data]; //3.获得进度 self.currentSize += data.length; //进度=已经下载/文件的总大小 NSLog(@"%f",1.0 * self.currentSize/self.totalSize); self.progressView.progress = 1.0 * self.currentSize/self.totalSize; //NSLog(@"%@",self.fullPath); } -(void)connectionDidFinishLoading:(NSURLConnection *)connection { //1.关闭文件句柄 [self.handle closeFile]; self.handle = nil; NSLog(@"connectionDidFinishLoading"); NSLog(@"%@",self.fullPath); }
3.通过断点续传来下载大文件(初级版)
设置请求头,如果文件存在就继续下载
//与上面不同的是请求头增加了Range NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSString *Range = [NSString stringWithFormat:@"bytes=%zd",_currentSize]; [request setValue:Range forHTTPHeaderField:@"Range"]; //下面判断文件是否存在不同,如果大于0就返回,不好的地方,删除了文件就不能再下载,待之后完善 //接受响应 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@"%@",response); NSLog(@"%@",response.MIMEType); //如果放在最前面,文件大小就需要加上当前文件的大小 //如果有下载返回,只适用于当前 //设置沙盒文件 //创建空文件用NSFileManager //句柄指向该文件 _totalSize = response.expectedContentLength+_currentSize; if(_currentSize > 0){ NSLog(@"文件已经下载"); return; } _fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"downFile.jpg"]; //contents内容为空, [[NSFileManager defaultManager] createFileAtPath:_fullPath contents:nil attributes:nil]; _fileHandle = [NSFileHandle fileHandleForWritingAtPath:_fullPath]; } //接受数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //将句柄移动到文件末尾 //通过句柄写入数据 //获取文件进度 if (_currentSize <=1) { _currentSize += data.length; NSLog(@"%f",1.0*_currentSize/_totalSize); } [_fileHandle seekToEndOfFile]; [_fileHandle writeData:data]; _progressView.progress = 1.0*_currentSize/_totalSize; }
缺点:删除了以后不能重新下载
4.文件上传,NSURLConnection上传比较比较奇葩
//文件上传 - (void)fileUpload{ //1.确认请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"]; //2.创建可变请求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //3.设置请求方法 request.HTTPMethod = @"POST"; //4.设置请求头信息,Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryjv0UfA04ED44AhWx [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"]; //5.拼接请求体参数 NSMutableData *fileData = [NSMutableData data]; /* --分隔符 Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png" Content-Type: image/png(MIMEType:大类型/小类型) 空行 文件参数 */ [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; //name:file 服务器规定的参数 //filename:Snip20160225_341.png 文件保存到服务器上面的名称 //Content-Type:文件的类型 [fileData appendData:[@"Content-Disposition: form-data; name="file"; filename="Snip20170424_7.png"" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:KNewLine]; //image图片 UIImage *image = [UIImage imageNamed:@"Snip20170424_7"]; //UIImage --->NSData NSData *imageData = UIImagePNGRepresentation(image); [fileData appendData:imageData]; [fileData appendData:KNewLine]; //非文件参数 //分隔符, //非文件参数 /* --分隔符 Content-Disposition: form-data; name="username" 空行 123456 */ [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:[@"Content-Disposition: form-data; name="username"" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:KNewLine]; [fileData appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; //结尾标识符 /* --分隔符-- */ [fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; //6.设置请求体,请求体二进制数据 request.HTTPBody = fileData; //发送请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //解析数据 NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); }]; }