您的位置:首页 > 理论基础 > 计算机网络

ASIHttpReqestX框架

2013-10-16 12:48 288 查看

下载ASIHTTPRequest:

Github project page: http://github.com/pokeb/asi-http-request/tree Download the latest version: http://github.com/pokeb/asi-http-request/tarball/master License (BSD): http://github.com/pokeb/asi-http-request/tree/master/LICENSE Google Group: http://groups.google.com/group/asihttprequest Lighthouse bug base: http://allseeing-i.lighthouseapp.com/projects/27881/home 相关资料 http://allseeing-i.com/ASIHTTPRequest/How-to-use - Using blocks

Blocks Programming Topics - Object and Block Variables

类库的依赖关系:

ASIHTTP类库依赖于以下5个框架或库:

CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics 和 libz1.2.3。

及一个网络操作源码:

Reachability.h (在源码的 External/Reachability 目录下)

Reachability.m (在源码的 External/Reachability 目录下)

库文件:

认证对话框

ASIAuthenticationDialog.h

ASIAuthenticationDialog.m

缓存代理接口
ASICacheDelegate.h

[plain]
view plaincopy

typedef enum _ASICachePolicy {

<span style="color:#009900;">// The default cache policy. When you set a request to use this, it will use the cache's defaultCachePolicy
// ASIDownloadCache's default cache policy is 'ASIAskServerIfModifiedWhenStaleCachePolicy'
</span> ASIUseDefaultCachePolicy = 0,

<span style="color:#009900;">// Tell the request not to read from the cache
</span> ASIDoNotReadFromCacheCachePolicy = 1,

<span style="color:#009900;">// The the request not to write to the cache
</span> ASIDoNotWriteToCacheCachePolicy = 2,

<span style="color:#009900;">// Ask the server if there is an updated version of this resource (using a conditional GET) ONLY when the cached data is stale
</span> ASIAskServerIfModifiedWhenStaleCachePolicy = 4,

<span style="color:#009900;">// Always ask the server if there is an updated version of this resource (using a conditional GET)
</span> ASIAskServerIfModifiedCachePolicy = 8,

<span style="color:#009900;">// If cached data exists, use it even if it is stale. This means requests will not talk to the server unless the resource they are requesting is not in the cache
</span> ASIOnlyLoadIfNotCachedCachePolicy = 16,

<span style="color:#009900;">// If cached data exists, use it even if it is stale. If cached data does not exist, stop (will not set an error on the request)
</span> ASIDontLoadCachePolicy = 32,

<span style="color:#009900;">// Specifies that cached data may be used if the request fails. If cached data is used, the request will succeed without error. Usually used in combination with other options above.
</span> ASIFallbackToCacheIfLoadFailsCachePolicy = 64
} ASICachePolicy;

枚举类型中的策略值:

策略可以进行组合

如:

[request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy|ASIDoNotWriteToCacheCachePolicy];

但注意:

调用[ASIHTTPRequest clearSession]将会删除任何使用ASICacheForSessionDurationCacheStoragePolicy策略的缓存数据。

使用ASICachePermanentlyCacheStoragePolicy,缓存的相应数据会被永久存储。要使用这个存储策略,向request设置:

[objc]
view plaincopy

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

要手动清除cache,调用函数clearCachedResponsesForStoragePolicy:,传入要清除的cache数据的存储策略:

[objc]
view plaincopy

[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

ASIUseDefaultCachePolicy 0 默认情况下的缓存策略(它不能与其它策略组合使用)

ASIDoNotReadFromCacheCachePolicy 1 当前请求不读取缓存数据。

ASIDoNotWriteToCacheCachePolicy 2 当前请求不写缓存数据。

ASIAskServerIfModifiedWhenStaleCachePolicy 4 默认缓存行为,request会先判断是否存在缓存数据,如果没有再进行网络请求。 如果存在缓存数据,并且数据没有过期,则使用缓存。如果存在缓存数据,但已经过期,request会先进行网络请求,判断服务器版本与本地版本是否一样,如果一样,则使用缓存。如果服务器有新版本,会进行网络请求,并更新本地缓存。(使用GET请求时有效)
ASIAskServerIfModifiedCachePolicy 8 每次请求都会 去服务器判断是否有更新。(使用GET请求时有效)
ASIOnlyLoadIfNotCachedCachePolicy 16 只要有缓存,就读取缓存数据而不管数据是否过期。直到请求的数据不在缓冲中时,才去服务器获取。
ASIDontLoadCachePolicy 32 只要有缓存,就读取缓存数据而不管数据是否过期。如果缓存中没有数据,则停止,不向服务器请求。
ASIFallbackToCacheIfLoadFailsCachePolicy 64 这个选项经常被用来与其它选项组合使用。请求失败时,使用本地缓存数据,如果使用本地缓冲,请求会成功不会引发错误(这个在处理异常时非常有用)

对代理方法可以见下载代理源码。里机的实现是很好的学习例子。是继承ASICacheDelegate的。
ASIDownloadCache.h

ASIDownloadCache.m

[plain]
view plaincopy

它对Get请求的响应数据进行缓存(被缓存的数据必需是成功的200请求):

[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];

当设置缓存策略后,所有的请求都被自动的缓存起来。
另外,如果仅仅希望某次请求使用缓存操作,也可以这样使用:

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];

多种的缓存并存
仅仅需要创建不同的ASIDownloadCache,并设置缓存所使用的路径,并设置到需要使用的request实例中:

ASIDownloadCache *cache = [[[ASIDownloadCache alloc] init] autorelease];
[cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];
[self setMyCache:cache];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[self myCache]];

数据压缩:支持对bytes和流数据,文件数据压缩

ASIDataCompressor.h

ASIDataCompressor.m
数据解压:支持对bytes和流数据,文件数据压缩

ASIDataDecompressor.h
ASIDataDecompressor.m

进度条代里:通过这代里设置,可以实现进度条效果。如上传下载进度
ASIProgressDelegate.h

将数据输为数据流进行操作。
ASIInputStream.h

ASIInputStream.m

存放ASI调试开关宏定义
ASIHTTPRequestConfig.h

请求响应代理:

ASIHTTPRequestDelegate.h

[plain]
view plaincopy

@protocol ASIHTTPRequestDelegate <NSObject>

@optional

<span style="color:#009900;">// These are the default delegate methods for request status
// You can use different ones by setting didStartSelector / didFinishSelector / didFailSelector
</span>- (void)requestStarted:(ASIHTTPRequest *)request;
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders;
- (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL;
- (void)requestFinished:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;
- (void)requestRedirected:(ASIHTTPRequest *)request;

<span style="color:#009900;">// When a delegate implements this method, it is expected to process all incoming data itself
// This means that responseData / responseString / downloadDestinationPath etc are ignored
// You can have the request call a different method by setting didReceiveDataSelector
</span>- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;

<span style="color:#009900;">// If a delegate implements one of these, it will be asked to supply credentials when none are available
// The delegate can then either restart the request ([request retryUsingSuppliedCredentials]) once credentials have been set
// or cancel it ([request cancelAuthentication])
</span>- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request;
- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request;

@end

- (void)requestStarted:(ASIHTTPRequest *)request;
当开始发起请求时触发,request为当前请求的上下文。

- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders;
当请求后收到响应头时触发,request为请求的上下文,responseHeaders存放HTTP响应的头域

对头域的提取可以使用如下方法:

[plain]
view plaincopy

[request responseStatusCode];
[[request responseHeaders] objectForKey:@"X-Powered-By"];
[request responseEncoding];

- (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL;
当请求一URL时,服务器响应重定向,跳转到新URL前触发。

- (void)requestRedirected:(ASIHTTPRequest *)request;
重定向到新URL完成后触发。

- (void)requestFinished:(ASIHTTPRequest *)request;
本次请求完成功后触发。即一次有效会话完成。

- (void)requestFailed:(ASIHTTPRequest *)request;
请求失败时触发。可以能过NSError* err = [response error]得到错误信息。

- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;
单次有接收数据时触发。(如果数据过长就会分块进行传输)这个也可以自己来实现进度条效果。

例子:

[plain]
view plaincopy

-(void)Down
{
NSString* paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];

NSString* filename = @"fileOk.zip";

NSString* filepath = [paths stringByAppendingPathComponent:filename];

//创建路径及空文件
bool ret = [[NSFileManager defaultManager] createFileAtPath:filepath contents:nil attributes:nil];

NSFileHandle* fhandle; //文件句柄

__block uint fileszie = 0;//初始化文件大小

if (ret) {
fhandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}

NSURL* url = [NSURL URLWithString:@"http://dd2.pc6.com/xy1/6000ICO.rar"];

ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];

[request setShouldContinueWhenAppEntersBackground:YES];

[request setDownloadProgressDelegate:progressview];

[request setCompletionBlock:^{
NSLog(@"Completed!");

assert(fhandle);

[fhandle closeFile];
}];

[request setFailedBlock:^{
NSLog(@"download failed !");
}];

<span style="color:#ff0000;">[request setDataReceivedBlock:^(NSData* data){
fileszie += data.length;
NSLog(@"recive total : %@",[NSString stringWithFormat:@"%.1f K",fileszie/1000.0]);

if (fhandle != nil)
{
[fhandle seekToEndOfFile];//移到末端进行追加
[fhandle writeData:data];//写入当前数据块
}
}];
</span>
[request startAsynchronous];
}

红色部份就是回调。

- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request;
当本次请求后,服务响应要求客户端进行认证时触发。

- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request;
请求需要代理认证时触发。

通常这个代理类只有在开启HTTP异步时才有效,同步情况下不会触发这些回调。

HTTP请求类:(核心文件了对IOS网络通导进行了一层封装)
ASIHTTPRequest.h

ASIHTTPRequest.m

常用总结:
同步请求(这个用得较少,因为会阻塞,相信大家不想呆在哪里等吧。)
示例:

[plain]
view plaincopy

NSURL* url = [NSURL URLWithString:@"http://www.baidu.com"];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
//[request startSynchronous];//use 同步请求
NSError* err = [request error];
assert(!err);

NSString* responsestr = [request responseString];

异步请求:

[plain]
view plaincopy

NSURL* url = [NSURL URLWithString:@<a href="http://www.baidu.com">http://www.baidu.com</a>];

[plain]
view plaincopy

ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
<span style="color:#ff0000;">request.delegate = self;
</span> [request startAsynchronous];//异步请求

其中红色部分表明要实现代理的类的实例。因为放在调用者中进行实现回调代理,所以这里用self。当然也可以自己写一个专门的实现代理的类来处理。
回调方式一:使用代理类来实现ASIHTTPRequestDelegate.h中的方法。

设置这一句之后就可以把ASIHTTPRequestDelegate.h中的方法放到调用者中进行实现这些回调了。如:

[plain]
view plaincopy

//异步回调
-(void)requestFailed:(ASIHTTPRequest *)request
{
NSError* err = [request error];
NSLog(@"error info = %@",err.userInfo);
}

-(void)requestFinished:(ASIHTTPRequest *)request
{
NSString* result = [request responseString];
NSLog(@"Finised : %@",result);
}

-(void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
NSLog(@"rq : %@",responseHeaders);
}

上面的回调使用的是代理类的方式进行。对于异步请求,ASIHTTPRequest给我们提供了多种回调方式,任由开发者进行发挥。
回调方式二:
使用OC本身的block特性来进行提定。使用这种回调不需要指定delegate类。但个人认为这种方式跟踪起来看的有点费劲(个人习惯)。

[plain]
view plaincopy

NSURL* url = [NSURL URLWithString:@"http://www.baidu.com"];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
NSString* restr = [request responseString];
//NSData* data = [request responseData];
NSLog(@"%@",restr);
}];

[request setFailedBlock:^{
NSError* err = [request error];
NSLog(@"err = %@",err.userInfo);
}];

[request startAsynchronous];

一共有的回调定义(即函数指针)

[plain]
view plaincopy

#if NS_BLOCKS_AVAILABLE
typedef void (^ASIBasicBlock)(void);
typedef void (^ASIHeadersBlock)(NSDictionary *responseHeaders);
typedef void (^ASISizeBlock)(long long size);
typedef void (^ASIProgressBlock)(unsigned long long size, unsigned long long total);
typedef void (^ASIDataBlock)(NSData *data);
#endif

- (void)setStartedBlock:(ASIBasicBlock)aStartedBlock;

当开始发起请求时触发,request为当前请求的上下文。与- (void)requestStarted:(ASIHTTPRequest *)request;回调一样

- (void)setHeadersReceivedBlock:(ASIHeadersBlock)aReceivedBlock;

当请求后收到响应头时触发,request为请求的上下文,responseHeaders存放HTTP响应的头域,与
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders;的回调一样。

- (void)setCompletionBlock:(ASIBasicBlock)aCompletionBlock;

本次请求完成功后触发。即一次有效会话完成。与- (void)requestFinished:(ASIHTTPRequest *)request;回调一样。
- (void)setFailedBlock:(ASIBasicBlock)aFailedBlock;

- (void)setBytesReceivedBlock:(ASIProgressBlock)aBytesReceivedBlock;

当接收到字节数据时触发。

- (void)setBytesSentBlock:(ASIProgressBlock)aBytesSentBlock;

当有数据发送到服务器时触发。

- (void)setDownloadSizeIncrementedBlock:(ASISizeBlock)aDownloadSizeIncrementedBlock;

在进行下载前,需要动态增长下载块大小时触发。

- (void)setUploadSizeIncrementedBlock:(ASISizeBlock)anUploadSizeIncrementedBlock;

在上传数据前,需要动态增长数据块大小时触发。

- (void)setDataReceivedBlock:(ASIDataBlock)aReceivedBlock;

单次有接收数据时触发。(如果数据过长就会分块进行传输)这个也可以自己来实现进度条效果。与- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;回调一样。

- (void)setAuthenticationNeededBlock:(ASIBasicBlock)anAuthenticationBlock;

当本次请求后,服务响应要求客户端进行认证时触发。与- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request;回调一样。

- (void)setProxyAuthenticationNeededBlock:(ASIBasicBlock)aProxyAuthenticationBlock;

请求需要代理认证时触发。与- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request;回调一样。

- (void)setRequestRedirectedBlock:(ASIBasicBlock)aRedirectBlock;

重定向到新URL完成后触发。与- (void)requestRedirected:(ASIHTTPRequest *)request;回调一样。

回调方式三:通过选择器实现(SEL)有点像DELPHI中的事件回调的实现。
SEL didStartSelector;

SEL didReceiveResponseHeadersSelector;

SEL willRedirectSelector;

SEL didFinishSelector;

SEL didFailSelector;

SEL didReceiveDataSelector;

三种回调任先其一来进行相应的应用开发。当然大家也可以试试三种都设置后看优先触发哪种回调。

关于异步请求,响应的请求判断,通常情况下,并发数个请求,每个请求响应的先后顺序都不一样,哪么如何能正确的处理请求所对应的响应呢。方法有三:

1、使用回调方式一,通过回调方法中的request(上下文)中的userinfo这个来设置相应的请求ID或唯一身份。待响应回调中通过上下文(request)取出相应的userinfo来进行判断是哪个具体的请求。
2、使用方式二和方式三的回调方式,因为该回调是指定在当前对应的request中的。创建不同的实例时就可以通过实例的方式进行区分。
3、使用子类来定义相应的业务请求区分。

http访问代理设置:

[plain]
view plaincopy

request setProxyAuthenticationScheme:(NSString *);
request setProxyCredentials:(NSDictionary *);
request setProxyDomain:(NSString *);
request setProxyHost:(NSString *);
request setProxyPassword:(NSString *);
request setProxyPort:(int);
request setProxyType:(NSString *);
request setProxyUsername:(NSString *);

也可以通过PAC(Proxy Auto Config)文件来设置代理:

取消请求
对于异步操作时,可能大家也想到了,过程中的请求是否可以取消的问题。
对于异步操作是有取消,同步请求是没有取消的。

调用[request cancel];就可以进行取消正在进行的请求,取消时会触发请求失败的回调方法。如果在取消过程中不想触发该回调,可以将实例进行设置。如下:

[request clearDelegatesAndCancel];

如果使用ASINetworkQueue队列来管理请求实例。
取消所有请求,使用 [queue cancelAllOperations];

别外需要注意的:
队列请求中需要注意的是,如果你取消了一个请求,队列会自动取消其它所有请求。

[[[networkqueue operations]objectAtIndex:1] cancel]; 如果这样操作会把所有的请求都取消了。
如果只需要想要的请求怎么办。只需要设置:[ queue setShouldCancelAllRequestsOnFailure:NO ];即可。设置完成后,调用[[[networkqueue operations]objectAtIndex:1] cancel];就会把第二个请求取消了。而其它请求仍在进行。

异步下载代码段:

[plain]
view plaincopy

-(void)downbtnclicked
{
NSString* paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)objectAtIndex:0];
paths = [paths stringByAppendingFormat:@"/down.zip"];

NSURL* url = [NSURL URLWithString:@"http://dd2.pc6.com/xy1/6000ICO.rar"];

ASIHTTPRequest* rq = [ASIHTTPRequest requestWithURL:url];
//[rq setShouldContinueWhenAppEntersBackground:YES];//退到后台仍运行
[rq setTimeOutSeconds:20];
[rq setDownloadDestinationPath:paths];//设置下载存放路径
NSLog(@"paths = %@",paths);

[rq setDownloadProgressDelegate:progressview];//设置下载进度,这里progrssview为UIProgressView

[rq setFailedBlock:^{
NSError* err = [rq error];
NSLog(@"errinfo = %@",err.userInfo);
}];
[rq startAsynchronous];
}

cookie的支持
如果Cookie存在的话,会把这些信息放在NSHTTPCookieStorage容器中共享,并供下次使用。

你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies。

当然,你也可以取消默认的Cookie策略,而使自定义的Cookie:

表单数据请求:

ASIFormDataRequest.h

ASIFormDataRequest.m

对Request的扩展,主要处理页面的表单数据的提交。通常适用于"POST"和"PUT"操作。

[plain]
view plaincopy

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"15967287719" forKey:@"phonenums"];
[request setPostValue:@"男" forKey:@"sex"];
[request setFile:@"/Users/xxx/Desktop/avatar.jpg" forKey:@"photo"];
[request addData:imageData withFileName:@"avatar.jpg" andContentType:@"image/jpeg" forKey:@"photos"];

[plain]
view plaincopy

默认为"POST"方式。如果想改为"PUT"调用:<code class="java plain">[request setRequestMethod:@</code><code class="java string">"PUT"</code><code class="java plain">];即可。</code>

上传代码段:

[plain]
view plaincopy

-(void)btnuploadclicked
{
NSString* ps = @"test";
NSURL* serverurl = [NSURL URLWithString:@<a href="http://xxxxxxxxx">http://xxxxxxxxx</a>];
formrequest = [ASIFormDataRequest requestWithURL:serverurl];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingMacChineseSimp);

[formrequest setStringEncoding:encoding];
[self printfBytes:ps Encoding:encoding];

[formrequest setPostValue:ps forKey:@"title"];
[formrequest setFile:@"/user/ffsh/Desktop/test.zip" forKey:@"attch"];

[formrequest setDelegate:self];
[formrequest setDidFinishSelector:@selector(OnRequestFinished)];
[formrequest setDidFailSelector:@selector(OnRequestFaided)];

[formrequest startAsynchronous];

}

网络请求队列,便于管理多个异步请求。

ASINetworkQueue.h

ASINetworkQueue.m

查看源文件可以看出ASINetworkQueue可以看作一个线程池,可以设置线程挂起和恢复。而ASIHttpRequest就是一个操作NSOperation ,其实可以当作为一个任务,这样就有点像线程池任务队列了。
每个ASIhttpRequest中实现了自己的-(void)main方法。
从该方法中可以看到最终的请求是使用CFNewWork中的CFHTTPMessageCreateRequest

[plain]
view plaincopy

// Create a new HTTP request.
request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (CFStringRef)[self requestMethod], (CFURLRef)[self url], [self useHTTPVersionOne] ? kCFHTTPVersion1_0 : kCFHTTPVersion1_1);
if (!request) {
[self failWithError:ASIUnableToCreateRequestError];
return;
}

在最后执行请求:

[plain]
view plaincopy

// If we immediately have access to proxy settings, start the request
// Otherwise, we'll start downloading the proxy PAC file, and call startRequest once that process is complete
if ([self configureProxies]) {
[self startRequest];
}

如果大家对NSOperationQueue和NSOperation使用不熟悉的,可以学习一下,再来看这两个文件,就简单些了。

多个请求例子:

[plain]
view plaincopy

-(void)goclicked
{
if(!fm)
{
fm = [NSFileManager defaultManager];
}

NSString* paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];

//NSLog(@"paths = %@",paths);
NSString* filenames = @"filedown.zip";

NSString* filepath = [paths stringByAppendingPathComponent:filenames];

bool ret = [fm createFileAtPath:filepath contents:nil attributes:nil];

NSFileHandle* fhandle;

__block uint fSize1 = 0;

if (ret) {
fhandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}

NSString* filename2 = @"file.zip";
NSString* filepath2 = [paths stringByAppendingPathComponent:filename2];

ret = [fm createFileAtPath:filepath2 contents:nil attributes:nil];

NSFileHandle* fhd;

__block uint fSize2 = 0;

if (ret) {
fhd = [NSFileHandle fileHandleForWritingAtPath:filepath2];
}

NSURL* url = [NSURL URLWithString:@"http://dd2.pc6.com/xy1/6000ICO.rar"];

NSURL* url2 = [NSURL URLWithString:@"http://dd2.pc6.com/xy1/6000ICO.rar"];

if (!networkqueue) {
networkqueue = [[ASINetworkQueue alloc]init];
}

failed = NO;

[networkqueue reset];//清空队列
[networkqueue setDownloadProgressDelegate:totalprogressview];
[networkqueue setShowAccurateProgress:YES];//进步精确显示
[networkqueue setDelegate:self];

ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];

[request setShouldContinueWhenAppEntersBackground:YES];

[request setDownloadProgressDelegate:progressview];
[request setUserInfo:[NSDictionary dictionaryWithObject:filenames forKey:@"TargetPath"]];

[request setCompletionBlock:^{
NSLog(@"%@ Completed!",filenames);

assert(fhandle);

[fhandle closeFile];
}];

[request setFailedBlock:^{
NSLog(@"%@ download failed !",filenames);
}];

[request setDataReceivedBlock:^(NSData* data){
fSize1 += data.length;
[progressone setText:[NSString stringWithFormat:@"%.1f K",fSize1/1000.0]];
[totalsize setText:[NSString stringWithFormat:@"%.0f%%",totalprogressview.progress*100]];

if (fhandle != nil)
{
[fhandle seekToEndOfFile];
[fhandle writeData:data];
}

NSLog(@"%@:%u",filenames,data.length);
}];

[networkqueue addOperation:request];

request = [ASIHTTPRequest requestWithURL:url2];
[request setShouldContinueWhenAppEntersBackground:YES];
[request setDownloadProgressDelegate:progress];
[request setUserInfo:[NSDictionary dictionaryWithObject:filename2 forKey:@"TargetPath"]];

[request setCompletionBlock:^{
NSLog(@"%@ Completed!",filename2);

assert(fhd);

[fhd closeFile];
}];

[request setFailedBlock:^{
NSLog(@"%@ download failed !",filename2);
}];

[request setDataReceivedBlock:^(NSData* data){
fSize2 += data.length;
[progresstwo setText:[NSString stringWithFormat:@"%d b",fSize2/*/1024.0*/]];
[totalsize setText:[NSString stringWithFormat:@"%.0f%%",totalprogressview.progress*100]];

if (fhd != nil)
{
[fhd seekToEndOfFile];
[fhd writeData:data];
}

}];

[networkqueue addOperation:request];
[networkqueue go];
}

请求中止,或应该用退出前,最好先把所有请求取消。加强对内存回的安全性。

另外:ASI目前团队已不维护ASI库,在后续的SDK4.5及IOS6.0的版本里,很多接口已被废弃。所在在高版本下使用ASI需要谨慎。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: