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協議。html

基礎知識

URL加載系統中須要用到的基礎類:瀏覽器

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方法用的比較多,關於下載文件代碼完成以後會保存一個下載以後的臨時路徑:session

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

NSURLSessionUploadTask上傳一個本地URL的NSData數據:app

    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:ide

    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狀態同時對應着多個鏈接,不能使用共享的一個全局狀態,會話是經過工廠方法來建立配置對象。url

defaultSessionConfiguration(默認的,進程內會話),ephemeralSessionConfiguration(短暫的,進程內會話),backgroundSessionConfigurationWithIdentifier(後臺會話)spa

第三種設置爲後臺會話的,當任務完成以後會調用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

博客同步至:個人簡書博客

相關文章
相關標籤/搜索