文件上传
下面看一下如何使用NSURLSessionUploadTask实现文件上传,这里贴出主要的几个方法:
#pragma mark 取得mime types -(NSString *)getMIMETypes:(NSString *)fileName{ return @"image/jpg"; } #pragma mark 取得数据体 -(NSData *)getHttpBody:(NSString *)fileName{ NSString *boundary=@"KenshinCui"; NSMutableData *dataM=[NSMutableData data]; NSString *strTop=[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"file1\"; filename=\"%@\"\nContent-Type: %@\n\n",boundary,fileName,[self getMIMETypes:fileName]]; NSString *strBottom=[NSString stringWithFormat:@"\n--%@--",boundary]; NSString *filePath=[[NSBundle mainBundle] pathForResource:fileName ofType:nil]; NSData *fileData=[NSData dataWithContentsOfFile:filePath]; [dataM appendData:[strTop dataUsingEncoding:NSUTF8StringEncoding]]; [dataM appendData:fileData]; [dataM appendData:[strBottom dataUsingEncoding:NSUTF8StringEncoding]]; return dataM; } #pragma mark 上传文件 -(void)uploadFile{ NSString *fileName=@"pic.jpg"; //1.创建url NSString *urlStr=@"http://192.168.1.208/FileUpload.aspx"; urlStr =[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url=[NSURL URLWithString:urlStr]; //2.创建请求 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url]; request.HTTPMethod=@"POST"; //3.构建数据 NSString *path=[[NSBundle mainBundle] pathForResource:fileName ofType:nil]; NSData *data=[self getHttpBody:fileName]; request.HTTPBody=data; [request setValue:[NSString stringWithFormat:@"%lu",(unsigned long)data.length] forHTTPHeaderField:@"Content-Length"]; [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",@"KenshinCui"] forHTTPHeaderField:@"Content-Type"]; //4.创建会话 NSURLSession *session=[NSURLSession sharedSession]; NSURLSessionUploadTask *uploadTask=[session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (!error) { NSString *dataStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@",dataStr); }else{ NSLog(@"error is :%@",error.localizedDescription); } }]; [uploadTask resume]; }
如果仅仅通过上面的方法或许文件上传还看不出和NSURLConnection之间的区别,因为拼接上传数据的过程和前面是一样的。事实上在NSURLSessionUploadTask中还提供了一个- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler方法用于文件上传。这个方法通常会配合“PUT”请求进行使用,由于PUT方法包含在Web DAV协议中,不同的WEB服务器其配置启用PUT的方法也不同,并且出于安全考虑,各类WEB服务器默认对PUT请求也是拒绝的,所以实际使用时还需做重分考虑,在这里不具体介绍,有兴趣的朋友可以自己试验一下。
代码演示
01.URLSession 上传,注意代理是 NSURLSessionTaskDelegate
- //
- // MJViewController.m
- // 01.URLSession 上传
- //
- // Created by apple on 14-4-30.
- // Copyright (c) 2014年 itcast. All rights reserved.
- //
- #import "MJViewController.h"
- @interface MJViewController () <NSURLSessionTaskDelegate>
- @end
- @implementation MJViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- [self uploadFile1];
- }
- #pragma mark - 监控上传进度
- - (void)uploadFile1
- {
- // 1. URL
- NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"head8.png" withExtension:nil];
- NSURL *url = [NSURL URLWithString:@"http://localhost/uploads/1.png"];
- // 2. Request
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:2.0f];
- // 1> PUT方法
- // PUT
- // 1) 文件大小无限制
- // 2) 可以覆盖文件
- // POST
- // 1) 通常有限制2M
- // 2) 新建文件,不能重名
- request.HTTPMethod = @"PUT";
- // 2> 安全认证
- // admin:123456
- // result base64编码
- // Basic result
- /**
- BASE 64是网络传输中最常用的编码格式 - 用来将二进制的数据编码成字符串的编码方式
- BASE 64的用法:
- 1> 能够编码,能够解码
- 2> 被很多的加密算法作为基础算法
- */
- NSString *authStr = @"admin:123456";
- NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
- NSString *base64Str = [authData base64EncodedStringWithOptions:0];
- NSString *resultStr = [NSString stringWithFormat:@"Basic %@", base64Str];
- [request setValue:resultStr forHTTPHeaderField:@"Authorization"];
- // 3. Session,全局单例(我们能够给全局的session设置代理吗?如果不能为什么?)
- // sharedSession是全局共享的,因此如果要设置代理,需要单独实例化一个Session
- /**
- NSURLSessionConfiguration(会话配置)
- defaultSessionConfiguration; // 磁盘缓存,适用于大的文件上传下载
- ephemeralSessionConfiguration; // 内存缓存,以用于小的文件交互,GET一个头像
- backgroundSessionConfiguration:(NSString *)identifier; // 后台上传和下载
- */
- NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
- NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
- // 需要监听任务的执行状态
- NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromFile:fileURL];
- // 4. resume
- [task resume];
- }
- #pragma mark - 上传进度的代理方法
- - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
- {
- // bytesSent totalBytesSent totalBytesExpectedToSend
- // 发送字节(本次发送的字节数) 总发送字节数(已经上传的字节数) 总希望要发送的字节(文件大小)
- NSLog(@"%lld-%lld-%lld-", bytesSent, totalBytesSent, totalBytesExpectedToSend);
- // 已经上传的百分比
- float progress = (float)totalBytesSent / totalBytesExpectedToSend;
- NSLog(@"%f", progress);
- }
- #pragma mark - 上传完成的代理方法
- - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
- {
- NSLog(@"完成 %@", [NSThread currentThread]);
- }