IOS开发系列——NSUrlSession专题

作者: Kevin_Junbaozi | 来源:发表于2017-04-19 20:15 被阅读1024次

    NSUrlSession专题

    1概述

    【主要参考】NSURLSession

    http://blog.csdn.net/qq_29846663/article/details/68961167

    NSURLSession在2013年随着iOS7的发布一起面世,苹果对它的定位是作为NSURLConnection的替代者,然后逐步将NSURLConnection退出历史舞台。现在使用最广泛的第三方网络框架:AFNetworking、SDWebImage等等都使用了NSURLSession。

    在WWDC 2013中,Apple的团队对NSURLConnection进行了重构,并推出了NSURLSession作为替代。NSURLSession将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask,NSURLSessionUploadTask,和NSURLSessionDownloadTask。

    它们之间的关系如下图:

    NSURLSessionTask及三个子类继承关系:

    NSURLSessionDataTask:主要用于读取服务端的简单数据,比如JSON数据。

    NSURLSessionDownloadTask:这个task的主要用途是进行文件下载,它针对大文件的网络请求做了更多的处理,比如下载进度,断点续传等等。

    NSURLSessionUploadTask:和下载任务对应,这个task主要是用于对服务端发送文件类型的数据使用的。

    1.1NSURLSession的使用

    NSURLSession本身是不会进行请求的,而是通过创建task的形式进行网络请求(resume()方法的调用),同一个NSURLSession可以创建多个task,并且这些task之间的cache和cookie是共享的。NSURLSession的使用有如下几步:

    •第一步:创建NSURLSession对象

    •第二步:使用NSURLSession对象创建Task

    •第三步:启动任务

    1.1.1创建NSURLSession对象

    NSURLSession对象的创建有如下三种方法:

    (1)直接创建

    NSURLSession *session=[NSURLSessionsharedSession];

    (2)配置后创建

    [NSURLSessionsessionWithConfiguration:defaultSessionConfiguration];

    (3)设置加代理获得

    //使用代理方法需要设置代理,但是session的delegate属性是只读的,要想设置代理只能通过这种方式创建session

    NSURLSession *session=[NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]

    delegate:self

    delegateQueue:[[NSOperationQueuealloc]init]];

    关于NSURLSession的配置有三种类型:

    //默认的配置会将缓存存储在磁盘上

    +(NSURLSessionConfiguration*)defaultSessionConfiguration;

    //瞬时会话模式不会创建持久性存储的缓存

    +(NSURLSessionConfiguration*)ephemeralSessionConfiguration;

    //后台会话模式允许程序在后台进行上传下载工作

    +(NSURLSessionConfiguration*)backgroundSessionConfigurationWithIdentifier:(NSString*)identifier

    1.1.2使用NSURLSession对象创建Task

    NSURLSessionTask的创建要根据具体需要创建相应类型的Task。

    (1)NSURLSessionDataTask

    通过request对象或url创建:

    -(NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;

    -(NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;

    通过request对象或url创建,同时指定任务完成后通过completionHandler指定回调的代码块:

    -(NSURLSessionDataTask*)dataTaskWithRequest:(NSURLRequest*)requestcompletionHandler:(void(^)(NSData*data,NSURLResponse*response,NSError*error))completionHandler;

    -(NSURLSessionDataTask*)dataTaskWithURL:(NSURL*)urlcompletionHandler:(void(^)(NSData*data,NSURLResponse*response,NSError*error))completionHandler;

    (2)NSURLSessionUploadTask

    通过request创建,在上传时指定文件源或数据源:

    -(NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)requestfromFile:(NSURL *)fileURL;

    -(NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)requestfromData:(NSData *)bodyData;

    -(NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;

    通过completionHandler指定任务完成后的回调代码块:

    -(NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)requestfromFile:(NSURL*)fileURLcompletionHandler:(void(^)(NSData*data,NSURLResponse*response,NSError*error))completionHandler;

    -(NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)requestfromData:(NSData*)bodyDatacompletionHandler:(void(^)(NSData*data,NSURLResponse*response,NSError*error))completionHandler;

    (3)NSURLSessionDownloadTask

    下载任务支持断点续传,第三种方式是通过之前已经下载的数据来创建下载任务:

    -(NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;

    -(NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;

    -(NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;

    同样地可以通过completionHandler指定任务完成后的回调代码块:

    -(NSURLSessionDownloadTask*)downloadTaskWithRequest:(NSURLRequest*)requestcompletionHandler:(void(^)(NSURL*location,NSURLResponse*response,NSError*error))completionHandler;

    -(NSURLSessionDownloadTask*)downloadTaskWithURL:(NSURL*)urlcompletionHandler:(void(^)(NSURL*location,NSURLResponse*response,NSError*error))completionHandler;

    -(NSURLSessionDownloadTask*)downloadTaskWithResumeData:(NSData*)resumeDatacompletionHandler:(void(^)(NSURL*location,NSURLResponse*response,NSError*error))completionHandler;

    我们在使用三种task的任意一种的时候都可以指定相应的代理。NSURLSession的代理对象结构如下:

    NSURLSessionDelegate–作为所有代理的基类,定义了网络请求最基础的代理方法。

    NSURLSessionTaskDelegate–定义了网络请求任务相关的代理方法。

    NSURLSessionDownloadDelegate–用于下载任务相关的代理方法,比如下载进度等等。

    NSURLSessionDataDelegate–用于普通数据任务和上传任务。

    相信大家都会使用代理,具体的使用方法这里不再讲解。

    1.1.3启动任务

    //启动任务

    [taskresume];

    1.2GET请求与POST请求

    我们可以使用NSURLSessionDataTask进行GET请求与POST请求。

    1.2.1GET请求

    //1、创建NSURLSession对象

    NSURLSession*session=[NSURLSessionsharedSession];

    //2、利用NSURLSession创建任务(task)

    NSURL*url=[NSURLURLWithString:@"http://www.xxx.com/login?username=myName&pwd=myPsd"];

    NSURLSessionDataTask*task=[sessiondataTaskWithURL:urlcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){

    }];

    //3、执行任务

    [taskresume];

    1.2.2POST请求

    //1、创建NSURLSession对象

    NSURLSession *session= [NSURLSession sharedSession];

    //2、利用NSURLSession创建任务(task)

    NSURL *url = [NSURLURLWithString:@"http://www.xxx.com/login"];

    //创建请求对象里面包含请求体

    NSMutableURLRequest*request = [NSMutableURLRequest requestWithURL:url];

    request.HTTPMethod =@"POST";

    request.HTTPBody =[@"username=myName&pwd=myPsd"dataUsingEncoding:NSUTF8StringEncoding];

    NSURLSessionDataTask*task = [session dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error){

    //打印解析后的json数据

    //NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);

    }];

    //3、执行任务

    [task resume];

    1.3文件的上传

    我们可以使用NSURLSessionUploadTask进行文件的上传,使用NSURLSessionUploadTask文件上传共有两种方法:

    方法1:

    NSURLSessionUploadTask *task=[[NSURLSessionsharedSession]uploadTaskWithRequest:requestfromFile:filename completionHandler:^(NSData*data,NSURLResponse*response,NSError*error){

    }];

    方法2:

    [self.session uploadTaskWithRequest:request fromData:bodycompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    NSLog(@"-------%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);

    }];

    1.3.1以数据流的方式进行上传

    这种方式好处就是大小不受限制,示例代码如下:

    -(void)NSURLSessionBinaryUploadTaskTest{

    //1.创建url

    NSString*urlString=@"http://www.xxxx.com/upload.php";

    //urlString = [urlStringstringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLFragmentAllowedCharacterSet]];

    NSURL*url=[NSURLURLWithString:urlString];

    //2.创建请求

    NSMutableURLRequest*request=[NSMutableURLRequestrequestWithURL:url];

    //文件上传使用post

    request.HTTPMethod=@"POST";

    //3.开始上传request的body data将被忽略,而由fromData提供

    [[[NSURLSessionsharedSession]uploadTaskWithRequest:requestfromData:[NSDatadataWithContentsOfFile:@"/Users/lifengfeng/Desktop/test.jpg"]completionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){

    if(error==nil){

    NSLog(@"uploadsuccess:%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }else{

    NSLog(@"uploaderror:%@",error);

    }

    }] resume];

    }

    1.3.2以拼接表单的方式进行上传

    上传的关键是请求体部分的表单拼接,获取本地上传文件的类型(MIME Types),至于具体的网络上传则很简单。另外拼接表单的方式会有大小限制,即HTML的MAX_FILE_SIZE限制(可以自己设定,一般2MB)。

    根据上面的继承关系图,我们知道uploadTask是dataTask的子类,也可以使用uploadTask来代替dataTask。

    表单拼接格式如下,boundary作为分界线:

    --boundary

    Content-Disposition:form-data;name=”表单控件名称”;filename=”上传文件名称”

    Content-Type:要上传文件MIME Types

    要上传文件二进制数据;

    --boundary--

    示例代码如下:

    -(void)NSURLSessionUploadTaskTest{

    //1.创建url采用Apache本地服务器

    NSString*urlString=@"http://localhost/upload/upload.php";

    urlString=[urlStringstringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLFragmentAllowedCharacterSet]];

    NSURL*url=[NSURLURLWithString:urlString];

    //2.创建请求

    NSMutableURLRequest*request=[NSMutableURLRequestrequestWithURL:url];

    //文件上传使用post

    request.HTTPMethod=@"POST";

    NSString*contentType=[NSStringstringWithFormat:@"multipart/form-data;boundary=%@",@"boundary"];

    [requestsetValue:contentTypeforHTTPHeaderField:@"Content-Type"];

    //test.jpg

    //3.拼接表单,大小受MAX_FILE_SIZE限制(2MB)FilePath:要上传的本地文件路径formName:表单控件名称,应于服务器一致

    NSData*data=[selfgetHttpBodyWithFilePath:@"/Users/lifengfeng/Desktop/test.jpg"formName:@"file"reName:@"newName.png"];

    request.HTTPBody=data;

    //根据需要是否提供,非必须,如果不提供,session会自动计算

    [requestsetValue:[NSStringstringWithFormat:@"%lu",data.length]forHTTPHeaderField:@"Content-Length"];

    //4.1使用dataTask

    [[[NSURLSessionsharedSession]dataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){

    if(error==nil){

    NSLog(@"uploadsuccess:%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }else{

    NSLog(@"uploaderror:%@",error);

    }

    }]resume];

    #if 0

    //4.2开始上传使用uploadTaskfromData:可有可无,会被忽略

    [[[NSURLSessionsharedSession]uploadTaskWithRequest:requestfromData:nilcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){

    if(error==nil){

    NSLog(@"uploadsuccess:%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);

    }else{

    NSLog(@"uploaderror:%@",error);

    }

    }]resume];

    #endif

    }

    其中用到的两个自定义的方法:

    ///

    filePath:要上传的文件路径formName:表单控件名称reName:上传后文件名

    -(NSData *)getHttpBodyWithFilePath:(NSString *)filePath formName:(NSString*)formName reName:(NSString *)reName

    {

    NSMutableData *data = [NSMutableData data];

    NSURLResponse *response = [selfgetLocalFileResponse:filePath];

    //文件类型:MIMEType文件的大小:expectedContentLength文件名字:suggestedFilename

    NSString *fileType = response.MIMEType;

    //如果没有传入上传后文件名称,采用本地文件名!

    if (reName == nil) {

    reName = response.suggestedFilename;

    }

    //表单拼接

    NSMutableString *headerStrM=[NSMutableString string];

    [headerStrMappendFormat:@"--%@\r\n",@"boundary"];

    // name:表单控件名称filename:上传文件名

    [headerStrMappendFormat:@"Content-Disposition: form-data; name=%@;filename=%@\r\n",formName,reName];

    [headerStrMappendFormat:@"Content-Type: %@\r\n\r\n",fileType];

    [data appendData:[headerStrM dataUsingEncoding:NSUTF8StringEncoding]];

    //文件内容

    NSData *fileData = [NSDatadataWithContentsOfFile:filePath];

    [data appendData:fileData];

    NSMutableString *footerStrM =[NSMutableStringstringWithFormat:@"\r\n--%@--\r\n",@"boundary"];

    [dataappendData:[footerStrMdataUsingEncoding:NSUTF8StringEncoding]];

    //NSLog(@"dataStr=%@",[[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding]);

    return data;

    }

    ///获取响应,主要是文件类型和文件名

    -(NSURLResponse *)getLocalFileResponse:(NSString *)urlString

    {

    urlString = [urlStringstringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLFragmentAllowedCharacterSet]];

    //本地文件请求

    NSURL *url = [NSURLfileURLWithPath:urlString];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    __block NSURLResponse *localResponse = nil;

    //使用信号量实现NSURLSession同步请求

    dispatch_semaphore_t semaphore =dispatch_semaphore_create(0);

    [[[NSURLSession sharedSession]dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data,NSURLResponse * _Nullable response, NSError * _Nullable error) {

    localResponse = response;

    dispatch_semaphore_signal(semaphore);

    }] resume];

    dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

    returnlocalResponse;

    }

    1.4文件的下载

    我们可以使用NSURLSessionDownloadTask实现文件的下载。NSURLSession使用代理方法也可以实现大文件下载,但是它实现不了断点下载,所以一般不用。

    -(void)NSURLSessionDownloadTaskTest{

    //1.创建url

    NSString*urlString=[NSStringstringWithFormat:@"http://www.xxx.com/test.mp3"];

    //一些特殊字符编码

    urlString=[urlStringstringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLQueryAllowedCharacterSet]];

    NSURL*url=[NSURLURLWithString:urlString];

    //2.创建请求

    NSURLRequest*request=[NSURLRequestrequestWithURL:url];

    //3.创建会话,采用苹果提供全局的共享session

    NSURLSession*sharedSession=[NSURLSessionsharedSession];

    //4.创建任务

    NSURLSessionDownloadTask*downloadTask=[sharedSessiondownloadTaskWithRequest:requestcompletionHandler:^(NSURL*_Nullablelocation,NSURLResponse*_Nullableresponse,NSError*_Nullableerror){

    if(error==nil){

    //location:下载任务完成之后,文件存储的位置,这个路径默认是在tmp文件夹下!

    //只会临时保存,因此需要将其另存

    NSLog(@"location:%@",location.path);

    //采用模拟器测试,为了方便将其下载到Mac桌面

    //NSString*filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES) lastObject];

    NSString*filePath=@"/Users/lifengfeng/Desktop/test.mp3";

    NSError*fileError;

    [[NSFileManagerdefaultManager]copyItemAtPath:location.pathtoPath:filePatherror:&fileError];

    if(fileError==nil){

    NSLog(@"filesave success");

    }else{

    NSLog(@"filesave error: %@",fileError);

    }

    }else{

    NSLog(@"downloaderror:%@",error);

    }

    }];

    //5.开启任务

    [downloadTaskresume];

    }

    2NSUrlProtocol中URLSession使用

    【主要参考】使用NSURLProtocol和NSURLSession拦截UIWebView的HTTP请求(包括ajax请求)

    http://www.cnblogs.com/wobuyayi/p/6283599.html

    注意:NSURLProtocol只能拦截UIWebView、NSURLConnection、NSURLSession和基于NSURLConnenction、NSURLSession实现的第三方框架(如AFNetworking)发出的网络请求,无法拦截WKWebview、CFNetwork以及基于CFNetwork实现的第三方框架(如MKNetworkit)发出的网络请求。

    下面提供一个完整的NSURLProtocol的实现类:

    RichURLSessionProtocol.h

    #import@interfaceRichURLSessionProtocol : NSURLProtocol@end

    RichURLSessionProtocol.m

    #import "RichURLSessionProtocol.h"

    static NSString * const RichURLProtocolHandledKey =@"RichURLProtocolHandledKey";

    @interface RichURLSessionProtocol()

    {

    NSURLResponse* _urlResponse;

    NSMutableData*_responseData;

    }

    @property (atomic,strong,readwrite) NSURLSessionDataTask *task;

    @property (nonatomic,strong) NSURLSession *session;

    @end

    @implementation RichURLSessionProtocol

    + (BOOL)canInitWithRequest:(NSURLRequest *)request

    {

    //只处理http和https请求

    NSString *scheme = [[requestURL] scheme];

    if ( ([schemecaseInsensitiveCompare:@"http"] == NSOrderedSame ||

    [schemecaseInsensitiveCompare:@"https"] == NSOrderedSame))

    {

    //看看是否已经处理过了,防止无限循环

    if ([NSURLProtocolpropertyForKey:RichURLProtocolHandledKey inRequest:request]) {

    return NO;

    }

    return YES;

    }

    return NO;

    }

    + (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {

    /**可以在此处添加头等信息*/

    NSMutableURLRequest*mutableReqeust = [request mutableCopy];

    return mutableReqeust;

    }

    - (void)startLoading

    {

    NSMutableURLRequest*mutableReqeust = [[self request] mutableCopy];

    //打标签,防止无限循环

    [NSURLProtocolsetProperty:@YES forKey:RichURLProtocolHandledKey inRequest:mutableReqeust];

    NSURLSessionConfiguration*configure = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSOperationQueue *queue =[[NSOperationQueue alloc] init];

    self.session= [NSURLSessionsessionWithConfiguration:configure delegate:self delegateQueue:queue];

    self.task = [self.sessiondataTaskWithRequest:mutableReqeust];

    [self.task resume];

    }

    - (void)stopLoading

    {

    [self.sessioninvalidateAndCancel];

    self.session = nil;

    }

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError *)error

    {

    if (error != nil) {

    [self.clientURLProtocol:self didFailWithError:error];

    }else

    {

    [self.clientURLProtocolDidFinishLoading:self];

    }

    }

    - (void)URLSession:(NSURLSession *)sessiondataTask:(NSURLSessionDataTask *)dataTask

    didReceiveResponse:(NSURLResponse*)response

    completionHandler:(void(^)(NSURLSessionResponseDisposition disposition))completionHandler

    {

    _urlResponse= response;

    // Create space for containing incoming data

    // This method may be called more than once if you're getting a multi-part

    mime

    // message and will be called once there's enough date to create the

    response object

    // Hence doa check if_responseData already there

    _responseData= [[NSMutableDataalloc]init];

    //NSLog(@"didReceiveResponse self: %@",self);

    [self.clientURLProtocol:selfdidReceiveResponse:responsecacheStoragePolicy:NSURLCacheStorageNotAllowed];

    completionHandler(NSURLSessionResponseAllow);

    [self.client URLProtocol:selfdidReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

    }

    //接受数据回调,有可能有多次回调

    - (void)URLSession:(NSURLSession *)sessiondataTask:(NSURLSessionDataTask *)dataTaskdidReceiveData:(NSData *)data

    {

    // Append the new data

    [_responseDataappendData:data];

    [self.clientURLProtocol:selfdidLoadData:data];

    }

    - (void)URLSession:(NSURLSession *)sessiondataTask:(NSURLSessionDataTask *)dataTask willCacheResponse: (NSCachedURLResponse*)proposedResponse completionHandler: (void (^)(NSCachedURLResponse *_Nullable)) completionHandler

    {

    completionHandler(proposedResponse);

    }

    //TODO:重定向

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask*)task willPerformHTTPRedirection:(NSHTTPURLResponse *)responsenewRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest*))completionHandler

    {

    NSMutableURLRequest*redirectRequest;

    redirectRequest = [newRequestmutableCopy];

    [[self class]removePropertyForKey:RichURLProtocolHandledKey inRequest:redirectRequest];

    [[self client]URLProtocol:self wasRedirectedToRequest:redirectRequestredirectResponse:response];

    [self.task cancel];

    [[self client]URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomaincode:NSUserCancelledError userInfo:nil]];

    }

    - (instancetype)initWithRequest:(NSURLRequest *)requestcachedResponse:(NSCachedURLResponse *)cachedResponseclient:(id)client

    {

    NSMutableURLRequest*redirectRequest;

    redirectRequest = [requestmutableCopy];

    //添加认证信息

    NSString *authString =[[[NSString stringWithFormat:@"%@:%@", kGlobal.userInfo.sAccount,kGlobal.userInfo.sPassword] dataUsingEncoding:NSUTF8StringEncoding]base64EncodedString];

    authString = [NSStringstringWithFormat: @"Basic %@", authString];

    [redirectRequestsetValue:authString forHTTPHeaderField:@"Authorization"];

    NSLog(@"拦截的请求:%@",request.URL.absoluteString);

    self = [superinitWithRequest:redirectRequest cachedResponse:cachedResponse client:client];

    if (self) {

    // Some stuff

    }

    return self;

    }

    - (void)URLSession:(NSURLSession

    *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge

    completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition,

    NSURLCredential * _Nullable))completionHandler{

    NSLog(@"自定义Protocol开始认证...");

    NSString *authMethod =[[challenge protectionSpace] authenticationMethod];

    NSLog(@"%@认证...",authMethod);

    if([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]) {

    NSURLCredential *card =[[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];

    completionHandler(NSURLSessionAuthChallengeUseCredential,card);

    }

    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]){

    if ([challengepreviousFailureCount] == 0) {

    NSURLCredential*credential = [NSURLCredential credentialWithUser:kGlobal.userInfo.sAccountpassword:kGlobal.userInfo.sPassword persistence:NSURLCredentialPersistenceForSession];

    [[challenge sender]useCredential:credential forAuthenticationChallenge:challenge];

    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);

    }else{

    completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil);

    }

    }

    NSLog(@"自定义Protocol认证结束");

    //通用SSL认证法二:

    //if ([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]) {

    //NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];

    //completionHandler(NSURLSessionAuthChallengeUseCredential,card);

    //[challenge.sender

    useCredential:[NSURLCredential

    credentialForTrust:challenge.protectionSpace.serverTrust]

    forAuthenticationChallenge:challenge];

    //}

    }

    @end

    3参考链接

    (Good)使用NSURLProtocol和NSURLSession拦截UIWebView的HTTP请求(包括ajax请求)

    http://www.cnblogs.com/wobuyayi/p/6283599.html

    从NSURLConnection到NSURLSession

    https://objccn.io/issue-5-4/

    ios NSURLSession(iOS7后,取代NSURLConnection)使用说明及后台工作流程分析

    http://www.mobile-open.com/2015/92324.html

    NSURLSession与NSURLConnection区别

    http://www.cnblogs.com/kakaluote123/articles/5426923.html

    HTTP协议授权访问

    http://blog.csdn.net/yangtiang/article/details/22793215

    NSURLCredential身份认证

    http://blog.csdn.net/majiakun1/article/details/17013379

    使用NSURLConnection连接HTTPS(SSL)站点

    http://www.tuicool.com/articles/7FnIZv

    相关文章

      网友评论

        本文标题:IOS开发系列——NSUrlSession专题

        本文链接:https://www.haomeiwen.com/subject/ldihzttx.html