NSURLSession(三)POST請求—>上傳圖片,nsurlsessionpost
這個例子,還是以新浪微博為例。
首先在宏定義出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;
}
如此,帶圖片的微博就完成了。