类库的依赖关系:
ASIHTTP类库依赖于以下5个框架或库:
CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics 和 libz1.2.3。
及一个网络操作源码:
Reachability.h (在源码的 External/Reachability 目录下)
Reachability.m (在源码的 External/Reachability 目录下)
库文件:
认证对话框
typedef enum _ASICachePolicy { // 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' ASIUseDefaultCachePolicy = 0, // Tell the request not to read from the cache ASIDoNotReadFromCacheCachePolicy = 1, // The the request not to write to the cache ASIDoNotWriteToCacheCachePolicy = 2, // Ask the server if there is an updated version of this resource (using a conditional GET) ONLY when the cached data is stale ASIAskServerIfModifiedWhenStaleCachePolicy = 4, // Always ask the server if there is an updated version of this resource (using a conditional GET) ASIAskServerIfModifiedCachePolicy = 8, // 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 ASIOnlyLoadIfNotCachedCachePolicy = 16, // 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) ASIDontLoadCachePolicy = 32, // 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. 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 当前请求不读取缓存数据。
它对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]];
@protocol ASIHTTPRequestDelegate <NSObject> @optional // These are the default delegate methods for request status // You can use different ones by setting didStartSelector / didFinishSelector / didFailSelector - (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; // 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 - (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data; // 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]) - (void)authenticationNeededForRequest:(ASIHTTPRequest *)request; - (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request; @end
[request responseStatusCode]; [[request responseHeaders] objectForKey:@"X-Powered-By"]; [request responseEncoding];
-(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 !");
}];
[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];//写入当前数据块
}
}];
[request startAsynchronous];
}
红色部份就是回调。
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:@http://www.baidu.com];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
request.delegate = self;
[request startAsynchronous];//异步请求
//异步回调 -(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); }
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;
- (void)setHeadersReceivedBlock:(ASIHeadersBlock)aReceivedBlock;
- (void)setCompletionBlock:(ASIBasicBlock)aCompletionBlock;
- (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)setAuthenticationNeededBlock:(ASIBasicBlock)anAuthenticationBlock;
- (void)setProxyAuthenticationNeededBlock:(ASIBasicBlock)aProxyAuthenticationBlock;
- (void)setRequestRedirectedBlock:(ASIBasicBlock)aRedirectBlock;
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"
]];
-(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存在的话,会把这些信息放在NSHTTPCookieStorage容器中共享,并供下次使用。
你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies。
当然,你也可以取消默认的Cookie策略,而使自定义的Cookie:
//Create a 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];
//This url will return the value of the 'ASIHTTPRequestTestCookie' cookie
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];
//Should be: I have 'Test Value' as the value of 'ASIHTTPRequestTestCookie'
NSLog(@
"%@"
,[request responseString]);
|
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"调用:[request setRequestMethod:@
"PUT"
];即可。
上传代码段:
-(void)btnuploadclicked { NSString* ps = @"test"; NSURL* serverurl = [NSURL URLWithString:@http://xxxxxxxxx]; 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]; }
// 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]; }
多个请求例子:
-(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需要谨慎。