【问题标题】:Get MBProgressHUD's progress from NSURL从 NSURL 获取 MBProgressHUD 的进度
【发布时间】:2016-05-19 10:08:16
【问题描述】:

我正在尝试计算我的下载方法的进度并在文件下载期间显示MBProgressHUD的进度,但我不知道如何计算进度浮动!这是我的代码:

- (IBAction)preview:(id)sender {

    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];

    // Set determinate mode
    HUD.mode = MBProgressHUDModeAnnularDeterminate;

    HUD.delegate = self;
    HUD.labelText = @"Loading";

    // myProgressTask uses the HUD instance to update progress
    [HUD showWhileExecuting:@selector(downloadDataFromMac) onTarget:self withObject:nil animated:YES];

}


- (void)downloadData {

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    NSURL *URL = [NSURL URLWithString:pathWithData];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {

        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];


    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {

        NSLog(@"File downloaded to: %@", filePath);

        //Hide HUD
        [HUD hide:YES];

            self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:filePath];

            [self.documentInteractionController setDelegate:self];

            [self.documentInteractionController presentPreviewAnimated:YES];

        }];


    [downloadTask resume];

}

已编辑:

- (void)downloadDataFromMac {

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    NSURL *URL = [NSURL URLWithString:pathWithData];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    NSProgress *progress;
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {

        [progress addObserver:self
                   forKeyPath:@"fractionCompleted"
                      options:NSKeyValueObservingOptionNew
                      context:NULL];

        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];

        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];



    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {

        NSLog(@"File downloaded to: %@", filePath);

        //Hide HUD
        [HUD hide:YES];

            self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:filePath];

            [self.documentInteractionController setDelegate:self];

            [self.documentInteractionController presentPreviewAnimated:YES];

        }];


    [downloadTask resume];

}



- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"fractionCompleted"]) {
        NSProgress *progress = (NSProgress *)object;
        NSLog(@"Progress… %f", progress.fractionCompleted);
        //do something with your progress here, for eg :
        //but dont forget to first make HUD a class property so you can update it
        [HUD setProgress:progress.fractionCompleted];

    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

【问题讨论】:

    标签: ios objective-c nsurl nsurlsession mbprogresshud


    【解决方案1】:

    您可以使用 RSNetworkKit。它具有所有与网络相关的调用、下载和上传文件的所有便捷方法。它在内部实现了 AFNetworking。

    https://github.com/rushisangani/RSNetworkKit

    RSDownlaodManager 有一个方法可以下载任何有进度的文件 你可以像这样简单地使用。

    [[RSDownloadManager sharedManager] downloadWithURL:@"URLString" downloadProgress:^(NSNumber *progress) {
    
    // show progress using HUD here
    // must use main thread to show progress or update UI.
    
    } success:^(NSURLResponse *response, NSURL *filePath) {
    
    } andFailure:^(NSError *error) {
    
    }];
    

    【讨论】:

    • 我下载了框架,但按照安装,但仍然得到这个错误RSNetworkKit.h not found !!!!!!!!!
    • 你试过导入 吗?
    • 是的!看来你是开发者,能给我发一个示例项目吗?你为什么让安装这么复杂?!
    • 是的,我已经更新了安装步骤。如果您仍然发现任何问题,请检查并告诉我。这很容易!!。只需在项目文件夹中创建一个 lib 文件夹,将框架放入该文件夹,将该框架拖放到您的项目中并在项目设置中设置一些标志。就这样!!
    • 还添加了示例以供参考。谢谢!!
    【解决方案2】:

    您可以将 NSProgress 属性添加到 NSURLSessionDownloadTask 定义中,然后您可以使用 KVO 观察该属性。因此,在创建下载任务之前,创建属性并将其添加到定义中,如下所示:

    NSProgress *progress;
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
    
    
    
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    
        NSLog(@"File downloaded to: %@", filePath);
    
        //Hide HUD
        [HUD hide:YES];
    
            self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:filePath];
    
            [self.documentInteractionController setDelegate:self];
    
            [self.documentInteractionController presentPreviewAnimated:YES];
    
        }];
    
    [progress addObserver:self
            forKeyPath:@"fractionCompleted"
               options:NSKeyValueObservingOptionNew
               context:NULL];
    [downloadTask resume];
    

    然后要观察该进度属性的变化,请将此方法添加到您的类中:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"fractionCompleted"]) {
        NSProgress *progress = (NSProgress *)object;
        NSLog(@"Progress… %f", progress.fractionCompleted);
        //do something with your progress here, for eg :
        //but dont forget to first make HUD a class property so you can update it
        [self.hud setProgress:progress.fractionCompleted];
    
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
    }
    

    【讨论】:

    • 谢谢,但我收到此错误'NSProgress *__strong *' to parameter of incompatible type 'void (^ _Nullable)(NSProgress * _Nonnull __strong)'
    • 你能发布你定义NSURLSessionDownloadTask的代码吗? (与块等的整个事情)
    • 太奇怪了!!!我刚刚检查了每一个类似的问题,所有的答案都是一样的!没有错误!为什么我会收到这个错误!!!
    • 对不起,Mc.Lover,离开了。这是因为您正在块内注册 KVO。我应该更具体。代码行 [progress addObserver.. ] 需要超出该定义。因此,在调用 [downloadTask resume] 之前,将这行代码移到定义之外,向下移动到底部
    • @LukeSmith 我使用了你的代码,但仍然错误'NSProgress *__strong *'到不兼容类型'void(^ _Nullable)(NSProgress * _Nonnull __strong)'的参数。请帮助我。
    猜你喜欢
    • 2015-04-06
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    相关资源
    最近更新 更多