1 概念
從iOS7開始新增的NSURLSession類來替代NSURLConnection
NSURLSession類,包含了NSURLConnection的所有功能,并增加了新的功能!
1)獲取數據(做音樂下載,視頻下載)
2)下載文件
3)上傳文件
支持后臺下載,后臺上傳的功能;
2 使用NSURLSession實現獲取數據
【Demo】-【1-NSURLSession_RequestData】
-
(IBAction)btnClick:(id)sender {
//NSURLSession實現異步請求數據
NSString *urlStr = @"http://mapi.damai.cn/proj/HotProj.aspx?CityId=0&source=10099&version=30602";//不管有沒有中文,最好是不要忘記這一步:
【防止網址中有中文的存在,而導致的問題】
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//1.構造NSURL
NSURL *url = [NSURL URLWithString:urlStr];//2.創建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.創建NSURLSession
//設置默認配置《下載的文件,默認保存在沙盒目錄中(tmp)》
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];//4.創建任務
// NSURLSessionDataTask 獲取數據
// NSURLSessionDownloadTask 下載數據
// NSURLSessionUploadTask 上傳文件
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {//請求數據,返回請求的結果 NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response; if (resp.statusCode == 200) { //請求成功 //解析數據 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",dict); }
}];
//5.啟動任務【開始發起請求】
[task resume];
}
pragma mark -NSURLSessionDownloadDelegate 協議方法,執行下載成功后的操作
//下載完畢以后,調用此方法
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
//location 下載回來的文件所在的臨時目錄
//將臨時文件保存到指定的目錄中
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/MP3/北京北京.mp3"];
if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:toPath error:nil]) {
NSLog(@"下載成功!");
NSLog(@"%@",toPath);
// self.myButton.userInteractionEnabled = NO;
}
}
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
//計算當前下載的進度
double progress = totalBytesWritten*1.0/totalBytesExpectedToWrite;
NSLog(@"%lf",progress);
//回到主線程,更新進度條的顯示 【 如何回到主線程 】
dispatch_async(dispatch_get_main_queue(), ^{
//更新進度條
[self.myProgressView setProgress:progress animated:YES];
});
}
3 使用NSURLSession實現下載文件
獲取數據和下載文件的區別:
獲取的數據是講數據下載到內存中;
下載文件是將文件下載到沙盒中;
下載文件默認將文件下載到沙盒中的tmp目錄(臨時目錄),所以,我們需要將下載到臨時目錄中的文件移動到Docusment目錄下;
見【Demo】-【2-NSURLSession-DownloadFile】
通過進度條顯示下載的進度
見【Demo】-【3-DownloadFile_progress】
4 斷點續傳
【Demo】-【4-DownloadFile_stopAndResume】
-(void)requestData
{
NSString *urlStr = @"http://10.6.154.91/share/視頻/1.mp4";
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//1.構造NSURL
NSURL *url = [NSURL URLWithString:urlStr];
//2.創建NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創建NSURLSession
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
//4.創建任務
self.task = [self.session downloadTaskWithRequest:request];
//5.啟動任務
[self.task resume];
}
//下載
-
(IBAction)downloadBtnClick:(id)sender {
self.stopBtn.enabled = YES;
if (self.isBegain)
{
//從頭下載
[self requestData];}else
{
//接著上次暫停的位置開始下載 【** 從暫停的位置接著下載的方法 **】
self.task = [self.session downloadTaskWithResumeData:self.resumeData];
[self.task resume];
self.resumeData = nil;
}
}
//暫停
-
(IBAction)stopBtnClick:(id)sender {
self.stopBtn.enabled = NO;
//暫停下載的任務 【** 暫停下載任務的方法 **】
[self.task cancelByProducingResumeData:^(NSData *resumeData) {self.resumeData = resumeData; self.isBegain = NO;
}];
}
-
(void)viewDidLoad {
[super viewDidLoad];self.isBegain = YES;
//在沙盒里創建一個目錄
if (![[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/視頻"]]) {[[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/視頻"] withIntermediateDirectories:YES attributes:nil error:nil];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
pragma mark -NSURLSessionDownloadDelegate
//下載完畢以后,調用此方法 【** 將下載內容永久的保存在本地 **】
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
//location 下載回來的文件所在的臨時目錄
//將臨時文件保存到指定的目錄中
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/視頻/1.mp4"];
[[NSFileManager defaultManager] moveItemAtPath:location.path toPath:toPath error:nil];
NSLog(@"下載成功:%@",toPath);
}
//下載過程中不斷調用該方法
-(void)URLSession:(NSURLSession )session downloadTask:(NSURLSessionDownloadTask )downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite 【 進度條進度設置 *】
{
//計算當前下載的進度
double progress = totalBytesWritten1.0/totalBytesExpectedToWrite;
【** 回到主線程的方法 **】
dispatch_async(dispatch_get_main_queue(), ^{
//回到主線程,更新進度條顯示
[self.myProgressView setProgress:progress animated:YES];
});
}
5 POST請求
GET請求和POST請求的區別:
1)GET請求會將參數直接寫在URL后面,所有的參數使用?xxxxx = XXXX&yyy=YYYY形式放在URL后面
URL的長度是有限制的,所以要發的數據較多時不建議使用get,GET請求因為參數直接暴露在URL外面,所以不夠 安全,但相對來說使用簡單,方便;
2)POST請求是將發送給服務器的所有參數全部放在請求體中,而不是URL后面,所以相對安全性更高;
如果要傳遞大量的數據,比如:文件上傳,圖片上傳;都是用POST請求;
但如果僅僅是獲取一段資源或者一段數據,而且不涉及到安全性的時候,使用GET更方便;
將【Demo】-【5-POST】
【** session用post方法申請數據 **】
-
(IBAction)sessionPost:(id)sender {
//POST
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php";
//1.構成NSURL
NSURL *url = [NSURL URLWithString:urlStr];//2.創建一個可變的請求對象
//NSMutableURLRequest是NSURLRequest的子類
//要對請求對象進行相關設置,使用NSMutableURLRequest
NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url];
//.設置請求方式POST
mRequest.HTTPMethod = @"POST";
//設置請求超時的時間
mRequest.timeoutInterval = 2;
NSString *param = @"page=1&number=10";
//.設置請求體
mRequest.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
//3.s創建session對象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//4.通過session對象創建任務
NSURLSessionDataTask *task = [session dataTaskWithRequest:mRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dict);
}];
//5.啟動任務
[task resume];
}
【** connection用post方法申請數據 **】
-
(IBAction)connectionPost:(id)sender {
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php";
//1.構成NSURL
NSURL *url = [NSURL URLWithString:urlStr];
//2.創建可變的請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//設置請求的類型
request.HTTPMethod = @"POST";
//設置超時時間
request.timeoutInterval = 5;
//設置請求體
NSString *str = @"page=2&number=20";
request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding];//3.連接服務器
[NSURLConnection connectionWithRequest:request delegate:self];
}
pragma mark -NSURLConnectionDataDelegate
//1.服務器收到客戶端的請求時調用該方法
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.downloadData = [[NSMutableData alloc] init];
}
//2.客戶端收到了服務器傳輸的數據
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.downloadData appendData:data];
}
//3.數據傳輸完畢
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//解析數據
if (self.downloadData) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.downloadData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dict);
NSLog(@"請求成功");
}
}
//4.請求失敗
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"請求失敗");
}