1 概念
從iOS7開(kāi)始新增的NSURLSession類來(lái)替代NSURLConnection
NSURLSession類,包含了NSURLConnection的所有功能陌粹,并增加了新的功能撒犀!
1)獲取數(shù)據(jù)(做音樂(lè)下載,視頻下載)
2)下載文件
3)上傳文件
支持后臺(tái)下載掏秩,后臺(tái)上傳的功能或舞;
2 使用NSURLSession實(shí)現(xiàn)獲取數(shù)據(jù)
【Demo】-【1-NSURLSession_RequestData】
-
(IBAction)btnClick:(id)sender {
//NSURLSession實(shí)現(xiàn)異步請(qǐng)求數(shù)據(jù)
NSString *urlStr = @"http://mapi.damai.cn/proj/HotProj.aspx?CityId=0&source=10099&version=30602";//不管有沒(méi)有中文,最好是不要忘記這一步:
【防止網(wǎng)址中有中文的存在蒙幻,而導(dǎo)致的問(wèn)題】
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//1.構(gòu)造NSURL
NSURL *url = [NSURL URLWithString:urlStr];//2.創(chuàng)建請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.創(chuàng)建NSURLSession
//設(shè)置默認(rèn)配置《下載的文件映凳,默認(rèn)保存在沙盒目錄中(tmp)》
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];//4.創(chuàng)建任務(wù)
// NSURLSessionDataTask 獲取數(shù)據(jù)
// NSURLSessionDownloadTask 下載數(shù)據(jù)
// NSURLSessionUploadTask 上傳文件
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {//請(qǐng)求數(shù)據(jù),返回請(qǐng)求的結(jié)果 NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response; if (resp.statusCode == 200) { //請(qǐng)求成功 //解析數(shù)據(jù) NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",dict); }
}];
//5.啟動(dòng)任務(wù)【開(kāi)始發(fā)起請(qǐng)求】
[task resume];
}
pragma mark -NSURLSessionDownloadDelegate 協(xié)議方法杆煞,執(zhí)行下載成功后的操作
//下載完畢以后魏宽,調(diào)用此方法
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
//location 下載回來(lái)的文件所在的臨時(shí)目錄
//將臨時(shí)文件保存到指定的目錄中
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
{
//計(jì)算當(dāng)前下載的進(jìn)度
double progress = totalBytesWritten*1.0/totalBytesExpectedToWrite;
NSLog(@"%lf",progress);
//回到主線程,更新進(jìn)度條的顯示 【 如何回到主線程 】
dispatch_async(dispatch_get_main_queue(), ^{
//更新進(jìn)度條
[self.myProgressView setProgress:progress animated:YES];
});
}
3 使用NSURLSession實(shí)現(xiàn)下載文件
獲取數(shù)據(jù)和下載文件的區(qū)別:
獲取的數(shù)據(jù)是講數(shù)據(jù)下載到內(nèi)存中队询;
下載文件是將文件下載到沙盒中派桩;
下載文件默認(rèn)將文件下載到沙盒中的tmp目錄(臨時(shí)目錄),所以蚌斩,我們需要將下載到臨時(shí)目錄中的文件移動(dòng)到Docusment目錄下铆惑;
見(jiàn)【Demo】-【2-NSURLSession-DownloadFile】
通過(guò)進(jìn)度條顯示下載的進(jìn)度
見(jiàn)【Demo】-【3-DownloadFile_progress】
4 斷點(diǎn)續(xù)傳
【Demo】-【4-DownloadFile_stopAndResume】
-(void)requestData
{
NSString *urlStr = @"http://10.6.154.91/share/視頻/1.mp4";
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//1.構(gòu)造NSURL
NSURL *url = [NSURL URLWithString:urlStr];
//2.創(chuàng)建NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建NSURLSession
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
//4.創(chuàng)建任務(wù)
self.task = [self.session downloadTaskWithRequest:request];
//5.啟動(dòng)任務(wù)
[self.task resume];
}
//下載
-
(IBAction)downloadBtnClick:(id)sender {
self.stopBtn.enabled = YES;
if (self.isBegain)
{
//從頭下載
[self requestData];}else
{
//接著上次暫停的位置開(kāi)始下載 【** 從暫停的位置接著下載的方法 **】
self.task = [self.session downloadTaskWithResumeData:self.resumeData];
[self.task resume];
self.resumeData = nil;
}
}
//暫停
-
(IBAction)stopBtnClick:(id)sender {
self.stopBtn.enabled = NO;
//暫停下載的任務(wù) 【** 暫停下載任務(wù)的方法 **】
[self.task cancelByProducingResumeData:^(NSData *resumeData) {self.resumeData = resumeData; self.isBegain = NO;
}];
}
-
(void)viewDidLoad {
[super viewDidLoad];self.isBegain = YES;
//在沙盒里創(chuàng)建一個(gè)目錄
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
//下載完畢以后,調(diào)用此方法 【** 將下載內(nèi)容永久的保存在本地 **】
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
//location 下載回來(lái)的文件所在的臨時(shí)目錄
//將臨時(shí)文件保存到指定的目錄中
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/視頻/1.mp4"];
[[NSFileManager defaultManager] moveItemAtPath:location.path toPath:toPath error:nil];
NSLog(@"下載成功:%@",toPath);
}
//下載過(guò)程中不斷調(diào)用該方法
-(void)URLSession:(NSURLSession )session downloadTask:(NSURLSessionDownloadTask )downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite 【 進(jìn)度條進(jìn)度設(shè)置 *】
{
//計(jì)算當(dāng)前下載的進(jìn)度
double progress = totalBytesWritten1.0/totalBytesExpectedToWrite;
【** 回到主線程的方法 **】
dispatch_async(dispatch_get_main_queue(), ^{
//回到主線程送膳,更新進(jìn)度條顯示
[self.myProgressView setProgress:progress animated:YES];
});
}
5 POST請(qǐng)求
GET請(qǐng)求和POST請(qǐng)求的區(qū)別:
1)GET請(qǐng)求會(huì)將參數(shù)直接寫(xiě)在URL后面员魏,所有的參數(shù)使用?xxxxx = XXXX&yyy=YYYY形式放在URL后面
URL的長(zhǎng)度是有限制的叠聋,所以要發(fā)的數(shù)據(jù)較多時(shí)不建議使用get撕阎,GET請(qǐng)求因?yàn)閰?shù)直接暴露在URL外面,所以不夠 安全碌补,但相對(duì)來(lái)說(shuō)使用簡(jiǎn)單虏束,方便;
2)POST請(qǐng)求是將發(fā)送給服務(wù)器的所有參數(shù)全部放在請(qǐng)求體中厦章,而不是URL后面镇匀,所以相對(duì)安全性更高;
如果要傳遞大量的數(shù)據(jù)袜啃,比如:文件上傳汗侵,圖片上傳;都是用POST請(qǐng)求群发;
但如果僅僅是獲取一段資源或者一段數(shù)據(jù)晰韵,而且不涉及到安全性的時(shí)候,使用GET更方便也物;
將【Demo】-【5-POST】
【** session用post方法申請(qǐng)數(shù)據(jù) **】
-
(IBAction)sessionPost:(id)sender {
//POST
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php";
//1.構(gòu)成NSURL
NSURL *url = [NSURL URLWithString:urlStr];//2.創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
//NSMutableURLRequest是NSURLRequest的子類
//要對(duì)請(qǐng)求對(duì)象進(jìn)行相關(guān)設(shè)置宫屠,使用NSMutableURLRequest
NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url];
//.設(shè)置請(qǐng)求方式POST
mRequest.HTTPMethod = @"POST";
//設(shè)置請(qǐng)求超時(shí)的時(shí)間
mRequest.timeoutInterval = 2;
NSString *param = @"page=1&number=10";
//.設(shè)置請(qǐng)求體
mRequest.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
//3.s創(chuàng)建session對(duì)象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//4.通過(guò)session對(duì)象創(chuàng)建任務(wù)
NSURLSessionDataTask *task = [session dataTaskWithRequest:mRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dict);
}];
//5.啟動(dòng)任務(wù)
[task resume];
}
【** connection用post方法申請(qǐng)數(shù)據(jù) **】
-
(IBAction)connectionPost:(id)sender {
NSString *urlStr = @"http://10.0.8.8/sns/my/user_list.php";
//1.構(gòu)成NSURL
NSURL *url = [NSURL URLWithString:urlStr];
//2.創(chuàng)建可變的請(qǐng)求對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//設(shè)置請(qǐng)求的類型
request.HTTPMethod = @"POST";
//設(shè)置超時(shí)時(shí)間
request.timeoutInterval = 5;
//設(shè)置請(qǐng)求體
NSString *str = @"page=2&number=20";
request.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding];//3.連接服務(wù)器
[NSURLConnection connectionWithRequest:request delegate:self];
}
pragma mark -NSURLConnectionDataDelegate
//1.服務(wù)器收到客戶端的請(qǐng)求時(shí)調(diào)用該方法
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.downloadData = [[NSMutableData alloc] init];
}
//2.客戶端收到了服務(wù)器傳輸?shù)臄?shù)據(jù)
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.downloadData appendData:data];
}
//3.數(shù)據(jù)傳輸完畢
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//解析數(shù)據(jù)
if (self.downloadData) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.downloadData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@",dict);
NSLog(@"請(qǐng)求成功");
}
}
//4.請(qǐng)求失敗
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"請(qǐng)求失敗");
}