iOSProject icon indicating copy to clipboard operation
iOSProject copied to clipboard

关于文件 断点 缓存下载这个案例的一些问题

Open OmgKevin opened this issue 6 years ago • 9 comments

参考的您这个案例中我想要实现相同的需求,所以集中参考了您的LMJOfflineDownloadViewController.m这个类文件中的实现方式,但是有一些东西看的不是很明白。 image

OmgKevin avatar Sep 16 '19 12:09 OmgKevin

我这里是自定义cell image 在SDFileDownloadView.m的- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath方法中实现:

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { SDFileTableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath];

    [self cellDidSelectRow:cell];

}

  • (void) cellDidSelectRow :(SDFileTableViewCell *)cell {

    // 1.0先隐藏掉下载按钮 [cell.selectButton setHidden:YES]; // 1.1显示下载进度label [cell.downloadSpeedLabel setHidden:NO];

    // 2.1 下载文件url NSArray<NSString *> *urls = @[

      @"http://teaching.csse.uwa.edu.au/units/CITS4401/practicals/James1_files/SPMP1.pdf",
      @"http://down.51rc.com/dwndoc/WrittenExamination/WrittenExperiences/dwn00006795.doc",
      @"http://video1.remindchat.com/20190905/1gEji0Sv/mp4/1gEji0Sv.mp4",
      @"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4",
      @"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
      @"http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4",
    
     ];
    

    __weak typeof(self)weakSelf = self;

    [urls enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

      MJDownloadInfo *info = [[MJDownloadManager defaultManager] downloadInfoForURL:obj];
    
      if (info.state == MJDownloadStateCompleted) {
          // 下载完成之后,下载中图标更换为下载完成图标
          [cell.downloadSpeedLabel setHidden:YES];
          [cell.selectButton setHidden:NO];
          [cell.selectButton setImage:[UIImage imageNamed:@"downloadok"] forState:UIControlStateNormal];
      }else {
          // 未下载状态
          NSLog(@"222222222222");
      }
    
    
      if (info.state == MJDownloadStateResumed || info.state == MJDownloadStateWillResume) {
    
    
      } else if (info.state == MJDownloadStateSuspened || info.state == MJDownloadStateNone) {
    
          [[MJDownloadManager defaultManager] download:obj progress:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
    
              dispatch_async(dispatch_get_main_queue(), ^{
    
                  // 2.2 下载中进度显示
                  cell.downloadSpeedLabel.text = [NSString stringWithFormat:@"%.2f%%", (CGFloat)totalBytesWritten / totalBytesExpectedToWrite * 100.0];
    
              });
    
          } state:^(MJDownloadState state, NSString *file, NSError *error) {
    
              dispatch_async(dispatch_get_main_queue(), ^{
    
                  // 2.3 下载完成,改变按钮状态,保存下载文件路径,保存cell点击状态
                  if (state == MJDownloadStateCompleted) {
    
                      [cell.downloadSpeedLabel setHidden:YES];
                      [cell.selectButton setHidden:NO];
                      [cell.selectButton setImage:[UIImage imageNamed:@"downloadok"] forState:UIControlStateNormal];
    
    
                      NSLog(@"打印保存文件路径地址 :%@",file);
    
                  }
              });
          }];
    
      }else if (info.state == MJDownloadStateCompleted) {
    
          // 已下载完成的文件取url链接跳转阅读控制器
          NSString * filepath = [NSString stringWithFormat:@"%@",info.file];
    
          if ([self.delegate respondsToSelector:@selector(cellFilePathStr:)]) {
    
              // 移除下载列表视图
              [self removeFromSuperview];
              // 代理方法跳转阅读文档控制器
              [self.delegate cellFilePathStr:filepath];
          }
      }
    

    }]; }

发现点击一行cell时,可以正常实现下载文件,但是当我想实现多点击几行cell让它多文件同时下载的时候,不知道应该怎么去实现,希望得到您的帮助

OmgKevin avatar Sep 16 '19 12:09 OmgKevin

考虑到cell的复用问题; 建议您这里修改下, 优先更新模型数据, 再更新UI数据

NJHu avatar Sep 16 '19 15:09 NJHu

抱歉, 注释写的不是很清楚, 补了些注释, 看下还有什么疑问吗?

// 数据 NSArray<NSString *> *urls = @[ @"http://teaching.csse.uwa.edu.au/units/CITS4401/practicals/James1_files/SPMP1.pdf", @"http://down.51rc.com/dwndoc/WrittenExamination/WrittenExperiences/dwn00006795.doc", @"http://video1.remindchat.com/20190905/1gEji0Sv/mp4/1gEji0Sv.mp4", @"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4", @"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4", @"http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4", ];

self.title = @"点击Cell开始/暂停下载";
LMJWeak(self);
// 遍历URL个数创建对应的模型数组
[urls enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    
    // 获取下载文件对象
    MJDownloadInfo *info = [[MJDownloadManager defaultManager] downloadInfoForURL:obj];
    
    NSString *subTitle = nil;
    // 比对缓存是否下载完毕
    if (info.state == MJDownloadStateCompleted) {
        subTitle = @"播放";
    }else {
        // 比对缓存进度
        CGFloat progress = ((CGFloat)info.totalBytesWritten) / info.totalBytesExpectedToWrite * 100;
        subTitle = [NSString stringWithFormat:@"进度: %.2f%%, 点击开始", isnan(progress) ? 0 : progress];
    }
    
    // 添加数据模型, 和  绑定点击事件;
    // 考虑到cell的复用问题, 这个cell点击的时候, 调用了模型的itemOperation回调,
    self.addItem([LMJWordItem itemWithTitle:[obj.lastPathComponent substringToIndex:5] subTitle:subTitle itemOperation:^(NSIndexPath *indexPath) {
        
        // 文件下载状态: 下载中和在下载队列排队, 最大3个下载
        if (info.state == MJDownloadStateResumed || info.state == MJDownloadStateWillResume) {
            
            // 暂停
            [[MJDownloadManager defaultManager] suspend:info.url];
            
            // 获取进度
            CGFloat progress = ((CGFloat)info.totalBytesWritten) / info.totalBytesExpectedToWrite * 100;
            
            // 刷新模型
            weakself.sections.firstObject.items[indexPath.row].subTitle = [NSString stringWithFormat:@"暂停中..进度: %.2f%%", isnan(progress) ? 0 : progress];
            
            // 刷新UI, 获取不到就不刷新UI, 下次滚动cell赋值模型的时候, 还会刷新模型数据
            ((LMJSettingCell *)[weakself.tableView cellForRowAtIndexPath:indexPath]).item = weakself.sections.firstObject.items[indexPath.row];
            
        } else if (info.state == MJDownloadStateSuspened || info.state == MJDownloadStateNone) { // 暂停中和无状态; 开始下载
            
            // 开始下载obj = Url
            [[MJDownloadManager defaultManager] download:obj progress:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    // 更新模型
                    weakself.sections.firstObject.items[indexPath.row].subTitle = [NSString stringWithFormat:@"进度: %.2f%%", (CGFloat)totalBytesWritten / totalBytesExpectedToWrite * 100.0];

                    // 更新视图; 获取不到cell就不刷新UI, 下次滚动cell然后赋值模型的时候, 还会刷新模型数据
                    ((LMJSettingCell *)[weakself.tableView cellForRowAtIndexPath:indexPath]).item = weakself.sections.firstObject.items[indexPath.row];
                });
            } state:^(MJDownloadState state, NSString *file, NSError *error) {
                // 主线程刷新UI
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (state == MJDownloadStateCompleted) {
                        // 更新模型
                        weakself.sections.firstObject.items[indexPath.row].subTitle = @"播放";
                        // 更新视图; 获取不到cell就不刷新UI, 下次滚动cell然后赋值模型的时候, 还会刷新模型数据
                        ((LMJSettingCell *)[weakself.tableView cellForRowAtIndexPath:indexPath]).item = weakself.sections.firstObject.items[indexPath.row];
                    }
                });
            }];
            
        }else if (info.state == MJDownloadStateCompleted) { // 文件是下载完毕的状态
            // 跳转播放, 根据实际情况点击
            VIDMoviePlayerViewController *playerVc = [[VIDMoviePlayerViewController alloc] init];
            playerVc.videoURL = [NSString stringWithFormat:@"file://%@", info.file];
            [weakself.navigationController pushViewController:playerVc animated:YES];
            
        }
        
    }]);
}];

// 添加2个操作模型, 绑定模型itemOperation操作
self.addItem([LMJWordItem itemWithTitle:@"全部开始" subTitle: nil itemOperation:^(NSIndexPath *indexPath) {
    [[MJDownloadManager defaultManager] resumeAll];
}]).addItem([LMJWordItem itemWithTitle:@"全部暂停" subTitle: nil itemOperation:^(NSIndexPath *indexPath) {
    [[MJDownloadManager defaultManager] suspendAll];
}]);

NJHu avatar Sep 16 '19 15:09 NJHu

尝试用了您这边的数据试了试, 应该是可以的; 建议您参考下cell的数据刷新和赋值模型数据的逻辑

image

image

image

NJHu avatar Sep 16 '19 15:09 NJHu

我看到您给我回复了,这会手头没电脑,我先用手机回复吧哈。我看了您写的这块的代码,咱俩有不同的地方是,我这边是自定义了cell,用downloadcell管理。然后列表下载页面是写在view里面的用downloadview管理,然后table列表数据的代理方法也都写在view里了,目前还没有用到模型。然后,在用那个MJDownload封装类来对每一行cell点击时,都会自动添加到队列里去同时下载每一行各自管理下载进度并显示并且点每一行cell的时候,取到的是不同的path这个步骤不是很明白,明天到了我仔细看下你给我发的,或者我可以抽出来一个比较简洁的demo发给您看一下可以吗

在2019年09月16日 23:19,Nemo 写道: 尝试用了您这边的数据试了试, 应该是可以的; 建议您参考下cell的数据刷新和赋值模型数据的逻辑

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

OmgKevin avatar Sep 16 '19 15:09 OmgKevin

因为我的cell封装的没那么高层级,所以还只是停留在希望可以用比较简单的方式去实现这种多文件下载的需求😢

在2019年09月16日 23:29,邢坤坤 写道: 我看到您给我回复了,这会手头没电脑,我先用手机回复吧哈。我看了您写的这块的代码,咱俩有不同的地方是,我这边是自定义了cell,用downloadcell管理。然后列表下载页面是写在view里面的用downloadview管理,然后table列表数据的代理方法也都写在view里了,目前还没有用到模型。然后,在用那个MJDownload封装类来对每一行cell点击时,都会自动添加到队列里去同时下载每一行各自管理下载进度并显示并且点每一行cell的时候,取到的是不同的path这个步骤不是很明白,明天到了我仔细看下你给我发的,或者我可以抽出来一个比较简洁的demo发给您看一下可以吗

在2019年09月16日 23:19,Nemo 写道: 尝试用了您这边的数据试了试, 应该是可以的; 建议您参考下cell的数据刷新和赋值模型数据的逻辑

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

OmgKevin avatar Sep 16 '19 15:09 OmgKevin

明天demo发下哦, 上传到您自己的github的仓库

NJHu avatar Sep 16 '19 15:09 NJHu

ok,谢谢你辛苦哈,

在2019年09月16日 23:44,Nemo 写道:

明天demo发下哦, 上传到您自己的github的仓库

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

OmgKevin avatar Sep 16 '19 15:09 OmgKevin

您好,我这边已经将自己的demo上传至GitHub,地址 :https://github.com/OmgKevin/FileDownload ,请帮忙看一下呀,万分感谢

OmgKevin avatar Sep 17 '19 02:09 OmgKevin