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;
}

如此,帶圖片的微博就完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章