OC的NSURLSession

  上一次的WWCD大會發布,說明了要廢棄NSURLConnection,估計不少人蛋疼了。在Xcode7中已經不能使用NSURLConnection了,這樣也致使了不少第三方框架不能在Xcode7中使用。NSURLSession的崛起已成爲了必然!php

  爲了適應IT這個行業必須不斷更新知識,不斷充實本身,因此我認真的學習了一下NSURLSession。程序員

  NSURLSession的簡介(IOS 7.0之後出現):NSURLSession是一組相互依賴的類,它的大部分組件和NSURLConnection中的組件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一樣之處在於,它將NSURLConnection替換爲NSURLSession和NSURLSessionConfiguration,以及3個NSURLSessionTask的子類:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。

1.支持後臺運行網絡任務json

2.暫停、中止、重啓網絡任務,再也不須要 NSOperation 封裝緩存

3.請求可使用一樣的配置容器服務器

4.不一樣的 session 可使用不一樣的私有存儲cookie

5.block 和代理能夠同時起做用網絡

6.直接從文件系統上傳、下載session

注意:爲了方便程序員使用,蘋果提供了一個全局 session併發

全部的 任務(Task) 都是由 Session 發起的app

全部的任務默認是掛起的,須要 Resume,不少時候不少人在使用的時候都會忘記寫resume。

session 的回調是異步的

  NSURLSession的成員變量NSURLSessionConfiguration:

NSURLSessionConfiguration 用於設置全局的網絡會話屬性,包括:身份驗證,超時時長,緩存策略,Cookie 等,能夠代替NSURLRequest。

NSURLSessionConfiguration 有三個類構造方法是爲不一樣的用例設計的

1.+ (NSURLSessionConfiguration *)defaultSessionConfiguration- 返回標準配置,具備共享 NSHTTPCookieStorage(cookie倉庫)NSURLCache(路徑緩存) 和 NSURLCredentialStorage(證書倉庫)。

2.+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration- 返回一個預設配置,沒有持久性存儲的緩存,Cookie或證書。這對於實現像祕密瀏覽功能的功能來講,是很理想的

3.+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0)-獨特之處在於,會建立一個後臺會話。後臺會話不一樣於常規的,普通的會話,它甚至能夠在應用程序掛起,退出,崩潰的狀況下運行上傳和下載任務。初始化時指定的標識符,被用於向任何可能在進程外恢復後臺傳輸的守護進程提供上下文

NSURLSessionConfiguration的經常使用屬性

//Hosts是一個系統文件,記錄了一些網站的IP地址和域名的對應關係

//Cookie就是服務器暫存放在你計算機上的一筆資料,好讓服務器用來辨認你的計算機\

NSURLSessionConfiguration-->HTTPShouldSetCookies是否應該設置cookie HTTPCookieAcceptPolicy設置cookie的選擇

屬性 描述
HTTPAdditionalHeaders HTTP 頭字段
timeoutIntervalForRequest 超時時長
timeoutIntervalForResource 整個資源請求時長
requestCachePolicy 緩存策略
allowsCellularAccess 容許蜂窩訪問
HTTPMaximumConnectionsPerHost 對於一個host的最大併發鏈接數,默認數值是 4,MAC 下的默認數值是 6

NSURLSession注意事項

一旦指定了 session 的代理,session會對代理進行強引用,若是不主動取消 session,會形成內存泄漏!

解決方案

解決方法1:在任務完成後取消 session

缺點:session一旦被取消就沒法再次使用

解決方法2:在視圖將要消失的時候取消 session

優勢:只須要一個全局的session統一管理

 

  NSURLSession支持的三種任務:

 

NSURLSession類支持三種類型的任務:加載數據(NSURLSessionDataTask),下載(NSURLSessionDownloadTask)和上傳(NSURLSessionUploadTask)。

 

  加載數據代碼演示:

- (void)sessionDemo1 {
    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/demo.json"];

    // 2. session
    NSURLSession *session = [NSURLSession sharedSession];

    // 3. 數據任務
    NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        NSLog(@"%@ %@ %@", result, response, [NSThread currentThread]);
    }];

    // 4. 繼續任務
    [task resume];
}

  

    下載文件數據代碼簡單演示:

注意:塊代碼回調結束後,下載的文件會被刪除

- (void)download {

    NSLog(@"開始");

    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://localhost/321.zip"];

    // 2. 下載
    [[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        NSLog(@"%@ %@", location, [NSThread currentThread]);
    }] resume];
}

 

 

    上傳文件數據代碼演示:

上傳文件

#define boundary @"itcast-upload"

- (void)uploadFile:(NSString *)fieldName dataDict:(NSDictionary *)dataDict params:(NSDictionary *)params {
    // 1. url - 負責上傳文件的腳本
    NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload-m.php"];

    // 2. request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";

    NSString *typeValue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:typeValue forHTTPHeaderField:@"Content-Type"];

    NSData *data = [self formData:fieldName dataDict:dataDict params:params];

    // 3. 上傳
    [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        NSLog(@"%@ %@", response, [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]);
    }] resume];
}

拼接數據體

///  生成 formData 二進制數據
///
///  @param fieldName 服務器字段名
///  @param dataDict  上傳文件數據字典 "保存在服務器文件名": 二進制數據
///  @param params    提交參數字典
///
///  @return formData 二進制數據
- (NSData *)formData:(NSString *)fieldName dataDict:(NSDictionary *)dataDict params:(NSDictionary *)params {

    NSMutableData *dataM = [NSMutableData data];

    // 1. 生成文件數據
    [dataDict enumerateKeysAndObjectsUsingBlock:^(NSString *fileName, NSData *fileData, BOOL *stop) {
        NSMutableString *strM = [NSMutableString string];

        [strM appendFormat:@"--%@\r\n", boundary];
        [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, fileName];
        [strM appendString:@"Content-Type: application/octet-stream\r\n\r\n"];

        [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
        [dataM appendData:fileData];

        [dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }];

    // 2. 生成參數數據
    [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {

        NSMutableString *strM = [NSMutableString string];

        [strM appendFormat:@"--%@\r\n", boundary];
        [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [strM appendString:value];
        [strM appendString:@"\r\n"];

        [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
    }];

    // 3. 結尾字符串
    NSString *tail = [NSString stringWithFormat:@"--%@--", boundary];
    [dataM appendData:[tail dataUsingEncoding:NSUTF8StringEncoding]];

    return dataM.copy;
}

 

開始上傳

- (void)uploadFileDemo {
    // 1. 上傳文件數據
    NSURL *fileURL1 = [[NSBundle mainBundle] URLForResource:@"001.png" withExtension:nil];
    NSData *data1 = [NSData dataWithContentsOfURL:fileURL1];

    NSURL *fileURL2 = [[NSBundle mainBundle] URLForResource:@"demo.jpg" withExtension:nil];
    NSData *data2 = [NSData dataWithContentsOfURL:fileURL2];

    // 如何傳遞參數 - 用字典傳遞參數
    NSDictionary *dataDict = @{@"001.png": data1, @"002.jpg": data2};

    // 2. 字符串參數
    NSDictionary *params = @{@"status": @"how are you"};

    // 3. 上傳文件而且提交參數
    [self uploadFile:@"userfile[]" dataDict:dataDict params:params];
}
相關文章
相關標籤/搜索