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=0;
    _receiveLength=0;
    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:0];
    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

 1 //
 2 //  LQAsynDownload.h
 3 //  lgTest
 4 //
 5 //  Created by yons on 14-2-14.
 6 //  Copyright (c) 2014年 GQ. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 typedef void (^initProgress)(long long initValue);
12
13 typedef void (^loadedData)(long long loadedLength);
14
15 @interface LQAsynDownload : NSObject<NSURLConnectionDataDelegate>
16
17 @property (strong) NSURL *httpURL;
18
19 @property (copy) void (^initProgress)(long long initValue);
20
21 @property (copy) void (^loadedData)(long long loadedLength);
22
23 + (LQAsynDownload *) initWithURL:(NSURL *) url;
24
25 - (void) startAsyn;
26
27 @end

LQAsynDownload.m

 1 //
 2 //  LQAsynDownload.m
 3 //  lgTest
 4 //
 5 //  Created by yons on 14-2-14.
 6 //  Copyright (c) 2014年 GQ. All rights reserved.
 7 //
 8
 9 #import "LQAsynDownload.h"
10
11 @interface LQAsynDownload()
12
13 @property (assign) long long contentLength;
14
15 @property (assign) long long receiveLength;
16
17 @property (strong) NSMutableData *receiveData;
18
19 @property (strong) NSString *fileName;
20
21 @property (strong) NSURLConnection *theConnection;
22
23 @property (strong) NSURLRequest *theRequest;
24
25 @end
26
27 @implementation LQAsynDownload
28
29 @synthesize receiveData = _receiveData, fileName = _fileName,
30             theConnection=_theConnection, theRequest=_theRequest;
31
32 + (LQAsynDownload *) initWithURL:(NSURL *) url{
33     LQAsynDownload *asynDownload = [[LQAsynDownload alloc] init];
34     asynDownload.theRequest=[NSURLRequest requestWithURL:url
35               cachePolicy:NSURLRequestUseProtocolCachePolicy
36                      timeoutInterval:60.0];
37     // create the connection with the request
38     // and start loading the data
39     return asynDownload;
40 }
41
42 - (void) startAsyn{
43     _contentLength=0;
44     _receiveLength=0;
45     self.receiveData = [[NSMutableData alloc] init];
46     self.theConnection = [[NSURLConnection alloc] initWithRequest:self.theRequest delegate:self];
47 }
48
49 //接收到http响应
50 - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
51     _contentLength = [response expectedContentLength];
52     _fileName = [response suggestedFilename];
53     if (self.initProgress != nil) {
54         self.initProgress(_contentLength);
55     }
56     NSLog(@"data length is %lli", _contentLength);
57 }
58
59 //传输数据
60 -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
61     _receiveLength += data.length;
62     [_receiveData appendData:data];
63     if (self.loadedData != nil) {
64         self.loadedData(data.length);
65     }
66     NSLog(@"data recvive is %lli", _receiveLength);
67 }
68
69 //错误
70 - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
71     [self releaseObjs];
72     NSLog(@"%@",error.description);
73 }
74
75 - (void) releaseObjs{
76     self.receiveData = nil;
77     self.fileName = nil;
78     self.theRequest = nil;
79     self.theConnection = nil;
80 }
81
82 //成功下载完毕
83 - (void) connectionDidFinishLoading:(NSURLConnection *)connection{
84     //数据写入doument
85     //获取完整目录名字
86     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
87     NSString *documentsDirectory = [paths objectAtIndex:0];
88     NSString *savePath = [NSString stringWithFormat:@"%@/%@",documentsDirectory, _fileName];
89     //创建文件
90     [_receiveData writeToFile:savePath atomically:YES];
91     [self releaseObjs];
92 }
93
94
95 @end

调用代码:

 1 LQAsynDownload *dwn = [LQAsynDownload initWithURL:[[NSURL alloc] initWithString:@"http://a.hiphotos.baidu.com/image/w%3D2048/sign=fae75ab5d63f8794d3ff4f2ee6230ff4/faedab64034f78f09f9423fe7b310a55b3191c1b.jpg"]];
 2
 3     dwn.initProgress = ^(long long initValue){
 4         _sum = initValue;
 5         NSLog(@"%lli",initValue);
 6         _rcv = 0;
 7         dispatch_async(dispatch_get_main_queue(), ^{
 8             self.pv.progress = 0.0;
 9             self.pv.hidden = NO;
10         });
11     };
12
13     dwn.loadedData = ^(long long loadedLength){
14         dispatch_async(dispatch_get_main_queue(), ^{
15             if (_rcv == _sum) {
16                 self.pv.hidden = YES;
17             } else {
18                 _rcv += loadedLength;
19                 self.pv.progress = _rcv/_sum;
20             }
21         });
22     };
23
24     [dwn startAsyn];

真相:

时间: 2024-10-23 05:19:07

iOS异步下载下载进度条显示的相关文章

异步下载圆形进度条显示进度

圆形进度条参考链接即可:使用css3实现圆形进度条 需求点击下载后遮罩层显示下载进度: 1.圆形进度条参考以上链接,有点小瑕疵,可更改定位距离实现重合. 2.遮罩层: .lbOverlay{ display: none; position: fixed; left: 0; top: 0; zoom: 1; background: black; z-index: 99999; width:100%; height:100%; filter:alpha(opacity=70); /*IE滤镜,透明度

Delphi下载指定网址(URL)的文件,带进度条显示

Delphi下载指定网址(URL)的文件,带进度条显示 发布于: 2012-12-26 11:21:04   |  发布在: Delphi文章   |  点击:626 主要使用的是Delphi自带的TIdhttp控件.一.界面设置在窗体上放置两个TEdit控件,一个用于输入要下载的文件URL,一个用于输入要保存到本地的文件路径:放置两个TLabel控件,一个显示文件总大小,一个显示当前已下载大小:放置一个按钮TButton,一个TIdhttp控件(在Indy Clients面板)和一个TIdAn

赵雅智_android多线程下载带进度条

progressBar说明 在某些操作的进度中的可视指示器,为用户呈现操作的进度,还它有一个次要的进度条,用来显示中间进度,如在流媒体播放的缓冲区的进度.一个进度条也可不确定其进度.在不确定模式下,进度条显示循环动画.这种模式常用于应用程序使用任务的长度是未知的. XML重要属性 android:progressBarStyle:默认进度条样式 android:progressBarStyleHorizontal:水平样式 progressBar重要方法 getMax():返回这个进度条的范围的

使用 new XMLHttpRequest() 制作下载文件进度条

mui 进度控件使用方法: 检查当前容器(container控件)自身是否包含.mui-progressbar类: 当前容器包含.mui-progressbar类,则以当前容器为目标控件,直接显示进度: 否则,检查当前容器的直接孩子节点是否包含.mui-progressbar类,若存在,则以遍历到的第一个含有.mui-progressbar类的孩子节点为目标控件,显示进度: 若当前容器的直接孩子节点,均不含.mui-progressbar类,则自动创建进度条控件: 如果有多个列表,每个列表在点击

AsyncTask的使用 (二)图片下载,进度条

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.Ht

recyclerView中多任务下载文件进度条更新的问题

在recyclerview或listview中进行下载时,由于条目复用等原因会导致下载的进度条更新错乱. 你可能觉得条目复用问题我解决过那么多次,加个tag了啥的就解决了不是. 有这个想法说明你没做过下载的处理.因为在下载的过程中,进度条是一直处于更新状态,所以传统的解觉条目复用的方式并不起作用. 解决方式有两种: 1.进度更新时把进度条进度存到bean中.然后在获取进度的循环中同步刷新adapter. 2.进度更新时把进度条进度存到bean中.写一个轮询刷新adapter.

C# 下载带进度条代码(普通进度条)

<span style="font-size:14px;"> </span><pre name="code" class="csharp"><span style="font-size:14px;"> /// <summary> /// 下载带进度条代码(普通进度条) /// </summary> /// <param name="URL&

【Android】读取sdcard卡上的全部图片而且显示,读取的过程有进度条显示

尽管以下的app还没有做到快图浏览.ES文件浏览器的水平,遇到大sdcard还是会存在读取过久.内存溢出等问题,可是基本思想是这种. 例如以下图.在sdcard卡上有4张图片, 打开app,则会吧sd卡上的全部图片读取,并显示出来.读取的过程有进度条显示. 制作步骤例如以下: 1.首先,res\values\strings.xml对字符设置例如以下,没有什么特别的. <? xml version="1.0" encoding="utf-8"?> <

【Android】读取sdcard卡上的所有图片并且显示,读取的过程有进度条显示

虽然下面的app还没有做到快图浏览.ES文件浏览器的水平,遇到大sdcard还是会存在读取过久.内存溢出等问题,但是基本思想是这样的. 如下图,在sdcard卡上有4张图片, 打开app,则会吧sd卡上的所有图片读取,并显示出来,读取的过程有进度条显示. 制作过程如下: 1.首先,res\values\strings.xml对字符设置如下,没有什么特别的. <?xml version="1.0" encoding="utf-8"?> <resour

Struts2 文件上传 进度条显示

参考成功博客:http://blog.sina.com.cn/s/blog_bca9d7e80101bkko.html 待测试博客:http://blog.csdn.net/z69183787/article/details/52536255 Struts2 文件上传 进度条显示