网络编程(08)NSURLSessionUploadTask 上

2018-05-25  本文已影响63人  Rui哥

一 NSURLSessionUploadTask 上传文件大致步骤:

#define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"   // 这个是分割符

1> 确定文件上传的路径URL
2> 创建一个NSMutableRequest  (request)
3> 设置request 的请求请求方式为 POST
4> 设置请求头信息Content-Type,告诉服务器这时一个上传文件的请求: 分割符是什么
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
5> 按照固定的格式设置请求体 (请求体包含具体的请求参数 和 要上传的文件数据)
6> 创建Session
7> 使用session 创建NSURLSessionUploadTask
8> 指行task 上传数据

二上传文件请求体详解

--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
Content-Type: image/png

需要上传的文件数据
--分隔符
Content-Disposition: form-data; name="username"

abc
--分隔符--
--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
Content-Type: image/png

需要上传的文件数据

2> 第二个部分: 非文件参数部分

--分隔符
Content-Disposition: form-data; name="username"

abc

3> 第三个部分: 结尾标识

--分隔符--

三上传文件实现

#define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"  //分隔符
#define KnewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] // 换行



-(void)upload1
{
    //(1)确定上传路径
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upload"];
    
    //(2)创建"可变"请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    
    //(3)修改请求方法为POST
    request.HTTPMethod = @"POST";
    
    //+ "设置请求头信息,告诉服务器这是一个文件上传请求"
    //Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryATJp9y6FGSNtJKNW
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
    
    //+ "按照固定的格式来拼接数据"
    //(4)设置请求体信息(文件参数)
    
    //(5)创建会话对象
    NSURLSession *session = [NSURLSession sharedSession];
    
    //(6)根据会话对象来创建uploadTask
    /* 参数说明
     *
     * 第一个参数:请求对象
     * 第二个参数:本应该放在请求体中的信息
[self bodyData] 相当于POST请求的 请求体,上传文件时要填写着这个地方,填在 request 的 请求头里是会被忽略的
     */
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self bodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    //(7)执行task发送请求上传文件
    [uploadTask resume];

}




// 上传文件的请求体
-(NSData *)bodyData
{
    NSMutableData *data = [NSMutableData data];
    
    //01 拼接文件参数
    /*
    --分隔符
    Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
    Content-Type: image/png
    空行
    文件数据
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //name:file 服务器规定
    //filename:该文件上传到服务器之后的名称
    //username|pwd
    [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20161126_210.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //要上传文件的二进制数据类型  MIMEType 组成:大类型/小类型
    [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20161126_238.png"];
    [data appendData:imageData];
    [data appendData:KnewLine];
    
    //02 拼接非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     abcdf
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //name:username
    [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    [data appendData:[@"abcdef" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    
    //03 结尾标识
    /*
     --分隔符--
     */
     [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    return data;
}


#define Kboundary @"----WebKitFormBoundaryATJp9y6FGSNtJKNW"
#define KnewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
@interface ViewController ()<NSURLSessionDataDelegate>






-(void)upload2
{
    //(1)确定上传路径
    NSURL *url = [NSURL URLWithString:@"http://http://127.0.0.1/upload/upload"];
    
    //(2)创建"可变"请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    
    //(3)修改请求方法为POST
    request.HTTPMethod = @"POST";
    
    //+ "设置请求头信息,告诉服务器这是一个文件上传请求"
    //Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryATJp9y6FGSNtJKNW
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
    
    //+ "按照固定的格式来拼接数据"
    //(4)设置请求体信息(文件参数)
    
    //(5)创建会话对象 设置代理 以便监听上传的进度
   NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                          delegate:self
                                                     delegateQueue:[NSOperationQueue mainQueue]];
    
    //(6)根据会话对象来创建uploadTask
    /* 参数说明
     *
     * 第一个参数:请求对象
     * 第二个参数:本应该放在请求体中的信息
     */
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self bodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    //(7)执行task发送请求上传文件
    [uploadTask resume];
    
}






-(NSData *)bodyData
{
    NSMutableData *data = [NSMutableData data];
    
    //01 拼接文件参数
    /*
    --分隔符
    Content-Disposition: form-data; name="file"; filename="Snip20161126_210.png"
    Content-Type: image/png
    空行
    文件数据
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //name:file 服务器规定
    //filename:该文件上传到服务器之后的名称
    //username|pwd
    [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20161126_210.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //要上传文件的二进制数据类型  MIMEType 组成:大类型/小类型
    [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20161126_238.png"];
    [data appendData:imageData];
    [data appendData:KnewLine];
    
    //02 拼接非文件参数
    /*
     --分隔符
     Content-Disposition: form-data; name="username"
     空行
     abcdf
     */
    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    //name:username
    [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    [data appendData:[@"abcdef" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    
    //03 结尾标识
    /*
     --分隔符--
     */
     [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    return data;
}



#pragma mark NSURLSessionDataDelegate 
-(void)URLSession:(NSURLSession *)session
             task:(NSURLSessionTask *)task
  didSendBodyData:(int64_t)bytesSent //本次上传的文件数据大小
   totalBytesSent:(int64_t)totalBytesSent //已经上传的文件数据的总大小
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend //文件的总大小
{
    NSLog(@"%f",1.0 * totalBytesSent / totalBytesExpectedToSend);
}




上一篇下一篇

猜你喜欢

热点阅读