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

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

目录
相关文章
|
4月前
|
消息中间件 NoSQL Linux
workFlow c++异步网络库编译教程与简介
搜狗公司C++服务器引擎,编程范式。支撑搜狗几乎所有后端C++在线服务,包括所有搜索服务,云输入法,在线广告等,每日处理数百亿请求。这是一个设计轻盈优雅的企业级程序引擎,可以满足大多数后端与嵌入式开发需求。 编程范式 结构化并发与任务隐藏回调与内存回收机制
58 0
|
6月前
|
网络协议 Python
149 python网络编程 - TFTP下载案例
149 python网络编程 - TFTP下载案例
28 0
|
5月前
|
XML Java Android开发
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
Android App开发网络通信中使用okhttp下载和上传图片、文件讲解及实战(超详细实现用户注册信息上传 附源码)
167 0
|
7月前
|
缓存 网络协议 Dubbo
异步编程 - 12 异步、基于事件驱动的网络编程框架 Netty
异步编程 - 12 异步、基于事件驱动的网络编程框架 Netty
47 0
|
8月前
|
存储 监控 数据可视化
Java网络编程:下载进度监控实现详解
文件下载是许多应用程序的重要功能,而下载进度监控是提高用户体验的关键。在本文中,我们将详细介绍如何使用Java实现文件下载进度监控,以便用户可以实时了解文件下载的进度。
103 0
|
24天前
|
数据采集 存储 iOS开发
Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例
本文介绍了如何使用Objective-C的MWFeedParser库高效捕获Stack Overflow的RSS数据并保存为CSV。首先,通过CocoaPods或手动方式集成MWFeedParser库,然后设置代理服务器以隐藏真实IP。接着,创建MWFeedParser实例,设置代理和解析类型,并启动解析。当数据解析完成后,可将其转换为CSV格式并保存。提供的代码示例详细展示了整个过程。注意实际使用时需替换代理服务器的相关信息。
Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例
|
25天前
|
机器学习/深度学习 算法
MATLAB中用BP神经网络预测人体脂肪百分比数据
MATLAB中用BP神经网络预测人体脂肪百分比数据
|
25天前
|
数据采集 存储 数据安全/隐私保护
拓展网络技能:利用lua-http库下载www.linkedin.com信息的方法
本文介绍如何使用Lua和lua-http库抓取LinkedIn信息,强调了Lua在爬虫开发中的应用。通过配置亿牛云爬虫代理解决IP封锁问题,实现步骤包括安装库、配置代理、发送HTTP请求、解析响应及提取信息。提供的Lua代码示例展示了下载和存储LinkedIn信息的过程。实验成功展示了Lua爬虫的可行性,但也指出需考虑反爬虫策略以应对实际挑战。
拓展网络技能:利用lua-http库下载www.linkedin.com信息的方法
|
1月前
|
前端开发 网络协议 Java
Netty入门指南:从零开始的异步网络通信
Netty入门指南:从零开始的异步网络通信
27 0
|
5月前
|
设计模式 网络协议 Java
C++ Boost 异步网络编程基础
Boost库为C++提供了强大的支持,尤其在多线程和网络编程方面。其中,Boost.Asio库是一个基于前摄器设计模式的库,用于实现高并发和网络相关的开发。Boost.Asio核心类是`io_service`,它相当于前摄模式下的`Proactor`角色。所有的IO操作都需要通过`io_service`来实现。在异步模式下,程序除了发起IO操作外,还需要定义一个用于回调的完成处理函数。`io_service`将IO操作交给操作系统执行,但它不同步等待,而是立即返回。调用`io_service`的`run`成员函数可以等待异步操作完成。当异步操作完成时,`io_service`会从操作系统获取结
83 1
C++ Boost 异步网络编程基础