IOS 網路開發NSURLSession(四)UploadTask(上傳資料+圖片)
原創blog,轉載請註明出處
blog.csdn.net/hello_hwc
前言:
UploadTask繼承自DataTask。不難理解,因為UploadTask只不過在Http請求的時候,把資料放到Http Body中。所以,用UploadTask來做的事情,通常直接用DataTask也可以實現。不過,能使用封裝好的API會省去很多事情,何樂而不為呢?
Demo下載連結
http://download.csdn.net/detail/hello_hwc/8557791
Demo裡包括了三種Task的使用,我想對想要學習NSURLSession的初學者還是有點協助的。
Demo效果
上傳資料
使用一個工具網站,想要學習RestAPI的同學可以使用這個網站的API做一些練習。
http://jsonplaceholder.typicode.com/
上傳圖片,圖片可以拍照,也可以從相簿裡選取,上傳的返回data是一個html網頁,用webview顯示。
這裡的上傳伺服器也是選擇一個共工具網站
http://www.freeimagehosting.net/upl.php
一 NSURLSessionUploadTask概述1.1NSMutableURLRequest
上傳資料的時候,一般要使用REST API裡的PUT或者POST方法。所以,要通過這個類來設定一些HTTP配置資訊。常見的包括
timeoutInterval //timeout的時間間隔HTTPMethod //HTTP方法//設定HTTP表頭資訊– addValue:forHTTPHeaderField:– setValue:forHTTPHeaderField:
HTTP header的具體資訊參見Wiki,常用的header一定要熟悉
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
1.2 三種上傳資料的方式
NSData - 如果對象已經在記憶體裡
使用以下兩個函數初始化
uploadTaskWithRequest:fromData: uploadTaskWithRequest:fromData:completionHandler:
Session會自動計算Content-length的Header
通常,還需要提供一些伺服器需要的Header,Content-Type就往往需要提供。
File-如果對象在磁碟上,這樣做有助於降低記憶體使用量。
使用以下兩個函數進行初始化
uploadTaskWithRequest:fromFile: uploadTaskWithRequest:fromFile:completionHandler:
同樣,會自動計算Content-Length,如果App沒有提供Content-Type,Session會自動建立一個。如果Server需要額外的Header資訊,也要提供。
Stream
使用這個函數建立
uploadTaskWithStreamedRequest:
注意,這種情況下一定要提供Server需要的Header資訊,例如Content-Type和Content-Length。
使用Stream一定要實現這個代理方法,因為Session沒辦法在重新嘗試發送Stream的時候找到資料來源。(例如需要授權資訊的情況)。這個代理函數,提供了Stream的資料來源。
URLSession:task:needNewBodyStream:
1 .3 代理方法
使用這個代理方法獲得upload的進度。其他的代理方法
NSURLSessionDataDelegate,NSURLSessionDelegate,NSURLSessionTaskDelegate同樣適用於UploadTask
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;
二 上傳資料
核心代碼如下
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@http://jsonplaceholder.typicode.com/posts]]; [request addValue:@application/json forHTTPHeaderField:@Content-Type];//這一行一定不能少,因為後面是轉換成JSON發送的 [request addValue:@application/json forHTTPHeaderField:@Accept]; [request setHTTPMethod:@POST]; [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; [request setTimeoutInterval:20]; NSDictionary * dataToUploaddic = @{self.keytextfield.text:self.valuetextfield.text}; NSData * data = [NSJSONSerialization dataWithJSONObject:dataToUploaddic options:NSJSONWritingPrettyPrinted error:nil]; NSURLSessionUploadTask * uploadtask = [self.session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (!error) { NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; self.responselabel.text = dictionary.description; }else{ UIAlertController * alert = [UIAlertController alertControllerWithTitle:@Error message:error.localizedFailureReason preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@OK style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; } }]; [uploadtask resume];
三 上傳圖片
核心部分代碼
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@http://www.freeimagehosting.net/upload.php]]; [request addValue:@image/jpeg forHTTPHeaderField:@Content-Type]; [request addValue:@text/html forHTTPHeaderField:@Accept]; [request setHTTPMethod:@POST]; [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; [request setTimeoutInterval:20]; NSData * imagedata = UIImageJPEGRepresentation(self.imageview.image,1.0); NSURLSessionUploadTask * uploadtask = [self.session uploadTaskWithRequest:request fromData:imagedata completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString * htmlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; UploadImageReturnViewController * resultvc = [self.storyboard instantiateViewControllerWithIdentifier:@resultvc]; resultvc.htmlString = htmlString; [self.navigationController pushViewController:resultvc animated:YES]; self.progressview.hidden = YES; [self.spinner stopAnimating]; [self.spinner removeFromSuperview]; }]; [uploadtask resume];
代理函數
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{ self.progressview.progress = totalBytesSent/(float)totalBytesExpectedToSend;}
後續:網路部分,還會更新授權,認證一篇,AFNetworking一篇,一些網路的基本概念一篇。然後,轉向更新資料存放區這一塊(CoreData以及IOS的檔案系統)。