NSURLSession(三)POST请求—>上传图片

这个例子,还是以新浪微博为例。

首先在宏定义出POST请求头的一个属性:请求体边界,它是干什么用的呢,先别急,往下看

#define boundary @"AaB03x" //设置边界 参数可以随便设置

    //1.构建URL
      NSURL *url=[NSURL URLWithString:@"https://api.weibo.com/2/statuses/upload.json"];

    //2.创建request请求
    //NSURLRequest *request=[NSURLRequest requestWithURL:url];
    //NSURLRequest 不可变的  NSMutableURLRequest可变的 可以设置请求属性
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
    
    //(1)请求模式(默认是GET)
    [request setHTTPMethod:@"POST"];
    //(2)超时时间
    [request setTimeoutInterval:120];
    //(3)缓存策略
    [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
    
    //(4)请求头
    //以下代码是关键
    //upload task不会在请求头里添加content-type(上传数据类型)字段
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; charset=utf-8;boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];

    
    //[request setValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>]
    //[request addValue:<#(NSString *)#> forHTTPHeaderField:<#(NSString *)#>]
    //[request setAllHTTPHeaderFields:<#(NSDictionary *)#>]
    
    //(5)设置请求体
    //发送的微博需要这2个参数
    //access_token(微博令牌,根据用户名,密码生成的明文密码)  status(微博内容)
    //pic (图片) ----因为图片转成字符串编码量太大如果直接拼接在URL里服务器无法识别其请求,所以要把图片数据放在请求体里

    //本地图片
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Icon.png" ofType:nil];
    //拼接请求体
    NSData *bodyData=[self setBodydata:filePath];注意上面宏定义的请求体边界下面就要用上了
    
    //3.创建网络会话
    NSURLSession *session=[NSURLSession sharedSession];
    
    //4.创建网络上传任务
    NSURLSessionUploadTask *dataTask=[session uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error == nil) {
            
            NSLog(@"%@",response);//202及是发布成功
        };
    }];
    
    //5.发送网络任务
    [dataTask resume];


//————————————————————————————POST请求体格式——————————————————————————————

//这个格式比较繁琐,但是这是死格式,大家耐心看,就可以看出规律了。注意看红字分析

//---->拼接成字符串,然后转成 NSData 返回

/*
 HTTP请求头:
 ....
 multipart/form-data; charset=utf-8;boundary=AaB03x //上传数据类型 必须要设置其类型
 ....
 
 
 HTTP请求体:
 
 --AaB03x  (边界到下一行用了换行,在oc里面 用 \r\n 来定义换一行 所以下面不要奇怪它的用法
 Content-Disposition: form-data; name="key1"(这行到 value1 换了2行,所以,自然而然 \r\n\r\n

 value1
 --AaB03x
 Content-disposition: form-data; name="key2"

 value2
 --AaB03x
 Content-disposition: form-data; name="key3"; filename="file"
 Content-Type: application/octet-stream
 
 图片数据...//NSData
 --AaB03x--结束的分割线也不要落下
 */

- (NSData *)setBodydata:(NSString *)filePath
{
    //把文件转换为NSData
    NSData *fileData = [NSData dataWithContentsOfFile:filePath];
    
    //1.构造body string
    NSMutableString *bodyString = [[NSMutableString alloc] init];
    
    //2.拼接body string
    //(1)access_token
    [bodyString appendFormat:@"--%@\r\n", boundary];(一开始的 --也不能忽略
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n"];
    [bodyString appendFormat:@"xxxxxx\r\n"];
    
    //(2)status
    [bodyString appendFormat:@"--%@\r\n", boundary];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"status\"\r\n\r\n"];
    [bodyString appendFormat:@"带图片的微博\r\n"];
    
    //(3)pic
    [bodyString appendFormat:@"--%@\r\n", boundary];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"pic\"; filename=\"file\"\r\n"];
    [bodyString appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"];
    
    
    //3.string --> data
    NSMutableData *bodyData = [NSMutableData data];
    //拼接的过程
    //前面的bodyString, 其他参数
    [bodyData appendData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
    //图片数据
    [bodyData appendData:fileData];
    
    //4.结束的分隔线
    NSString *endStr = [NSString stringWithFormat:@"\r\n--%@--\r\n",boundary];
    //拼接到bodyData最后面
    [bodyData appendData:[endStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    return bodyData;
}

如此,带图片的微博就完成了。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。