ios - 使用 NSURLSession 下载多个文件

标签 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];
}

最佳答案

如果您想下载多个文件,并且在完成后您想通知:

请使用 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;
}

关于ios - 使用 NSURLSession 下载多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43245369/

相关文章:

ios - iphone 在应用程序启动时获取设备方向

ios - 在 Swift 类中初始化 AnyObject 属性?

objective-c - Xcode 拒绝查看 appkey.c

ios - UIPageViewController 在访问 UITableView 内容后不加载页面内容

iphone - UIScrollView 底部的 UIButtons 未接收触摸

ios - 如何在 UITableview 中滚动时拆分数据并重新加载?

IOS:不快速调用完成的动画

iphone - 存档项目给我以下错误 : The identity 'iPhone Distribution:

iOS 6 Facebook 发布程序以 "remote_app_id does not match stored id"结束

iphone - 可编辑 Div 的字符限制