NSURLSession詳解

    <1> NSURLSession 簡介:
    {
        NSURLSession
iOS 7.0 以後推出的網絡解決方案!用於替代 NSURLConnection,  針對下載/上傳等複雜的網絡操做提供了專門的解決方案!
   
        NSURLSession
使用更加簡單/方便!
   
    }
    <
2> NSURLSession 中新增的內容:
    {
       
1> 全局的 NSURLSession 對象: 全部的網絡會話都由一個 NSURLSession 對象發起, 實例化一個 NSURLSession 對象有兩種方法:
            {
                *
1 對於簡單的,不須要監聽網絡請求過程的網絡會話來講,使用系統提供的,全局的 NSURLSession 單利對象:
           
                NSURLSession *session = [NSURLSession sharedSession];
           
                *
2 若是須要監聽網絡進度,須要自定義一個 NSURLSession 對象,而且設置代理!這時還須要一個 NSURLSessionConfiguration,能夠設置全局的網絡訪問屬性.
           
                NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
           
                NSURLSession *session = [NSURLSession sessionWithConfiguration:cfg delegate:
self delegateQueue:[NSOperationQueue mainQueue]];
            }
       
2> 網絡任務(Task); NSURLSession ,有三種網絡任務類型.
            {
                *
1 用於非文件下載的普通的 GET/POST請求 NSURLSessionDataTask.實例化對象有如下2種方法:
                {
                   
// 1> 經過一個 request 實例化普通網絡任務,增長完成以後的 block 回調,使用比較多.
                    NSURLSessionDataTask *task = [
self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                       
                    }];
               
                   
// 2> 經過一個 url 實例化普通網絡任務,增長完成以後的 block 回調,使用比較多.
                    NSURLSessionDataTask *task = [
self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                   
                    }];
                }
                *
2 用於文件下載的網絡任務 NSURLSessionDownloadTask (不管文件大小,下載都使用 NSURLSessionDownloadTask) ,實例化對象有如下三種方法:
                {
                   
// 1> 經過一個 request 實例化下載網絡任務,增長任務完成以後的 block 回調,通常用在小文件下載.

                    NSURLSessionDownloadTask *task = [
self.session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
                       
                    }];

                   
// 2> 經過一個 url 實例化下載網絡任務,增長任務完成以後的 block 回調,通常用在小文件下載.
                    NSURLSessionDownloadTask *task = [
self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
                       
                    }];
               
                   
// 3> 經過以前下載的數據 ResumeData ,實例化一個下載任務,用於斷點續傳.
                    NSURLSessionDownloadTask *task = [session downloadTaskWithResumeData:ResumeData completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
                       
                    }];
                }
                *
3 用於文件上傳的網絡任務 NSURLSessionUploadTask.
                {
                   
// 目前,只有經過這種方式實例化的下載任務,才能實現文件上傳.依然須要拼接數據.
               
                    NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:fromData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                       
//
                    }]
                }
            }
    }
    <
3> NSURLSession 的使用分爲三步:
    {
       
1> 實例化一個 NSURLSession 對象 session ;
        NSURLSession *session = [NSURLSession sharedSession];

       
2> 經過 NSURLSession 對象,實例化對應的網絡任務 task;
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request];

       
3> 開啓網絡任務
        [task resume];
    }
}
/*------------------------------------  02 NSURLSession 下載的斷點續傳 ---------------------------*/
1.使用 NSURLSession 實現下載任務. php

2.實時監聽下載進度,使用斷點續傳.
{
   
利用 NSURLSession 實現文件下載,首先須要建立一個 NSURLSessionDownloadTask; 因爲須要實時監聽下載進度,因此,須要實現 <NSURLSessionDownloadDelegate>方法,這樣,就須要自定義一個會話 session.而且制定代理.
   
   
// NSURLSession 下載的斷點續傳實現步驟:
   
   
1. 懶加載全局網絡會話
    {
        -(NSURLSession *)session
        {
           
if (!_session) {
               
                NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
               
                _session = [NSURLSession sessionWithConfiguration:config delegate:
self delegateQueue:nil];
               
            }
           
return _session;
        }
    }
   
2. 利用全局網絡會話,建立下載 task, 開始下載任務
    {
       
self.task = [self.session downloadTaskWithURL:url];
       
        [
self.task resume];
    }
   
3. 在代理方法中,實時監聽下載進度
    {
       
// 監聽下載進度的方法
       
// bytesWritten :本次下載的字節數
       
// totalBytesWritten :已經下載的字節數
       
// totalBytesExpectedToWrite :下載文件的總字節數
        -(
void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
        {
           
            NSLog(
@"代理回調~");
           
           
float progress = (float)totalBytesWritten/totalBytesExpectedToWrite;
           
            dispatch_async(dispatch_get_main_queue(), ^{
               
               
self.progress.progress = progress;
               
            });
           
        }
       
       
// 完成下載的時候調用
        -(
void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
        {
            NSLog(
@"下載完成%@",location);
        }
       
       
// 斷點續傳的代理方法,暫時什麼都不寫
        -(
void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
        {
            NSLog(
@"%s",__FUNCTION__);
        }
    }
   
4. 當點擊暫停以後,應該取消下載任務,記錄當前下載的文件數據,而且將 task 任務設爲 nil
    {
        [
self.task cancelByProducingResumeData:^(NSData *resumeData) {
           
           
self.reusemData = resumeData;
           
           
self.task = nil;
        }];
    }
   
5. 當點擊繼續以後,應該從上次下載的進度繼續下載,這時,從新建立下載 task, 而且是根據上次記錄的文件下載數據來實例化下載任務
    {
       
if (!self.reusemData) {
           
return;
        }
       
       
self.task = [self.session downloadTaskWithResumeData:self.reusemData];
       
       
self.reusemData = nil;
       
        [
self.task resume];
    }
   
}
/*------------------------------------- 03 NSURLSession 實現上傳文件 -----------------------------*/
1.使用 NSURLSession 實現文件上傳.
{
    NSURLSession
上傳文件和 NSURLConnection 同樣須要按格式拼接文件數據.重要的是要學會封裝方法,具體使用以下:
    {
       
// NSURLSession 作文件上傳
        - (
void)uploadMfileSession
        {
           
// 1.實例化全局網絡會話
            NSURLSession *session = [NSURLSession sharedSession];
           
           
// 2.建立網絡請求
            {
                NSURL *url = [NSURL URLWithString:
@"http://localhost/upload/upload-m.php"];
               
                NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
               
// 設置請求方法
                request.HTTPMethod =
@"POST";
               
// 告訴服務器,須要作文件上傳
                NSString *contentType = [NSString stringWithFormat:
@"multipart/form-data; boundary=%@",kBOUNDARY];
               
                [request setValue:contentType forHTTPHeaderField:
@"Content-Type"];
            }
           
           
// 3. 將須要上傳至服務器的文件包裝在字典中.
            {
               
// 須要上傳的文件路徑
                NSString *file1 =
@"/Users/likaining/Desktop/meinv.jpg";
                NSString *file2 =
@"/Users/likaining/Downloads/XMLdemo.xml";
               
               
// 文件在服務器中保存的名稱
                NSString *fileName1 =
@"meinv";
                NSString *fileName2 =
@"demo";
               
               
// 將上傳數據包裝在字典中
                NSMutableDictionary *fileDict = [NSMutableDictionary dictionary];

                [fileDict setObject:file1 forKey:fileName1];
                [fileDict setObject:file2 forKey:fileName2];
            }
           
// 4. 將須要上傳的非文件數據也包裝在字典中
            {
                NSMutableDictionary *parameter = [NSMutableDictionary dictionary];
                [parameter setObject:
@"likaining" forKey:@"username"];
            }
           
// 5. 將須要上傳的數據,按照上傳的數據格式化數據.而且轉爲二進制數據.
            NSData *dataM = [
self formDataWithfileName:@"userfile[]" fileDict:fileDict parameter:parameter];
           
           
// 6. 利用網絡會話,創建上傳任務
            NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:dataM completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
               
//
                NSLog(
@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
               
                NSLog(
@"response: %@",response);
               
            }];
           
           
// 7 .開始上傳.
            [task resume];
        }
       
       
// 格式化上傳數據的方法封裝.
        - (NSData *) formDataWithfileName:(NSString *)fileName fileDict:(NSDictionary *)fileDict parameter:(NSDictionary *)parameter
        {
           
            NSMutableData *data = [NSMutableData data];
           
           
// key : 服務器保存的文件名
           
// obj : 上傳的文件地址
            [fileDict enumerateKeysAndObjectsUsingBlock:^(
id key, id obj, BOOL *stop) {
               
//
                NSMutableString *headerStrM = [NSMutableString stringWithFormat:
@"\r\n--%@\r\n",kBOUNDARY];
                [headerStrM appendFormat:
@"Content-Disposition: form-data; name=%@; filename=%@\r\n",fileName,key];
               
                NSString *contentType = [
self getContentTypeFromFile:obj];
               
                [headerStrM appendFormat:
@"Content-Type: %@\r\n\r\n",contentType];
               
                NSData *headerData = [headerStrM dataUsingEncoding:NSUTF8StringEncoding];
               
                NSData *fileData = [NSData dataWithContentsOfFile:obj];
               
               
                [data appendData:headerData];
                [data appendData:fileData];
               
            }];
           
           
// key :username 服務器接收的 key
           
// obj :上傳文件的人
            [parameter enumerateKeysAndObjectsUsingBlock:^(
id key, id obj, BOOL *stop) {
               
//
                NSMutableString *headerM = [NSMutableString stringWithFormat:
@"\r\n--%@\r\n",kBOUNDARY];
                [headerM appendFormat:
@"Content-Disposition: form-data; name=%@\r\n\r\n",key];
               
                NSString *username = obj;
               
                NSData *headerData = [headerM dataUsingEncoding:NSUTF8StringEncoding];
               
                NSData *userData = [username dataUsingEncoding:NSUTF8StringEncoding];
               
                [data appendData:headerData];
                [data appendData:userData];
               
            }];
           
            NSMutableString *footerStrM = [NSMutableString stringWithFormat:
@"\r\n--%@--\r\n",kBOUNDARY];
           
            NSData *footerData = [footerStrM dataUsingEncoding:NSUTF8StringEncoding];
           
            [data appendData:footerData];
           
           
return data;
        }
    }
   
}
/*------------------------------------- 04 文件的複製和剪切 ---------------------------------------*/
文件操做中的複製和剪切.
{
   
文件下載到本地以後,有時候須要對文件進行移動操做,這樣就須要掌握掌握文件的複製和剪切操做.
   
   
1.文件的拷貝
   
// 新建一個文件路徑
    NSString *path =
@"/Users/likaining/Desktop/abc/";
   
   
// 從一個文件路徑拷貝文件到另外一個文件路徑
   
// AtPath : 拷貝前的文件路徑
   
// ToPath : 拷貝後的文件路徑
    [[NSFileManager defaultManager] copyItemAtPath:location.path toPath:path error:
0];
   
   
   
2.文件的剪切
   
// response.suggestedFilename:建議使用的文件名,通常跟服務器端的文件名一致
    NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
   
   
// 將臨時文件剪切到Caches文件夾
   
// AtPath : 剪切前的文件路徑
   
// ToPath : 剪切後的文件路徑
    [[NSFileManager defaultManager] moveItemAtPath:location.path toPath:file error:
nil];
   
}
/*------------------------------------- 05 文件的解壓縮 ------------------------------------------*/
文件的解壓縮操做,使用解壓縮框架.
{
   
爲了方便網絡傳輸,文件常常被壓縮以後再進行網絡傳輸,這個時候,須要學會解壓縮文件.
   
   
1.文件的解壓縮須要導入第三方框架: SSZipArchive ,須要注意的是,這個框架依賴一個動態度 libz.dylib.
   
   
2. 壓縮文件:
   
// 1.得到須要壓縮的文件夾
    NSString *images = [caches stringByAppendingPathComponent:
@"images"];
   
   
// 1.建立一個zip文件(壓縮)
    NSString *zipFile = [caches stringByAppendingPathComponent:
@"images.zip"];
   
   
BOOL result = [SSZipArchive createZipFileAtPath:zipFile withContentsOfDirectory:images];
   
   
3. 解壓縮文件:
   
// location.path:須要解壓縮的文件
   
// 文件解壓縮以後存放的路徑(注意,只須要給出一個文件路徑就能夠,由於極可能解壓縮以後,生成不少個文件).
    [SSZipArchive unzipFileAtPath:location.path toDestination:path];

}
web

相關文章
相關標籤/搜索