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

博客同步至:个人简书博客

相关文章
相关标签/搜索