使用NSURLSession下载多个文件

时间:2017-04-06 03:49:11

标签: ios objective-c iphone nsurlsession

我想逐个从服务器的url数组中下载多个文件。

我需要显示每个下载文件的进度,用户也可以在其中取消它。

ViewControllerh:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    IBOutlet UIView *vw_download;
    IBOutlet UILabel *lbl_BookTitle;
    IBOutlet UILabel *lbl_BookDes;
    IBOutlet UILabel *lbl_downloadStatus;
    IBOutlet UIImageView *img_todownload;
    IBOutlet UIProgressView *vw_downloadbar;
    IBOutlet UIButton *btn_stopDownload;
}

-(IBAction)btn_stopDownloading:(id)sender;

@end

ViewController.m:

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDelegate> {
    NSMutableArray *downloadLinksArray;
    NSURLSession *session ;
    NSURLSessionDownloadTask *task;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    downloadLinksArray=[[NSMutableArray alloc]initWithObjects:@"URL1",@"URL2", @"URL3", @"URL4",  nil];

    [vw_downloadbar setProgress:0];
    lbl_downloadStatus.text=[NSString stringWithFormat:@"Downloading in Progress"];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(IBAction)startDownload:(id)sender {
    //[self startChapterDownLoad];

    for (int i=0;i< [downloadLinksArray count];i++) {
        NSURL *Url= [NSURL URLWithString:[NSString stringWithFormat:@"%@",[downloadLinksArray objectAtIndex:i]]];

        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

        session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

        NSURLRequest* request = [NSURLRequest requestWithURL:Url];

        task = [session downloadTaskWithRequest:request];

        [task resume];
    }
}

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    CGFloat percentDone = (double)totalBytesWritten/(double)totalBytesExpectedToWrite;
    // Notify user.

    [self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithFloat:percentDone] waitUntilDone:NO];
}

- (void) updateProgress:(NSNumber *)percent {
    [vw_downloadbar setProgress:percent.floatValue];
}

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    // Either move the data from the location to a permanent location, or do something with the data at that location.
}

-(IBAction)btn_stopDownloading:(id)sender {
    [task cancel];
    [vw_downloadbar setProgress:0];
}

1 个答案:

答案 0 :(得分:1)

如果你想下载多个文件,当它完成时你要通知:

请检查代码 - 使用NSFileManager:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession              *session       = [NSURLSession sessionWithConfiguration:configuration];

NSString      *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSFileManager *fileManager   = [NSFileManager defaultManager];

for (NSString *filename in self.filenames)
{
    NSURL *url = [baseURL URLByAppendingPathComponent:filename];
    NSURLSessionTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

        NSString *finalPath = [documentsPath stringByAppendingPathComponent:filename];

        BOOL success;
        NSError *fileManagerError;
        if ([fileManager fileExistsAtPath:finalPath]) {
            success = [fileManager removeItemAtPath:finalPath error:&fileManagerError];
            NSAssert(success, @"removeItemAtPath error: %@", fileManagerError);
        }

        success = [fileManager moveItemAtURL:location toURL:[NSURL fileURLWithPath:finalPath] error:&fileManagerError];
        NSAssert(success, @"moveItemAtURL error: %@", fileManagerError);

        NSLog(@"finished %@", filename);
    }];
    [downloadTask resume];
}

你可以选择:NSOperationQueue

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;

NSBlockOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self methodToCallOnCompletion];
    }];
}];

for (NSURL* url in urlArray)
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSData *data = [NSData dataWithContentsOfURL:url];
        NSString *filename = [documentsPath stringByAppendingString:[url lastPathComponent]];
        [data writeToFile:filename atomically:YES];
    }];
    [completionOperation addDependency:operation];
}

[queue addOperations:completionOperation.dependencies waitUntilFinished:NO];
[queue addOperation:completionOperation];

会显示下载文件的百分比:

你可以根据你的要求改变:(我没有测试过,但它会起作用)。

@property (nonatomic, retain) NSMutableData *dataToDownload;
@property (nonatomic) float downloadSize;

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];

    NSURL *url = [NSURL URLWithString: @"your url"];
    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithURL: url];

    [dataTask resume];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
    completionHandler(NSURLSessionResponseAllow);

    progressBar.progress=0.0f;
    _downloadSize=[response expectedContentLength];
    _dataToDownload=[[NSMutableData alloc]init];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [_dataToDownload appendData:data];
    progressBar.progress=[ _dataToDownload length ]/_downloadSize;
}