day2---NSURLSession

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 = totalBytesWritten
1.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(@"請求失敗");
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容