NSURLConnection设置代理
来源:互联网 发布:世界行政区域数据 编辑:程序博客网 时间:2024/05/21 11:16
1 NSURLConnection设置代理
(1)两种为NSURLConnection设置代理方式的区别
//第一种设置方式: //通过该方法设置代理,会自动的发送请求 // [[NSURLConnection alloc]initWithRequest:request delegate:self]; //第二种设置方式: //设置代理,startImmediately为NO的时候,该方法不会自动发送请求 NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //手动通过代码的方式来发送请求 //注意该方法内部会自动的把connect添加到当前线程的RunLoop中在默认模式下执行 [connect start]; ```(2)如何控制代理方法在哪个线程调用```objc //说明:默认情况下,代理方法会在主线程中进行调用(为了方便开发者拿到数据后处理一些刷新UI的操作不需要考虑到线程间通信) //设置代理方法的执行队列 [connect setDelegateQueue:[[NSOperationQueue alloc]init]];<div class="se-preview-section-delimiter"></div>
(3)开子线程发送网络请求的注意点,适用于自动发送网络请求模式
//在子线程中发送网络请求-调用startf方法发送-(void)createNewThreadSendConnect1{ //1.创建一个非主队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //2.封装操作,并把任务添加到队列中执行 [queue addOperationWithBlock:^{ NSLog(@"%@",[NSThread currentThread]); //2-1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"]; //2-2.创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //2-3.使用NSURLConnection设置代理,发送网络请求 NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES]; //2-4.设置代理方法在哪个队列中执行,如果是非主队列,那么代理方法将再子线程中执行 [connection setDelegateQueue:[[NSOperationQueue alloc]init]]; //2-5.发送网络请求 //注意:start方法内部会把当前的connect对象作为一个source添加到当前线程对应的runloop中 //区别在于,如果调用start方法开发送网络请求,那么再添加source的过程中,如果当前runloop不存在 //那么该方法内部会自动创建一个当前线程对应的runloop,并启动。 [connection start]; }];}//在子线程中发送网络请求-自动发送网络请求-(void)createNewThreadSendConnect2{ NSLog(@"-----"); //1.创建一个非主队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //2.封装操作,并把任务添加到队列中执行 [queue addOperationWithBlock:^{ //2-1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"]; //2-2.创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //2-3.使用NSURLConnection设置代理,发送网络请求 //注意:该方法内部虽然会把connection添加到runloop,但是如果当前的runloop不存在,那么不会主动创建。 NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; //2-4.设置代理方法在哪个队列中执行,如果是非主队列,那么代理方法将再子线程中执行 [connection setDelegateQueue:[[NSOperationQueue alloc]init]]; //2-5 创建当前线程对应的runloop,并开启 [[NSRunLoop currentRunLoop]run]; }];}<div class="se-preview-section-delimiter"></div>
2 NSURLSession的基本使用
(1)使用步骤
使用NSURLSession创建task,然后执行task
(2)关于task
a.NSURLSessionTask是一个抽象类,本身不能使用,只能使用它的子类 b.NSURLSessionDataTask\NSURLSessionUploadTask\NSURLSessionDownloadTask
(3)发送get请求
//1.创建NSURLSession对象(可以获取单例对象) NSURLSession *session = [NSURLSession sharedSession]; //2.根据NSURLSession对象创建一个Task NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=ss&pwd=ss&type=JSON"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; //方法参数说明 /* 注意:该block是在子线程中调用的,如果拿到数据之后要做一些UI刷新操作,那么需要回到主线程刷新 第一个参数:需要发送的请求对象 block:当请求结束拿到服务器响应的数据时调用block block-NSData:该请求的响应体 block-NSURLResponse:存放本次请求的响应信息,响应头,真实类型为NSHTTPURLResponse block-NSErroe:请求错误信息 */ NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) { //拿到响应头信息 NSHTTPURLResponse *res = (NSHTTPURLResponse *)response; //4.解析拿到的响应数据 NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields); }]; //3.执行Task //注意:刚创建出来的task默认是挂起状态的,需要调用该方法来启动任务(执行任务) [dataTask resume];<div class="se-preview-section-delimiter"></div>
(4)发送get请求的第二种方式
//注意:该方法内部默认会把URL对象包装成一个NSURLRequest对象(默认是GET请求) //方法参数说明 /* //第一个参数:发送请求的URL地址 //block:当请求结束拿到服务器响应的数据时调用block //block-NSData:该请求的响应体 //block-NSURLResponse:存放本次请求的响应信息,响应头,真实类型为NSHTTPURLResponse //block-NSErroe:请求错误信息 */- (nullable NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error))completionHandler;<div class="se-preview-section-delimiter"></div>
(5)发送POST请求
//1.创建NSURLSession对象(可以获取单例对象) NSURLSession *session = [NSURLSession sharedSession]; //2.根据NSURLSession对象创建一个Task NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"]; //创建一个请求对象,并这是请求方法为POST,把参数放在请求体中传递 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) { //拿到响应头信息 NSHTTPURLResponse *res = (NSHTTPURLResponse *)response; //解析拿到的响应数据 NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields); }]; //3.执行Task //注意:刚创建出来的task默认是挂起状态的,需要调用该方法来启动任务(执行任务) [dataTask resume];<div class="se-preview-section-delimiter"></div>
3 NSURLSession下载文件-代理
(1)创建NSURLSession对象,设置代理(默认配置)
//1.创建NSURLSession,并设置代理 /* 第一个参数:session对象的全局配置设置,一般使用默认配置就可以 第二个参数:谁成为session对象的代理 第三个参数:代理方法在哪个队列中执行(在哪个线程中调用),如果是主队列那么在主线程中执行,如果是非主队列,那么在子线程中执行 */ NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];<div class="se-preview-section-delimiter"></div>
(2)根据Session对象创建一个NSURLSessionDataTask任务(post和get选择)
//创建taskNSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];//注意:如果要发送POST请求,那么请使用dataTaskWithRequest,设置一些请求头信息NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];<div class="se-preview-section-delimiter"></div>
(3)执行任务(其它方法,如暂停、取消等)
//启动task //[dataTask resume]; //其它方法,如取消任务,暂停任务等 //[dataTask cancel]; //[dataTask suspend];<div class="se-preview-section-delimiter"></div>
(4)遵守代理协议,实现代理方法(3个相关的代理方法)
/* 1.当接收到服务器响应的时候调用 session:发送请求的session对象 dataTask:根据NSURLSession创建的task任务 response:服务器响应信息(响应头) completionHandler:通过该block回调,告诉服务器端是否接收返回的数据 */-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler/* 2.当接收到服务器返回的数据时调用 该方法可能会被调用多次 */-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveData:(nonnull NSData *)data/* 3.当请求完成之后调用该方法 不论是请求成功还是请求失败都调用该方法,如果请求失败,那么error对象有值,否则那么error对象为空 */-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error<div class="se-preview-section-delimiter"></div>
(5)当接收到服务器响应的时候,告诉服务器接收数据(调用block)
//默认情况下,当接收到服务器响应之后,服务器认为客户端不需要接收数据,所以后面的代理方法不会调用 //如果需要继续接收服务器返回的数据,那么需要调用block,并传入对应的策略 /* NSURLSessionResponseCancel = 0, 取消任务 NSURLSessionResponseAllow = 1, 接收任务 NSURLSessionResponseBecomeDownload = 2, 转变成下载 NSURLSessionResponseBecomeStream NS_ENUM_AVAILABLE(10_11, 9_0) = 3, 转变成流 */ completionHandler(NSURLSessionResponseAllow);<div class="se-preview-section-delimiter"></div>
4 NSURLSessionDownloadTask实现大文件下载
(1)使用NSURLSession和NSURLSessionDownload可以很方便的实现文件下载操作
/* 第一个参数:要下载文件的url路径 第二个参数:当接收完服务器返回的数据之后调用该block location:下载的文件的保存地址(默认是存储在沙盒中tmp文件夹下面,随时会被删除) response:服务器响应信息,响应头 error:该请求的错误信息 */ //说明:downloadTaskWithURL方法已经实现了在下载文件数据的过程中边下载文件数据,边写入到沙盒文件的操作 NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * __nullable location, NSURLResponse * __nullable response, NSError * __nullable error)<div class="se-preview-section-delimiter"></div>
(2)downloadTaskWithURL内部默认已经实现了变下载边写入操作,所以不用开发人员担心内存问题
(3)文件下载后默认保存在tmp文件目录,需要开发人员手动的剪切到合适的沙盒目录
(4)缺点:没有办法监控下载进度
5 使用NSURLSessionDownloadTask实现大文件下载-监听下载进度
(1)创建NSURLSession并设置代理,通过NSURLSessionDownloadTask并以代理的方式来完成大文件的下载
//1.创建NSULRSession,设置代理 self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; //2.创建task NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]; self.downloadTask = [self.session downloadTaskWithURL:url]; //3.执行task [self.downloadTask resume];<div class="se-preview-section-delimiter"></div>
(2)常用代理方法的说明
/* 1.当接收到下载数据的时候调用,可以在该方法中监听文件下载的进度 该方法会被调用多次 totalBytesWritten:已经写入到文件中的数据大小 totalBytesExpectedToWrite:目前文件的总大小 bytesWritten:本次下载的文件数据大小 */-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite/* 2.恢复下载的时候调用该方法 fileOffset:恢复之后,要从文件的什么地方开发下载 expectedTotalBytes:该文件数据的总大小 */-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes/* 3.下载完成之后调用该方法 */-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location/* 4.请求完成之后调用 如果请求失败,那么error有值 */-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error<div class="se-preview-section-delimiter"></div>
(3)实现断点下载相关代码
//如果任务,取消了那么以后就不能恢复了 // [self.downloadTask cancel]; //如果采取这种方式来取消任务,那么该方法会通过resumeData保存当前文件的下载信息 //只要有了这份信息,以后就可以通过这些信息来恢复下载 [self.downloadTask cancelByProducingResumeData:^(NSData * __nullable resumeData) { self.resumeData = resumeData; }]; ----------- //继续下载 //首先通过之前保存的resumeData信息,创建一个下载任务 self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData]; [self.downloadTask resume];<div class="se-preview-section-delimiter"></div>
(4)计算当前下载进度
//获取文件下载进度 self.progress.progress = 1.0 * totalBytesWritten/totalBytesExpectedToWrite; ```(5)局限性 01 如果用户点击暂停之后退出程序,那么需要把恢复下载的数据写一份到沙盒,代码复杂度更 02 如果用户在下载中途未保存恢复下载数据即退出程序,则不具备可操作性---<div class="se-preview-section-delimiter"></div>#####6 使用NSURLSessionDataTask实现大文件离线断点下载(完整)(1)关于NSOutputStream的使用<div class="se-preview-section-delimiter"></div>```objc //1. 创建一个输入流,数据追加到文件的屁股上 //把数据写入到指定的文件地址,如果当前文件不存在,则会自动创建 NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES]; //2. 打开流 [stream open]; //3. 写入流数据 [stream write:data.bytes maxLength:data.length]; //4.当不需要的时候应该关闭流 [stream close];
(2)关于网络请求请求头的设置(可以设置请求下载文件的某一部分)
(3)开子线程发送网络请求的注意点,适用于自动发送网络请求模式```objc//在子线程中发送网络请求-调用startf方法发送-(void)createNewThreadSendConnect1{ //1.创建一个非主队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //2.封装操作,并把任务添加到队列中执行 [queue addOperationWithBlock:^{ NSLog(@"%@",[NSThread currentThread]); //2-1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"]; //2-2.创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //2-3.使用NSURLConnection设置代理,发送网络请求 NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES]; //2-4.设置代理方法在哪个队列中执行,如果是非主队列,那么代理方法将再子线程中执行 [connection setDelegateQueue:[[NSOperationQueue alloc]init]]; //2-5.发送网络请求 //注意:start方法内部会把当前的connect对象作为一个source添加到当前线程对应的runloop中 //区别在于,如果调用start方法开发送网络请求,那么再添加source的过程中,如果当前runloop不存在 //那么该方法内部会自动创建一个当前线程对应的runloop,并启动。 [connection start]; }];}//在子线程中发送网络请求-自动发送网络请求-(void)createNewThreadSendConnect2{ NSLog(@"-----"); //1.创建一个非主队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //2.封装操作,并把任务添加到队列中执行 [queue addOperationWithBlock:^{ //2-1.确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"]; //2-2.创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //2-3.使用NSURLConnection设置代理,发送网络请求 //注意:该方法内部虽然会把connection添加到runloop,但是如果当前的runloop不存在,那么不会主动创建。 NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; //2-4.设置代理方法在哪个队列中执行,如果是非主队列,那么代理方法将再子线程中执行 [connection setDelegateQueue:[[NSOperationQueue alloc]init]]; //2-5 创建当前线程对应的runloop,并开启 [[NSRunLoop currentRunLoop]run]; }];}
0 0
- NSURLConnection设置代理
- NSURLConnection常用的代理方法
- 数据请求:NSURLConnection ,代理方法
- NSURLConnection代理方法线程问题
- iOS NSURLConnection同步 异步请求 代理
- 文件的下载(通过NSURLConnection代理)
- NSURLConnection 遵守代理协议但是不能响应代理
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- NSURLConnection
- Programatically install apk from assets folder in android
- Linux下的C语言编程——求三角形面积
- web常见问题
- 点多边形测试
- 我的caffe学习之路<第九天>
- NSURLConnection设置代理
- Java输入/输出流
- 【CodeForce 734C 】Anton and Making Potions (枚举+二分)
- JQuery 解决用load加载页面到div时,不执行页面js的问题
- android获取文件getMimeType的方法
- linux vim 全部 替换 转义字符
- 连接跟踪的一些设想
- KMeans聚类算法Hadoop实现
- 形态学梯度操作