Swift 如何实现后台上传视频至 Firebase Storage 不阻塞客户端操作?
视频上传流程优化方案
现有代码的核心低效点
- 全程将用户交互阻塞在上传流程中,所有任务严格串行执行,没有利用iOS系统和Firebase原生的后台任务能力
- 流程顺序存在明显逻辑浪费:在20MB视频全部上传完成、拿到远程访问URL之后,才通过远程URL加载视频资源做帧抽取生成缩略图。这个操作本质是需要把刚上传的20MB视频从服务器重新下载到本地才能抽帧,相当于平白多消耗了一轮完整的上下行流量——视频文件本身就在本地,选片完成的瞬间就可以零网络开销本地抽帧生成缩略图
- 所有任务强绑定在当前页面的嵌套回调链中,用户切走页面、App切到后台都会导致上传流程被系统回收中断
客户端侧非阻塞上传实现
- 解锁用户交互权限
把现在设置为interaction: true的ProgressHUD改成非阻塞浮窗,仅展示当前上传进度,不拦截用户的点击、页面跳转操作,让用户可以正常使用App的其他功能 - 调整任务执行逻辑,删掉无效等待
选完视频的第一时间就在本地完成缩略图抽取、压缩,直接上传这个仅几十KB的小图,同时并行启动20MB视频的上传任务,完全不需要等视频传完再启动缩略图流程。同时Firebase Storage的putFile方法本身基于系统NSURLSession的后台上传能力,只要在项目配置中开启UIBackgroundModes的后台任务权限,哪怕App切到后台,上传任务也不会被系统杀掉 - 解耦任务与页面生命周期
把上传流程放到独立的全局队列中执行,不要绑定当前页面的生命周期回调:用户上传到一半切去别的页面、退出当前页面,上传任务依然可以在后台继续执行;每个任务的进度、最终结果通过通知或者全局状态管理器同步给UI,不需要用户一直停留在上传页面盯着进度
最后写Firestore的操作可以做本地离线缓存:等视频和缩略图的URL都准备好之后,通过Firestore的离线能力在本地构建好写入操作,等网络条件合适的时候自动同步到线上,不需要客户端同步等待写入完成
服务端兜底的减负方案
如果想完全把上传后的计算逻辑从客户端剥离,可以采用客户端直传+云函数兜底的模式:
- 客户端仅承担最基础的上传职责:把本地的原始视频文件上传到指定的Storage路径,把生成的文档ID、视频存储路径、用户ID先写到Firestore对应的文档中,标记文档状态为“上传中”即可直接结束流程
- 后续的缩略图生成、视频转码、访问URL拼接、Firestore字段补全的逻辑,全部交给Cloud Functions监听Storage上传事件自动处理,处理完成后自动更新Firestore文档的最终展示字段
- 客户端只需要监听对应文档的字段变化,拿到最终的展示数据就行,全程不需要在客户端等待后续处理流程
内容的提问来源于stack exchange,提问作者StackGU
相关产品推荐
相关产品推荐

