天天看點

iOS開發-NSURLSession詳解

Core Foundation中NSURLConnection在2003年伴随着Safari浏覽器的發行,誕生的時間比較久遠,iOS更新比較快,AFNetWorking在3.0版本删除了所有基于NSURLConnection API的所有支援,新的API完全基于NSURLSession。AFNetworking 1.0建立在NSURLConnection的基礎之上 ,AFNetworking 2.0使用NSURLConnection基礎API,以及較新基于NSURLSession的API的選項。NSURLSession用于請求資料,作為URL加載系統,支援http,https,ftp,file,data協定。

基礎知識

URL加載系統中需要用到的基礎類:

iOS開發-NSURLSession詳解

iOS7和Mac OS X 10.9之後通過NSURLSession加載資料,調用起來也很友善: 

NSURL *url=[NSURL URLWithString:@"http://www.cnblogs.com/xiaofeixiang"];
    NSURLRequest *urlRequest=[NSURLRequest requestWithURL:url];
    NSURLSession *urlSession=[NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask=[urlSession dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSDictionary *content = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@",content);
    }];
    [dataTask resume];
      

NSURLSessionTask是一個抽象子類,它有三個具體的子類是可以直接使用的:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。這三個類封裝了現代應用程式的三個基本網絡任務:擷取資料,比如JSON或XML,以及上傳下載下傳檔案。dataTaskWithRequest方法用的比較多,關于下載下傳檔案代碼完成之後會儲存一個下載下傳之後的臨時路徑:

NSURLSessionDownloadTask *downloadTask=[urlSession downloadTaskWithRequest:urlRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
    }];
      

NSURLSessionUploadTask上傳一個本地URL的NSData資料:

NSURLSessionUploadTask *uploadTask=[urlSession uploadTaskWithRequest:urlRequest fromData:[NSData new] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
    }];
      

NSURLSession在Foundation中我們預設使用的block進行異步的進行任務處理,當然我們也可以通過delegate的方式在委托方法中異步處理任務,關于委托常用的兩種NSURLSessionTaskDelegate和NSURLSessionDownloadDelegate,其他的關于NSURLSession的委托有興趣的可以看一下API文檔,首先我們需要設定delegate:

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *inProcessSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
    NSString *url = @"http://www.cnblogs.com/xiaofeixiang";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLSessionTask *dataTask = [inProcessSession dataTaskWithRequest:request];
    [dataTask resume];
      

任務下載下傳的設定delegate:

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *inProcessSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
    NSString *url = @"http://www.cnblogs.com/xiaofeixiang";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLSessionDownloadTask *downloadTask = [inProcessSession downloadTaskWithRequest:request];
    [downloadTask resume];
      

關于delegate中的方式隻實作其中的兩種作為參考:

#pragma mark - NSURLSessionDownloadDelegate
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    NSLog(@"NSURLSessionTaskDelegate--下載下傳完成");
}

#pragma mark - NSURLSessionTaskDelegate
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
     NSLog(@"NSURLSessionTaskDelegate--任務結束");
}
      

NSURLSession狀态同時對應着多個連接配接,不能使用共享的一個全局狀态,會話是通過工廠方法來建立配置對象。

defaultSessionConfiguration(預設的,程序内會話),ephemeralSessionConfiguration(短暫的,程序内會話),backgroundSessionConfigurationWithIdentifier(背景會話)

第三種設定為背景會話的,當任務完成之後會調用application中的方法:

-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
    
}
      

網絡封裝

上面的基礎知識能滿足正常的開發,我們可以對常見的資料get請求,Url編碼處理,動态添加參數進行封裝,其中關于url中文字元串的處理

stringByAddingPercentEncodingWithAllowedCharacters屬于新的方式,字元允許集合選擇的是URLQueryAllowedCharacterSet,

NSCharacterSet中分類有很多,詳細的可以根據需求進行過濾~

typedef void (^CompletioBlock)(NSDictionary *dict, NSURLResponse *response, NSError *error);

@interface FENetWork : NSObject

+(void)requesetWithUrl:(NSString *)url completeBlock:(CompletioBlock)block;

+(void)requesetWithUrl:(NSString *)url params:(NSDictionary *)params completeBlock:(CompletioBlock)block;

@end
      
@implementation FENetWork

+(void)requesetWithUrl:(NSString *)url completeBlock:(CompletioBlock)block{
    NSString *urlEnCode=[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURLRequest *urlRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlEnCode]];
    NSURLSession *urlSession=[NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask=[urlSession dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@",error);
            block(nil,response,error);
        }else{
            NSDictionary *content = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            block(content,response,error);
        }
    }];
    [dataTask resume];
}

+(void)requesetWithUrl:(NSString *)url params:(NSDictionary *)params completeBlock:(CompletioBlock)block{
    
    NSMutableString *mutableUrl=[[NSMutableString alloc]initWithString:url];
    if ([params allKeys]) {
        [mutableUrl appendString:@"?"];
        for (id key in params) {
            NSString *value=[[params objectForKey:key] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
            [mutableUrl appendString:[NSString stringWithFormat:@"%@=%@&",key,value]];
        }
    }
    [self requesetWithUrl:[mutableUrl substringToIndex:mutableUrl.length-1] completeBlock:block];
}

@end      

參考資料:https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCharacterSet_Class/index.html#//apple_ref/occ/clm/NSCharacterSet/URLQueryAllowedCharacterSet

部落格同步至:我的簡書部落格

作者:FlyElephant

出處:http://www.cnblogs.com/xiaofeixiang

說明:部落格經個人辛苦努力所得,如有轉載會特别申明,部落格不求技驚四座,但求與有緣人分享個人學習知識,生活學習提高之用,部落格所有權歸本人和部落格園所有,如有轉載請在顯著位置給出博文連結和作者姓名,否則本人将付諸法律。

iOS