原創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的初學者還是有點幫助的。
上傳數據
使用一個工具網站,想要學習RestAPI的同學可以使用這個網站的API做一些練習。
http://jsonplaceholder.typicode.com/
上傳圖片,圖片可以拍照,也可以從相冊裡選取,上傳的返回data是一個html網頁,用webview顯示。
這裡的上傳服務器也是選擇一個共工具網站
http://www.freeimagehosting.net/upl.php
上傳數據的時候,一般要使用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
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:
使用這個代理方法獲得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的文件系統)。