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加載系統中需要用到的基礎類:

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

博客同步至:我的簡書博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM