AFNetworkingKevin的IOS开发专题iOS Developer

IOS开发系列——NSUrlSession专题

2017-04-19  本文已影响1024人  Kevin_Junbaozi

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

上一篇下一篇

猜你喜欢

热点阅读