教你如何封装异步网络连接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;
        }
    }

    // 设置长度为0
    [_storeData setLength:0];
}

- (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

只要你愿意,你想怎么封装就怎么封装,就是这么简单,自己动手,丰衣足食^_^.

时间: 2024-09-19 17:28:46

教你如何封装异步网络连接NSURLConnection实现带有百分比的下载的相关文章

Java aio(异步网络IO)初探

[本文转载于Java aio(异步网络IO)初探] 按照<Unix网络编程>的划分,IO模型可以分为:阻塞IO.非阻塞IO.IO复用.信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO.如何区分呢?首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO.非阻塞IO.IO服用.信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将

iOS下的实际网络连接状态检测

序言 网络连接状态检测对于我们的iOS app开发来说是一个非常通用的需求.为了更好的用户体验,我们会在无网络时展现本地或者缓存的内容,并对用户进行合适的提示.对绝大部分iOS开发者来说,从苹果示例代码改变而来的各种Reachablity框架是实现这个需求的普遍选择,比如这个库.但事实上,基于此方案的所有实现,都无法帮助我们检测真正的网络连接状态,它们能检测的只是本地连接状态:这种情况包括但不限于如下场景: 1.现在很流行的公用wifi,需要网页鉴权,鉴权之前无法上网,但本地连接已经建立: 2.

动车上的书摘-java网络 连接服务器

一.服务器初试-telnet工具     当我们编写网络程序时,我们应该认识telnet的小工具(unix 和 win 自带).Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.win自带的telnet要去开启,开启的步骤如下:                                   注意:第一:打开控制面板,打开程序和功能,看到左边有个"打开或关闭Windows功能 ,打开找到tel

Java AIO初探(异步网络IO)

按照<Unix网络编程>的划分,IO模型可以分为:阻塞IO.非阻塞IO.IO复用.信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO.如何区分呢?首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO.非阻塞IO.IO服用.信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO.阻塞IO和非阻塞IO

网络连接图标出现黄色感叹号是怎么回事?

  故障分析:出现网络连接的黄色的感叹号,先来说说黄色感叹号所代表的意思?它的意思就是说明电脑设备中设备驱动有异常状况,需要找到合适的网卡驱动程序重新更新,也就是网卡驱动的问题. 故障解决:而我们首先要做的就是找到你的异常驱动设备,一般是网络适配器(网卡)驱动的故障,所以建议你去网上下载一个驱动精灵或者驱动人生来修复网卡驱动解除故障.这些都是有官方网站下载地址的.当然如果你的电脑自带了网卡驱动光盘的话那就最好不过了,直接通过光盘安装网络驱动再将电脑重启查看是否能解决故障. 下面我们来教你如何查看

win8电脑中如何屏蔽不需要的网络连接?

  现在无线网成为我们生活的一部分,不管是使用电脑还是手机,都会连接当地的无线网,有些我们经常去的地区,设备就会设置自动连接,不用每次都手动输入密码,对于我们来说是个很方便的事情.但是不知道大家有没有考虑过,我们登过很多地方的无线网,电脑都会保存这些密码,只要在无线网服务范围内,就会自动连接,这样久而久之就会发现自己电脑中的网络连接越来越多, 对于电脑来说也是具有风险的.下面小编就来教大家如何在win8电脑中快速删除多出的网络连接? win8电脑中快速删除多出的网络连接方法如下 1.首先,咱们需

Android应用中使用AsyncHttpClient来异步网络数据

首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测试的Activity,用到了RequstClient,LoadCacheResponseLoginouthandler,LoadDatahandler三个重写的类 [java] view plaincopyprint? package com.example.asynchttpclienttest;    

iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载

前言:iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载是在前篇iOS开发之网络编程--使用NSURLConnection实现大文件下载的基础上进行    断点续传的设置.关于iOS开发之网络编程--使用NSURLConnection实现大文件下载的细节这里当然就不会再累述的啦.   断点续传的原理:    每次在向服务器请求下载数据的同时,要告诉服务器从整个下载文件的数据流的某个还未下载的位置开始下载,然后服务器就返回从那个位置开始的数据流.    图片示意图:

iOS下的实际网络连接状态检测:RealReachability

序言 网络连接状态检测对于我们的iOS app开发来说是一个非常通用的需求.为了更好的用户体验,我们会在无网络时展现本地或者缓存的内容,并对用户进行合适的提示.对绝大部分iOS开发者来说,从苹果示例代码改变而来的各种Reachablity框架是实现这个需求的普遍选择,比如这个库.但事实上,基于此方案的所有实现,都无法帮助我们检测真正的网络连接状态,它们能检测的只是本地连接状态:这种情况包括但不限于如下场景: 1.现在很流行的公用wifi,需要网页鉴权,鉴权之前无法上网,但本地连接已经建立: 2.