ASIHTTPRequest是一个很常见的网络请求开源框架,虽然博主声明已经不更新,但目前来看依旧可以满足大部分需求。ASIHTTPRequest负责单独文件的下载,存储在iOS的文件系统中,比如Document目录下或者Cache目录。
ASINetworkQueue是下载队列,里面添加很多的单独的ASIHTTPRequest下载任务,可以更好的管理多个下载请求。
这里记录ASIHTTPRequest和ASINetworkQueue两者一起实现一个下载队列任务,按顺序依次下载很多首歌曲到Cache目录。
初始化队列
//初始化队列
ASINetworkQueue *networkQueueForSong = [[ASINetworkQueue alloc] init];
[networkQueueForSong reset];
//初始化待下载数组
NSMutableArray *toDownLoadFiles=[NSMutableArray arrayWithObjects:@”www.test1.com/song1.mp3″,@”www.test1.com/song2.mp3″,@”www.test1.com/song3.mp3″, nil];
//下载队列代理方法
[networkQueueForSong setRequestDidFailSelector:@selector(singleDownLoadFail:)];
[networkQueueForSong setRequestDidFinishSelector:@selector(singleDownloadFinished:)];
[networkQueueForSong setRequestDidReceiveResponseHeadersSelector:@selector(downLoadReceiveResponseHeader:)];
[networkQueueForSong setRequestDidStartSelector:@selector(singleDownLoadStart:)];
[networkQueueForSong setQueueDidFinishSelector:@selector(downLoadFinish)];
[networkQueueForSong setDelegate:self];
//设置下载队列属性,设置为1只允许下完一首再下另一首,默认是并行下载不分前后
[networkQueueForSong setMaxConcurrentOperationCount:1];
这里networkQueueForSong为初始化的队列,然后初始化了toDownLoadFiles这个下载资源的数组,里面是三首歌儿的示例url。队列的代理方法其实和单独的ASIHTTPRequest下载代理方法一样,比如setRequestDidFinishSelector这个方法的作用就是单独的每个下载完成的时候回调函数,在队列里设置了,下载就不需要单独设置了。最后ASINetworkQueue有一些自己的属性,比如常用的同时下载的数量设定,具体用法注释有写。
添加下载请求
//添加下载请求
for (int i=0; i<toDownLoadFiles.count; i++) {
NSURL *url=[NSURL URLWithString:[toDownLoadFiles objectAtIndex:i]];
ASIHTTPRequest *request=[ASIHTTPRequest requestWithURL:url];
NSString *savePath=[NSHomeDirectory() stringByAppendingPathComponent:@”Library/Caches”];
[request setDownloadDestinationPath:[savePath stringByAppendingPathComponent:[NSString stringWithFormat:@”offLineSong%@.mp3″,i]]];
[request setShouldContinueWhenAppEntersBackground:YES];
[request setUserInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@”songRequest”] forKey:@”name”]];
[request setTimeOutSeconds:120];
[request setNumberOfTimesToRetryOnTimeout:3];
[request setDelegate:self];
[networkQueueForSong addOperation:request];
}
添加下载请求是具体的每个下载内容的设置,这里需要设置下载路径Library/Caches,对于App的离线文件,这个是存储的路径,而不是Document需要注意,否则很可能被拒。方法setShouldContinueWhenAppEntersBackground顾名思义就是允许后台下载。对于下载时网络环境不好可能出现的复杂情况可以用setTimeOutSeconds这个方法来设置超时时间,超过这个时间才会被认定为失败,这里设置了2分钟,那么这个下载请求就会持续2分钟不被认为失败,如果失败了,方法setNumberOfTimesToRetryOnTimeout会规定重试几次。最后将这个下载的请求添加的队列networkQueueForSong中去。
在单个下载完成的代理方法里可以通过下面的方法记录下载完成的路径:
NSString *localPath=[request downloadDestinationPath];
开始下载
[networkQueueForSong go];
这样下载队列开始执行,会按照添加的顺序一个一个的下载,失败了重试三次,每个单独的下载,整个队列的下载都会有代理方法。
查看结果
如果越狱用户或者是模拟器可以直接通过工具或者命令行进入到Library/Caches查看下载是否成功,看看有没有下载的文件。如果没越狱的机器就没这个权限看了,可以通过NSFileManager打印出Library/Cache目录下内容来查看
//打印目录下文件
-(void)printOffLinePath{
//在这里获取应用程序Documents文件夹里的文件及文件夹列表
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
NSError *error = nil;
NSArray *fileList = [[NSArray alloc] init];
//fileList便是包含有该文件夹下所有文件的文件名及文件夹名的数组
fileList = [fileManager contentsOfDirectoryAtPath:documentDir error:&error];
NSLog(@” array %@”,fileList);
}
NSFileManager不仅仅是这个用途,它负责管理iOS的文件系统,比如需要删除的时候:
NSFileManager *defaultManager = [NSFileManager defaultManager];
[defaultManager removeItemAtPath:removeImgPath error:nil];
如果需要知道下载路径文件夹下文件的总大小,可以通过这个方法:
//计算路径下文件大小
-(float)currentOffLineSize{
NSString *savePath=[NSHomeDirectory() stringByAppendingPathComponent:@”Library/Caches”];
NSFileManager *filemgr;
NSArray *filelist;
int count;
float cacheSize = 0;
filemgr =[NSFileManager defaultManager];
filelist = [filemgr contentsOfDirectoryAtPath:savePath error:NULL];
count = [filelist count];
for (NSString *url in filelist) {
NSData *data = [filemgr contentsAtPath:[NSString stringWithFormat:@”%@/%@”,savePath,url]];
cacheSize = cacheSize + ([data length]/1000);
}
cacheSize = (cacheSize/1024);
return cacheSize;
}