系统文件下载(手机系统切换电脑版)


设计一个健壮的大文件下载系统

Compile : Bole Online-BEASTQ

如果需要

我希望NSScreencast iOS应用程序支持下载视频供离线使用。每个视频的大小在80-200 MB之间,所以需要构建一个健壮的下载系统。

第一步是添加下载按钮,在章节页面显示进度。类似于在iTunes里下载歌曲。点击下载按钮动画,进入循环下载进度指示器。下载在后台完成,并向订阅按钮发送进度通知,以在用户界面中显示进度百分比。

实际下载是通过“操作”子类完成的。这种方法提供了很大的便利,比如控制并发和服务优先级,并有一个方便的机制来取消运行中的下载。下载进度通过通知发送给外界,通知中包含章节ID,所有感兴趣的UIS都可以收听通知并进行更新。

当然,下载的时候不需要让用户盯着屏幕,用户可以自由切换应用甚至暂停,下载就可以继续。

接下来我需要在一个统一的位置显示待下载和之前的下载,方便查看哪些内容正在下载,哪些下载完成,可以离线观看和删除视频。

此页面在表格视图中以行的形式显示每一章的数据。收到下载进度更改通知时,每行显示的下载内容需要快速刷新。

为了实现上述功能,我将这个状态保存为核心数据模型。我的DownloadInfo模型是这样的:

有了Core Data,我们可以跟踪下载的整个生命周期状态。我以前使用过plists存储,但是(我敢说)核心数据比plists更容易存储。

这里,我在模型中存储下载进度百分比,但不重复存储值。在快速连接中,你会得到很多进度变化(每秒几十次),不需要每次都保存到Core Data。我只在取消请求时保存数据,想在UI里看到下载百分比。

将数据存储到核心数据的另一个优势是,我们可以使用NSFetchedResultsController快速构建下载视图控制器。

错误处理

所有涉及网络的操作都有出错的机会。下载大文件会加剧这种机会。人们走出Wi-Fi范围,进入隧道,乘坐飞机等很多事情都会干扰下载。为了确保最好的用户体验,我想对其进行处理,以允许用户快速重试(在某些情况下,是自动重试)。

当发生失败,把 DownloadInfo 的 state 标记为 .failed,UI 随之更新。单元格重载,用户可以点击重试该下载。

暂停和恢复

当 NSURLSession API 引入时,它就可以取消请求并产生一个不透明的对象,叫做 resume data。使用这种技术,你可以从它停下来的地方开始请求,唯一需要考虑的问题只是如何把该数据持久化,以备恢复下载。这样把该数据添加到我的 DownloadInfo 模型就很合适了。当用户点击正在进行的下载,会调用 downloadTask.cancel(byProducing:) 并保存 resume data 以供日后使用。

特别小心,参考IOs 10上的简历数据当前已损坏。

处理蜂窝网络

我不想有任何数据损坏,所以默认设置为无.然后设置一个标识符来切换值的状态,因为有些人可能想无限制地使用它。

使用FX可达性()监控网络连接状态。如果用户想下载蜂窝网络下的章节,我们会弹出切换设置,让下载继续。

保持模型和文件同步

因为我们将文件的元数据保存在磁盘上,所以我们需要确保元数据总是同步的。删除章节时,还必须删除磁盘核心数据中的模型。为了确保同步,我使用CleanupDownloadsOperation来检查是否有与磁盘上的部分相对应的下载信息(除非数据被删除),以及每个下载的文件是否记录在核心数据中(除非被删除)。

在这里,如果出现问题,两种状态(数据库/磁盘)必须解除同步。

后台下载

虽然看似简单,但后台下载会带来很多复杂混乱的情况。下一篇文章会讲这个话题。

他们说,加个离线下载就行了

本来想在app发布前给app加个离线下载功能的时候,发现需要多加一两天,挺复杂的。

我觉得这是软件开发。

看了这篇文章有收获吗?请更多人分享

关注“iOS大全”,提升iOS技能