ios专题 - 异步下载加下载进度显示
【罗国强原创】
今天被刺激了,愤概地要写下这边博文。
说到http异步下载,首先要知道其中的关键类。
关键类是NSURLConnection NSURLRequest NSMutableURLRequest
委托是 NSURLConnectionDownloadDelegate NSURLConnectionDataDelegate NSURLConnectionDelegate
首先,我们要实现最基本的下载功能。
LQAsynDownload.h
//
// LQAsynDownload.h
// lgTest
//
// Created by yons on 14-2-14.
// Copyright (c) 2014年 GQ. All rights reserved.
// #import <Foundation/Foundation.h> @interface LQAsynDownload : NSObject<NSURLConnectionDataDelegate> @property (strong) NSURL *httpURL; + (LQAsynDownload *) initWithURL:(NSURL *) url; - (void) startAsyn; @end
LQAsynDownload.m
//
// LQAsynDownload.m
// lgTest
//
// Created by yons on 14-2-14.
// Copyright (c) 2014年 GQ. All rights reserved.
// #import "LQAsynDownload.h" @interface LQAsynDownload() @property (assign) long long contentLength; @property (assign) long long receiveLength; @property (strong) NSMutableData *receiveData; @property (strong) NSString *fileName; @property (strong) NSURLConnection *theConnection; @property (strong) NSURLRequest *theRequest; @end @implementation LQAsynDownload @synthesize receiveData = _receiveData, fileName = _fileName,
theConnection=_theConnection, theRequest=_theRequest; + (LQAsynDownload *) initWithURL:(NSURL *) url{
LQAsynDownload *asynDownload = [[LQAsynDownload alloc] init];
asynDownload.theRequest=[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
return asynDownload;
} - (void) startAsyn{
_contentLength=;
_receiveLength=;
self.receiveData = [[NSMutableData alloc] init];
self.theConnection = [[NSURLConnection alloc] initWithRequest:self.theRequest delegate:self];
} //接收到http响应
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
_contentLength = [response expectedContentLength];
_fileName = [response suggestedFilename];
NSLog(@"data length is %lli", _contentLength);
} //传输数据
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
_receiveLength += data.length;
[_receiveData appendData:data];
NSLog(@"data recvive is %lli", _receiveLength);
} //错误
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
[self releaseObjs];
NSLog(@"%@",error.description);
} - (void) releaseObjs{
self.receiveData = nil;
self.fileName = nil;
self.theRequest = nil;
self.theConnection = nil;
} //成功下载完毕
- (void) connectionDidFinishLoading:(NSURLConnection *)connection{
//数据写入doument
//获取完整目录名字
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:];
NSString *savePath = [NSString stringWithFormat:@"%@/%@",documentsDirectory, _fileName];
//创建文件
[_receiveData writeToFile:savePath atomically:YES];
[self releaseObjs];
} @end
最简单的功能调用代码:
LQAsynDownload *dwn = [LQAsynDownload initWithURL:[[NSURL alloc] initWithString:@"http://t2.baidu.com/it/u=0,3067863433&fm=19&gp=0.jpg"]];
[dwn startAsyn];
查查模拟器,神啊,MM靓图出现了
情人节努力的补充礼物,哈哈。
关键点分析:
其实就是实现NSURLConnectionData委托的几个方法:
这个方法是客户端接收到回应后的调用方法,算是下载的开始。
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
跟着就是接收数据的方法
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
还有一个遇到错误时的处理方法
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
最后是下载成功调用的方法
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
接着实现,下载进度查看。
在原代码基础上增加2个block 属性。
LQAsynDownload.h
//
// LQAsynDownload.h
// lgTest
//
// Created by yons on 14-2-14.
// Copyright (c) 2014年 GQ. All rights reserved.
// #import <Foundation/Foundation.h> 11 typedef void (^initProgress)(long long initValue);
12
13 typedef void (^loadedData)(long long loadedLength); @interface LQAsynDownload : NSObject<NSURLConnectionDataDelegate> @property (strong) NSURL *httpURL; 19 @property (copy) void (^initProgress)(long long initValue);
20
21 @property (copy) void (^loadedData)(long long loadedLength); + (LQAsynDownload *) initWithURL:(NSURL *) url; - (void) startAsyn; @end
LQAsynDownload.m
//
// LQAsynDownload.m
// lgTest
//
// Created by yons on 14-2-14.
// Copyright (c) 2014年 GQ. All rights reserved.
// #import "LQAsynDownload.h" @interface LQAsynDownload() @property (assign) long long contentLength; @property (assign) long long receiveLength; @property (strong) NSMutableData *receiveData; @property (strong) NSString *fileName; @property (strong) NSURLConnection *theConnection; @property (strong) NSURLRequest *theRequest; @end @implementation LQAsynDownload @synthesize receiveData = _receiveData, fileName = _fileName,
theConnection=_theConnection, theRequest=_theRequest; + (LQAsynDownload *) initWithURL:(NSURL *) url{
LQAsynDownload *asynDownload = [[LQAsynDownload alloc] init];
asynDownload.theRequest=[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
return asynDownload;
} - (void) startAsyn{
_contentLength=;
_receiveLength=;
self.receiveData = [[NSMutableData alloc] init];
self.theConnection = [[NSURLConnection alloc] initWithRequest:self.theRequest delegate:self];
} //接收到http响应
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
_contentLength = [response expectedContentLength];
_fileName = [response suggestedFilename];
53 if (self.initProgress != nil) {
54 self.initProgress(_contentLength);
55 }
NSLog(@"data length is %lli", _contentLength);
} //传输数据
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
_receiveLength += data.length;
[_receiveData appendData:data];
63 if (self.loadedData != nil) {
64 self.loadedData(data.length);
65 }
NSLog(@"data recvive is %lli", _receiveLength);
} //错误
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
[self releaseObjs];
NSLog(@"%@",error.description);
} - (void) releaseObjs{
self.receiveData = nil;
self.fileName = nil;
self.theRequest = nil;
self.theConnection = nil;
} //成功下载完毕
- (void) connectionDidFinishLoading:(NSURLConnection *)connection{
//数据写入doument
//获取完整目录名字
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:];
NSString *savePath = [NSString stringWithFormat:@"%@/%@",documentsDirectory, _fileName];
//创建文件
[_receiveData writeToFile:savePath atomically:YES];
[self releaseObjs];
} @end
调用代码:
LQAsynDownload *dwn = [LQAsynDownload initWithURL:[[NSURL alloc] initWithString:@"http://a.hiphotos.baidu.com/image/w%3D2048/sign=fae75ab5d63f8794d3ff4f2ee6230ff4/faedab64034f78f09f9423fe7b310a55b3191c1b.jpg"]]; dwn.initProgress = ^(long long initValue){
_sum = initValue;
NSLog(@"%lli",initValue);
_rcv = ;
dispatch_async(dispatch_get_main_queue(), ^{
self.pv.progress = 0.0;
self.pv.hidden = NO;
});
}; dwn.loadedData = ^(long long loadedLength){
dispatch_async(dispatch_get_main_queue(), ^{
if (_rcv == _sum) {
self.pv.hidden = YES;
} else {
_rcv += loadedLength;
self.pv.progress = _rcv/_sum;
}
});
}; [dwn startAsyn];
真相:
情人节第二个礼物:
以前觉得很神奇的野,用心去试试,会觉得很简单,不是吗?
ios专题 - 异步下载加下载进度显示的更多相关文章
- iOS Cell异步图片加载优化,缓存机制详解
最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载, ...
- NGUI的异步场景加载进度条
1.直接创建三个场景,其中第二个场景是用来显示进度条加载的界面,进度条用UISlider,不会的看我前面的博文就可以了. 2.这里提供两种方法,建议使用第一种,加载比较平缓 方法一: using Sy ...
- iOS 自定义任意形状加载进度条(水波纹进度条)
1. 项目中要做类似下面的加载动画: 先给出安卓的实现方式 2.iOS的实现方式参考了下面两位的,感谢. 以任意底部图片为背景的加载动画 和 水波纹动画 最后附上自己的demo
- iOS WKWebView添加网页加载进度条(转)
一.效果展示 WKWebProgressViewDemo.gif 二.主要步骤 1.添加UIProgressView属性 @property (nonatomic, strong) WKWebView ...
- BackgroundWorker实现的winfrom中实现异步等待加载图片显示
BackgroundWorker简介 BackgroundWorker在winfrom中有对应控件,该有三个事件:DoWork .ProgressChanged 和 RunWorkerCompl ...
- WPF 客户端浏览器 添加Loading加载进度
在windows开发界面时,使用浏览器来请求和显示网页内容,是比较常见的. 但是在请求网页内容时,因网速或者前端功能复杂加载较慢,亦或者加载时遇到各种问题,如空白/黑屏/加载不完整/证书问题等. 因此 ...
- 灵活、可高度自定义的——Progress进度圈、弹窗、加载进度、小菊花
DDProgressHUD的介绍 提供了四种类型的展示: 显示无限旋转的加载图(比如小菊花,可以自定义),显示文字信息.网络刷新时经常用到. 显示加载进度的动画,也可以显示文字.网络下载时用的比较多, ...
- 《C/C++实现Console下的加载进度条模拟[美观版]》
前言 有时候我们会遇到在CMD或DOS控制台上出现的加载进度条,虽然不是如网页和软件写的美观.但确确实实也有着自己的特色.而且,一个好看的加载进度条也能增加用户使用控制台程序的体验!所以,拿来研究 ...
- IOS GCD图片数据异步下载,下载完成后合成显示
关于GCD使用详解,请看我的上一篇blog:http://www.cnblogs.com/xin-lang/p/6278606.html 前段时间遇到个需要异步下载,下载完成后再组合显示的东西.这里我 ...
随机推荐
- 【CSS】Beginner4:Text
1.alter the size and shape of the text 2.font-family:Arial, Verdana,"Times New Roman",helv ...
- nyoj 括号匹配
这个方程有两种形式,本文采用 if(s[i]=s[j]) dp[i][j]=d[i-1][j-1] dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]) (i=&l ...
- ssh,telnet远程AIX以及数据传输问题
(1)telnet远程 输入:telnet 目标IP 输入用户名,密码 进入远程机器 (2)AIX默认安装ftp,使用ftp传输数据 ftp 目标IP地址 输入用户名,密码(远程服务器的) 或者输入f ...
- org.apache.hadoop.hbase.TableNotDisabledException 解决方法
Exception in thread "main" org.apache.hadoop.hbase.TableNotDisabledException: org.apache.h ...
- 把普通的git库变成bare库
$ cd your_repo $ mv .git .. && rm -fr * $ mv ../.git . $ mv .git/* . $ rmdir .git $ git conf ...
- glusterfs repo
Installing Gluster For RPM based distributions, if you will be using InfiniBand, add the glusterfs R ...
- PHP魔术方法总结
1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ...
- 【三支火把】---一份程序看懂C程序printf()的几种常用用法
闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...
- libpcre.so.1 cannot be found
安装完Nginx之后,启动报错. [vagrant@localhost sbin]$ sudo ./nginx ./nginx: error while loading shared librarie ...
- 亿级数据时,内存性能低于IO性能
最近因项目需要,需要生成有0到99999999共1亿的不重复数,于是想着直接将这些数据生成为一个文件就可以了,代码如. private void generate(string savePath) { ...