教你如何封装异步网络连接NSURLConnection实现带有百分比的下载
教你如何封装异步网络连接NSURLConnection实现带有百分比的下载
注:本教程需要你对block有着较为深刻的理解,且对如何封装对象有着一些经验.
也许你已经用惯了AFNetworking2.0,或者是ASIHTTPRequest(这个已经都不更新了,还不支持ARC,放弃为妙^_^),或者还有其他轻量级的开源代码.用着是很爽,但有时候我们只想实现简单的功能,用不着那么复杂,而且,那些开源代码太多,我们很难理解,那就尝试一下自己封装一个简单的吧.
NSURLConnection有着两种类型的实现,一种是同步的:
使用非常简单,它直接根据request返回一个data给你,不过因为是同步的,会阻塞主线程,你可以将他放到线程中就能把它变成异步的了,很easy,自己尝试.
剩下的几种基本上都是异步的了,实现起来也很容易,继承几个协议实现几个方法而已嘛.
上面的这么多操作,你只完成了一个功能,那就是下载一张图片而已.
如果我们能把一个网络地址链接抽象成一个对象,而这个对象来处理所有的这些操作,不需要我们把它暴露出来,比如像下面的使用方式:
某某类 *对象1 = [初始化一个网址];
[对象1 开始执行网络请求];
[对象1 监测下载状况];
.......
像上面的使用方式,非常接近人的思维方式,给链接地址,开始下载,监控下载状况,我们就应该这么用嘛.
那我们就按照这种套路来设计我们的类了.
能初始化一个网址以及有一个开始操作:
如何才能够不用协议就可以获取到下载进度呢(监测下载状态),我们就用block当做属性来获取下载进度:
以下是一份完整的代码:
#import <Foundation/Foundation.h> // block的相关定义
typedef void (^downloadProgressBlock_t)\
(NSData *data, long long totalBytesReceived, long long totalBytesExpectedToReceive);
typedef void (^completionDataBlock_t)(NSDictionary *headers, NSData *body); @interface YXNetwork : NSObject // 将block定义成属性
@property (nonatomic, copy) downloadProgressBlock_t downloadProgressBlock;
@property (nonatomic, copy) completionDataBlock_t completionDataBlock; // 初始化方法
- (instancetype)initWithUrlString:(NSString *)urlString; // 开始网络下载
- (void)start; @end
要下载东西我们需要能够存储数据,因为是下载,肯定也需要有网络链接,我们还需要知道下载数据期望的最大数值,要不然我们怎么表示进度呢?
基本思路就是这样子的,我们开始写代码了:
#import "YXNetwork.h" @interface YXNetwork ()<NSURLConnectionDelegate, NSURLConnectionDataDelegate> {
long long _expectedLength; // 期望最大的数据长度
} @property (nonatomic, strong) NSMutableData *storeData; // 存储下载的数据
@property (nonatomic, strong) NSURLConnection *dataConncetion; // 网络链接对象
@property (nonatomic, strong) NSDictionary *responseHeaders; // 该网络链接所有头信息 @end @implementation YXNetwork - (instancetype)initWithUrlString:(NSString *)urlString
{
self = [super init];
if (self)
{
self.storeData = [NSMutableData new];
self.dataConncetion = \
[[NSURLConnection alloc] initWithRequest:netURLRequest(urlString)
delegate:self
startImmediately:NO];
} return self;
} - (void)start
{
[self.dataConncetion start];
} - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSHTTPURLResponse *r = (NSHTTPURLResponse *)response; // 如果能获取到期望的数据长度就执行括号中的方法
if ([r expectedContentLength] != NSURLResponseUnknownLength)
{
_expectedLength = [r expectedContentLength];
_responseHeaders = [r allHeaderFields];
}
else
{
_expectedLength = ;
}
} // 设置长度为0
[_storeData setLength:];
} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[_storeData appendData:theData]; // 如果指定了block
if (_downloadProgressBlock)
{
_downloadProgressBlock(theData, [_storeData length], _expectedLength);
}
} - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 如果指定了block
if (_completionDataBlock)
{
_completionDataBlock(_responseHeaders, _storeData);
}
} NS_INLINE NSURLRequest *netURLRequest(NSString *netPath)
{
//创建简单的网络请求
return [NSURLRequest requestWithURL:[NSURL URLWithString:netPath]];
} @end
代码很简单,需要你对block有一定的了解,你拷贝如上两段代码到你的工程文件中,可以看看是怎么实现的.
现在来看看怎么使用:
比你之前直接用系统的那个NSURLConnection清爽了很多很多倍,对吧.
以下是下载图片时运行的截图:
给你提供高清图片下载地址: http://wallpapers.wallbase.cc/high-resolution/wallpaper-2594485.jpg
只要你愿意,你想怎么封装就怎么封装,就是这么简单,自己动手,丰衣足食^_^.
教你如何封装异步网络连接NSURLConnection实现带有百分比的下载的更多相关文章
- 用asyncio的异步网络连接来获取sina、sohu和163的网站首页
代码如下: import asyncio async def wget(host): print('wget %s...' % host) connect = asyncio.open_connect ...
- Android OkHttp网络连接封装工具类
package com.lidong.demo.utils; import android.os.Handler; import android.os.Looper; import com.googl ...
- iOS开发网络篇—NSURLConnection基本使用
iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据 ...
- iOS开发网络篇--NSURLConnection
S简介 NSURLConnection: 作用: 1.负责发送请求,建立客户端和服务器的连接发送数据给服务器 2.并收集来自服务器的响应数据 步骤: 1.创建一个NSURL对象,设置请求路径 2.传入 ...
- swift开发网络篇—NSURLConnection基本使用
iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据 ...
- iOS 多个异步网络请求全部返回后再执行具体逻辑的方法
对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...
- Android批量图片加载经典系列——使用二级缓存、异步网络负载形象
一.问题描写叙述 Android应用中常常涉及从网络中载入大量图片,为提升载入速度和效率,降低网络流量都会採用二级缓存和异步载入机制.所谓二级缓存就是通过先从内存中获取.再从文件里获取,最后才会訪问网 ...
- 百度APP移动端网络深度优化实践分享(二):网络连接优化篇
本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为<百度App网络深度优化系列<二>连接优化>,感谢原作者的无私分享. 一.前言 在<百度APP移动端网 ...
- WebView 的使用----android 网络连接处理分析
在Android中,可以有多种方式来实现网络编程: 创建URL,并使用URLConnection/HttpURLConnection 使用HttpClient 使用WebView 创建URL,并使用U ...
随机推荐
- Android Notification 的四种使用方式
实现通知步骤 一般实现通知需要如下步骤: 1.获取 NotificationManager 实例管理通知: 2.实例 Notification 对象: 3.管理事件 Intent: 4.发送通知. 注 ...
- ionic3打包打包安卓apk详细过程以及遇到的问题
1.jdk和sdk的安装以及环境变量配置参考打包详解 上述连接已经从下载安装jdk以及sdk的环境变量配置到打包的流程以及很详细了.但是在我自己安装打包的过程中遇到了这篇文章中没有遇到的问题,下面图文 ...
- Python多线程&进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- 自适应网页设计(Responsive Web Design)别名(响应式web设计)转载阮一峰
随着3G的普及,越来越多的人使用手机上网. 移动设备正超过桌面设备,成为访问互联网的最常见终端.于是,网页设计师不得不面对一个难题:如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通 ...
- 资料整理:基于node push server实现push notification
chat example based on ionic/ socket.io/ redis https://github.com/jbavari/ionic-socket.io-redis-chat ...
- Zookeeper概念学习系列之分布式事务
不多说,直接上干货! 初学者来说,肯定会有这么一个疑问.为什么会在zookeeper里牵扯到分布式事务? zookeeper到底是什么? zookeeper实际上是yahoo开发的,用于分布式中一致性 ...
- Shiro与Spring、Springmvc的整合
1.在web.xml中配置Shiro的filter 在web系统中,shiro也通过filter进行拦截.filter拦截后将操作权交给spring中配置的filterChain(过虑链儿) shir ...
- Android OpenGL教程-第三课【转】
第三课 给多边形上色: 作为第二课的扩展,我将叫你如何使用颜色.你将理解两种着色模式,在左图中,三角形用的是光滑着色,四边形用的是平面着色. 这次增加的代码不算多. 增加一个color的buffer ...
- C#继承中构造函数,成员变量的执行顺序
public class Animal { static string baseClassName; protected string _skincolor; Instancevariable iv ...
- webservice log4net日志写入失败
原因1:如果webservice和调用者都部署在一台机器上,日志有可能写到了项目所在目录中,虽然你添加的服务引用是部署在iis下的,但不会写到这.暂时解决办法,把webservice部署到内网服务器上 ...