下载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
类库的依赖关系:
ASIHTTP类库依赖于以下5个框架或库:
CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics 和 libz1.2.3。
及一个网络操作源码:
Reachability.h (在源码的 External/Reachability 目录下)
Reachability.m (在源码的 External/Reachability 目录下)
库文件:
认证对话框
ASIAuthenticationDialog.h
ASIAuthenticationDialog.m
缓存代理接口
ASICacheDelegate.h
- 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设置:
- ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
- [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
要手动清除cache,调用函数clearCachedResponsesForStoragePolicy:,传入要清除的cache数据的存储策略:
- [[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
- 它对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
- @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响应的头域
对头域的提取可以使用如下方法:
- [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;
单次有接收数据时触发。(如果数据过长就会分块进行传输)这个也可以自己来实现进度条效果。
例子:
- -(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
常用总结:
同步请求(这个用得较少,因为会阻塞,相信大家不想呆在哪里等吧。)
示例:
- 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];
异步请求:
- NSURL* url = [NSURL URLWithString:@<a href="http://www.baidu.com">http://www.baidu.com</a>];
- ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
- <span style="color:#ff0000;">request.delegate = self;
- </span> [request startAsynchronous];//异步请求
其中红色部分表明要实现代理的类的实例。因为放在调用者中进行实现回调代理,所以这里用self。当然也可以自己写一个专门的实现代理的类来处理。
回调方式一:使用代理类来实现ASIHTTPRequestDelegate.h中的方法。
设置这一句之后就可以把ASIHTTPRequestDelegate.h中的方法放到调用者中进行实现这些回调了。如:
- //异步回调
- -(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类。但个人认为这种方式跟踪起来看的有点费劲(个人习惯)。
- 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];
一共有的回调定义(即函数指针)
- #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访问代理设置:
- 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 setPACurl:[NSURL URLWithString:@
"file:///Users/xxx/Desktop/proxys.pac"
]];
取消请求
对于异步操作时,可能大家也想到了,过程中的请求是否可以取消的问题。
对于异步操作是有取消,同步请求是没有取消的。
调用[request cancel];就可以进行取消正在进行的请求,取消时会触发请求失败的回调方法。如果在取消过程中不想触发该回调,可以将实例进行设置。如下:
[request clearDelegatesAndCancel];
如果使用ASINetworkQueue队列来管理请求实例。
取消所有请求,使用 [queue cancelAllOperations];
别外需要注意的:
队列请求中需要注意的是,如果你取消了一个请求,队列会自动取消其它所有请求。
[[[networkqueue operations]objectAtIndex:1] cancel]; 如果这样操作会把所有的请求都取消了。
如果只需要想要的请求怎么办。只需要设置:[ queue setShouldCancelAllRequestsOnFailure:NO ];即可。设置完成后,调用[[[networkqueue operations]objectAtIndex:1] cancel];就会把第二个请求取消了。而其它请求仍在进行。
异步下载代码段:
- -(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:
NSDictionary *properties = [[[NSMutableDictionary alloc] init] autorelease];
[properties setValue:[@
"Test Value"
encodedCookieValue] forKey:NSHTTPCookieValue];
[properties setValue:@
"ASIHTTPRequestTestCookie"
forKey:NSHTTPCookieName];
[properties setValue:@
".allseeing-i.com"
forKey:NSHTTPCookieDomain];
[properties setValue:[NSDate dateWithTimeIntervalSinceNow:
60
*
60
] forKey:NSHTTPCookieExpires];
[properties setValue:@
"/asi-http-request/tests"
forKey:NSHTTPCookiePath];
NSHTTPCookie *cookie = [[[NSHTTPCookie alloc] initWithProperties:properties] autorelease];
url = [NSURL URLWithString:@
"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"
];
request = [ASIHTTPRequest requestWithURL:url];
[request setUseCookiePersistence:NO];
[request setRequestCookies:[NSMutableArray arrayWithObject:cookie]];
[request startSynchronous];
NSLog(@
"%@"
,[request responseString]);
|
表单数据请求:
ASIFormDataRequest.h
ASIFormDataRequest.m
对Request的扩展,主要处理页面的表单数据的提交。通常适用于"POST"和"PUT"操作。
- 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"];
- 默认为"POST"方式。如果想改为"PUT"调用:<code class="java plain">[request setRequestMethod:@</code><code class="java string">"PUT"</code><code class="java plain">];即可。</code>
上传代码段:
- -(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
- // 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;
- }
在最后执行请求:
- // 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使用不熟悉的,可以学习一下,再来看这两个文件,就简单些了。
多个请求例子:
- -(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需要谨慎。