NSURLSession VS NSURLConnection_nsurlconnection vs nsurlsession_li_yangyang_li的博客-程序员秘密

技术标签: iOS 开发  

NSURLSession VS NSURLConnection  
NSURLSession可以看做是NSURLConnection的进化版,其对NSURLConnection的改进点有: 

  • * 根据每个Session做配置(http header,Cache,Cookie,protocal,Credential),不再在整个App层面共享配置.
  • * 支持网络操作的取消和断点续传
  • * 改进了授权机制的处理
  • * 丰富的Delegate模型
  • * 分离了真实数据和网络配置数据。
  • * 后台处理上传和下载,即使你点击了“Home”按钮,后台仍然可以继续下载,并且提供了根据网络状况,电力情况进行处理的配置。

知识点  



用法  
使用NSURLSession的一般套路如下: 
  • 1. 定义一个NSURLRequest
  • 2. 定义一个NSURLSessionConfiguration,配置各种网络参数
  • 3. 使用NSURLSession的工厂方法获取一个所需类型的NSURLSession
  • 4. 使用定义好的NSURLRequest和NSURLSession构建一个NSURLSessionTask
  • 5. 使用Delegate或者CompletionHandler处理任务执行过程的所有事件。

实战  
这儿我简单的实现了一个下载任务的断点续传功能,具体效果如下: 

 

实现代码如下: 
Object-c代码   收藏代码
  1. #import "UrlSessionDemoViewController.h"  
  2.   
  3. @interface UrlSessionDemoViewController ()  
  4.   
  5. @end  
  6.   
  7. @implementation UrlSessionDemoViewController  
  8.   
  9. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  10. {  
  11.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  12.     return self;  
  13. }  
  14.   
  15. - (void)viewDidLoad  
  16. {  
  17.     [super viewDidLoad];  
  18.     self.progressBar.progress = 0;  
  19. }  
  20.   
  21.   
  22. - (NSURLSession *)session  
  23. {  
  24.     //创建NSURLSession  
  25.     NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];  
  26.     NSURLSession  *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];  
  27.     return session;  
  28. }  
  29.   
  30. - (NSURLRequest *)request  
  31. {  
  32.     //创建请求  
  33.     NSURL *url = [NSURL URLWithString:@"http://p1.pichost.me/i/40/1639665.png"];  
  34.     NSURLRequest *request = [NSURLRequest requestWithURL:url];  
  35.     return request;  
  36. }  
  37.   
  38. -(IBAction)start:(id)sender  
  39. {  
  40.     //用NSURLSession和NSURLRequest创建网络任务  
  41.     self.task = [[self session] downloadTaskWithRequest:[self request]];  
  42.     [self.task resume];  
  43. }  
  44.   
  45. -(IBAction)pause:(id)sender  
  46. {  
  47.     NSLog(@"Pause download task");  
  48.     if (self.task) {  
  49.         //取消下载任务,把已下载数据存起来  
  50.         [self.task cancelByProducingResumeData:^(NSData *resumeData) {  
  51.             self.partialData = resumeData;  
  52.             self.task = nil;  
  53.         }];  
  54.     }  
  55. }  
  56.   
  57. -(IBAction)resume:(id)sender  
  58. {  
  59.     NSLog(@"resume download task");  
  60.     if (!self.task) {  
  61.         //判断是否又已下载数据,有的话就断点续传,没有就完全重新下载  
  62.         if (self.partialData) {  
  63.             self.task = [[self session] downloadTaskWithResumeData:self.partialData];  
  64.         }else{  
  65.             self.task = [[self session] downloadTaskWithRequest:[self request]];  
  66.         }  
  67.     }  
  68.     [self.task resume];  
  69. }  
  70.   
  71. //创建文件本地保存目录  
  72. -(NSURL *)createDirectoryForDownloadItemFromURL:(NSURL *)location  
  73. {  
  74.     NSFileManager *fileManager = [NSFileManager defaultManager];  
  75.     NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];  
  76.     NSURL *documentsDirectory = urls[0];  
  77.     return [documentsDirectory URLByAppendingPathComponent:[location lastPathComponent]];  
  78. }  
  79. //把文件拷贝到指定路径  
  80. -(BOOL) copyTempFileAtURL:(NSURL *)location toDestination:(NSURL *)destination  
  81. {  
  82.   
  83.     NSError *error;  
  84.     NSFileManager *fileManager = [NSFileManager defaultManager];  
  85.     [fileManager removeItemAtURL:destination error:NULL];  
  86.     [fileManager copyItemAtURL:location toURL:destination error:&error];  
  87.     if (error == nil) {  
  88.         return true;  
  89.     }else{  
  90.         NSLog(@"%@",error);  
  91.         return false;  
  92.     }  
  93. }  
  94.   
  95. #pragma mark NSURLSessionDownloadDelegate  
  96. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask  
  97. didFinishDownloadingToURL:(NSURL *)location  
  98. {  
  99.     //下载成功后,文件是保存在一个临时目录的,需要开发者自己考到放置该文件的目录  
  100.     NSLog(@"Download success for URL: %@",location.description);  
  101.     NSURL *destination = [self createDirectoryForDownloadItemFromURL:location];  
  102.     BOOL success = [self copyTempFileAtURL:location toDestination:destination];  
  103.       
  104.     if(success){  
  105. //        文件保存成功后,使用GCD调用主线程把图片文件显示在UIImageView中  
  106.         dispatch_async(dispatch_get_main_queue(), ^{  
  107.             UIImage *image = [UIImage imageWithContentsOfFile:[destination path]];  
  108.             self.imageView.image = image;  
  109.             self.imageView.contentMode = UIViewContentModeScaleAspectFit;  
  110.             self.imageView.hidden = NO;  
  111.         });  
  112.     }else{  
  113.         NSLog(@"Meet error when copy file");  
  114.     }  
  115.     self.task = nil;  
  116. }  
  117.   
  118. /* Sent periodically to notify the delegate of download progress. */  
  119. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask  
  120.       didWriteData:(int64_t)bytesWritten  
  121.  totalBytesWritten:(int64_t)totalBytesWritten  
  122. totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite  
  123. {  
  124.     //刷新进度条的delegate方法,同样的,获取数据,调用主线程刷新UI  
  125.     double currentProgress = totalBytesWritten/(double)totalBytesExpectedToWrite;  
  126.     dispatch_async(dispatch_get_main_queue(), ^{  
  127.         self.progressBar.progress = currentProgress;  
  128.         self.progressBar.hidden = NO;  
  129.     });  
  130. }  
  131.   
  132. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask  
  133.  didResumeAtOffset:(int64_t)fileOffset  
  134. expectedTotalBytes:(int64_t)expectedTotalBytes  
  135. {  
  136. }  
  137.   
  138. - (void)didReceiveMemoryWarning  
  139. {  
  140.     [super didReceiveMemoryWarning];  
  141. }  
  142.   
  143. @end  
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/li_yangyang_li/article/details/50618041

智能推荐

Android恶意代码分析流程,【技术分享】Android恶意软件分析_weixin_39865061的博客-程序员秘密

预估稿费:200RMB(不服你也来投稿啊!)投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿目的这个练习涵盖了技术分析Android恶意软件通过使用一个定制的恶意软件样本在Android设备上运行时,将会reverse shell给一个攻击者。我们将通过使用静态和动态分析技术分析完整功能应用程序。虚拟机使用:Santoku Linux VM工具:AVD Manager, ADB...

国产动漫详细列表_cpongo3的博客-程序员秘密

国产动漫详细列表动漫名称来源跟新时间描述斗罗大陆第二季腾讯视频每周六由唐家三少的同名小说改编而成,内容切合小说原著万界神主腾讯视频每周三 周六虽然有点短,但是挺好看的狐妖小红娘腾讯视频每周五国产中算是比较好看的动漫...

java并发编程之CompletionService_My_Vina的博客-程序员秘密

(转自:https://blog.csdn.net/u010185262/article/details/56017175 侵删)应用场景当向Executor提交多个任务并且希望获得它们在完成之后的结果,如果用FutureTask,可以循环获取task,并调用get方法去获取task执行结果,但是如果task还未完成,获取结果的线程将阻塞直到task完成,由于不知道哪个task优先执行完毕,使用这...

C# Linq多表查询多参数排序_ciixcxy521659的博客-程序员秘密

两表 SQL to Linq SQL: strQuery = "SELECT A.*, B.LABEL_DESC FROM LBLMATREL A, LBLDEF B" + " WHERE A.FACTORY = B.FAC...

日期时间工具类_sheng_xinjun的博客-程序员秘密

package com.util;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.regex.Matcher;import java.util.regex.Patter...

随便推点

康娜的二叉树_Merry2004的博客-程序员秘密

题目描述九月月赛的时候,康娜学会了一种叫做线段树的数据结构。现在她发现了另外一个维护序列的数据结构。这棵二叉树的每个节点维护一对权值,记作 (a,b) 。这棵树满足任意父亲节点的 a 一定大于他的任何一个子孙节点的 a;对于任意节点,必然满足右儿子节点的 b < 这个节点自己的 b < 左儿子节点的 b。现在给你一个数列 x ,设a=x[i], b=i,用这个数列建立这种二叉树。可以保证这种二叉树的结构是唯一的。现在康娜建好了这棵树,她开始好奇另一个问题:对于这棵树上的任意一个点,将

Git 文件跟踪_37号楼梯的博客-程序员秘密

.gitignore只追踪.h 和.cpp结尾的文件。*.*!*.cpp!*.h 我们一般写的形式为“ git push origin &amp;lt;src&amp;gt;:&amp;lt;dst&amp;gt; ”,冒号前表示local branch的名字,冒号后表示remote repository下 branch的名字。注意,如果你省略了&amp;lt;dst&amp;gt;,git就认为你想push到remote re...

c语言flash里能存文件吗,STM32内部FLASH打包读写_宋简单的博客-程序员秘密

最近做到的项目在运行需要把一组uint8_t(unsigned char)的数据进行掉电储存,想到单片机STM32f030f4p6内部flash可以直接由程序操作,写了以下代码用于uint8_t数据打包保存和读取。1、程序清单 与 测试结果本程序包含5个文件,分别是:1、Flash.c:内部flash读取储存相关函数2、Flash.h:flash头文件3、USART1.c:STM32F030F4P...

JS对象,JSON_llkaidaotumi的博客-程序员秘密

对象万物皆对象字面量书写格式:关键字 标识符 赋值符号 大括号 分号let obj = {} ;例子:let iphone ={name:`HW`,size:5.0,price:9999,};对象初始化let obj ={属性名1:属性值1,属性名2:属性值2,属性名3:属性值3,属性名4:属性值4,};键值对键:属性名值:属性值变量称为属性,函数称为方法注:冒号右侧是否是函数【增,删,改,查】增对.

Matlab之魔方阵magic_magic matlab_星尘亦星辰的博客-程序员秘密

1、函数功能magic函数是用于创建魔方阵。魔方阵的特点是:每行每列以及对角线的元素之和相等的方阵。2、代码示例clc;clear all;A = magic(4)sum(A(1,:)) %求第一行的元素之和sum(A(:,1)) %求第一列的元素之和sum(diag(A)) %求对角线的元素之和,diag函数生成主对角线元素的向量运行结果:...

SQLCODE=-419, SQLSTATE=42911_sqlcode -419_今天去哪摸鱼的博客-程序员秘密

项目场景:DB2报错:SQLCODE=-419, SQLSTATE=42911问题描述:运行程序时,提示SQLCODE=-419, SQLSTATE=42911select cash_flow / nvl(CASHFLOW_DISCOUNT,1) from 表A 原因分析:翻阅资料后发现,十进制除法运算无效。在DB2除法中,被除数A / 除数B,两个字段的字段类型有小数点的差异,除数B的精度大于A时,就会报错。cash_flow的字段类型为decimal(30,15),cashflo