MASA MAUI iOS 文件下载与断点续传
@
背景
最近在MAUI项目中碰到了大文件下载方面的需求,要求可以实现显示下载进度、暂停、继续下载等,在开发过程中也是碰到了不少问题,所以在此简单分享使用MAUI在IOS上完成下载功能的经验,也希望大家少踩坑。文章中如有不妥的地方,也请多多指教。
介绍
NSURLSession 是 iOS 中用于处理网络请求和数据下载的核心类之一。它提供了强大的功能,使应用程序能够与远程服务器通信、下载文件、上传数据等。
本文我们借助NSUrlSession 中的NSUrlSessionDownloadTask来创建下载任务。
下载任务直接将服务器的响应数据写入临时文件,在数据从服务器到达时为应用提供进度更新。
在后台会话中使用下载任务时,即使应用处于挂起状态或未运行,这些下载也会继续。
可以暂停(取消)下载任务,稍后再恢复它们(需要服务端支持)还可以恢复由于网络连接问题而失败的下载
此方法内部实现了一边下载,一边将下载数据写入沙盒的操作,下载完成后会自动删除沙盒中的文件,所以我们需要在回调(DidFinishDownloading)中将文件移动至其他位置进行保存。
方案及代码
1、新建MAUI项目


2、建立NSUrlSession会话连接
这里我们使用的网路连接类为NSUrlSession,它提供了一个用于发出网络请求和处理异步网络任务的 API并且它支持后台传输。在初始化NSUrlSession之前,我们需要先创建NSUrlSessionConfiguration,它是NSUrlSession中的一个重要的配置,NSUrlSessionConfiguration 有三种模式:
- DefaultSessionConfiguration(默认模式)
- BackgroundSessionConfiguration (后台模式) :后台模式允许你创建一个后台会话,该会话可以在应用程序处于后台或挂起状态时继续进行网络请求。你需要提供一个唯一的标识符(identifier),以便在应用程序重新启动时恢复会话。
- EphemeralSessionConfiguration(瞬时模式) :创建一个临时会话,它在请求结束后不会持久化任何数据,包括缓存和存储的凭据。适用于需要临时性的、不需要持久化数据的请求,例如临时登录或隐私敏感的请求。
我们先在项目中新建IOSDownloadManagerService.cs然后继承于Microsoft.iOS 中的NSUrlSessionDownloadDelegate方法,然后建立NSUrlSession会话连接,
这里我们使用BackgroundSessionConfiguration 模式创建后台下载任务。
注意:无论下载多少文件,我们只需要初始化一个URLSession

3、使用NSUrlSessionDownloadTask 创建下载任务
这里我们使用 NSUrlSessionDownloadTask来实现下载,资源会下载到一个临时文件,下载完成需将文件移动至想要的路径,系统会删除临时路径文件。

4、DidWriteData 监听下载
开始下载后我们可以通过 重写 DidWriteData 方法来获取当前正在下载的文件信息,包括 当前的session会话、当前的下载任务NSURLSessionDownloadTask、本次传递过来的数据量、目前为止下载了多少的数据等。 我们通过这些信息来计算当前下载速度,下载进度等。

打印下载进度监听日志:


5、DidFinishDownloading 完成下载
下载完成后,会触发DidFinishDownloading事件
通过重写DidFinishDownloading来监听下载完成事件,将文件移动到自己想保存的路径下。

到这里我们就完成一个基础的文件下载功能。当然一个完整的下载管理功能,我们还需要具备暂停下载、恢复下载、后台下载、杀死进程后恢复下载等功能的支持。
6、CancelDownload (取消/暂停)下载
我们可以通过NSUrlSessionDownloadTask的Cancel方法来暂停或取消下载任务,Cancel方法会回调一个NSData格式断点数据给我们,然后我们可以将断点数据保存起来,用于后续恢复下载。
在此之前我们需要调整 StartDownload 方法,将文件下载任务NSUrlSessionDownloadTask 存起来,用户后续恢复下载。

CancelDownload 暂停/取消下载

注意:仅满足以下条件时,才能恢复下载:
1、首次请求资源以来,资源未发生更改
2、任务是 HTTP 或 HTTPS 请求GET
3、服务器在其响应中提供 or 头或者同时提供 ETagLast-Modified
4、服务器支持字节范围请求
5、系统尚未删除临时文件
7、ResumeDownload 恢复下载
这里我们利用 NSUrlSession 的 CreateDownloadTask(NSData resumeData) 方法根据 断点数据 创建一个新的下载任务,以便从之前中断的位置继续下载。

8、杀死进程-恢复下载
这里我们使用 DidCompleteWithError 方法来监听载任务错误事件包括杀死进程
当我们的正在执行下载任务的应用程序被异常杀掉进程后,重新启动后会进入DidCompleteWithError方法,所以我们要想恢复下载就需要先获取下载任务的断点数据,这一点我们可以利用本地存储,提前将断点数据存入到本地文件中。
Maui.Essentials

DidCompleteWithError

到此,基本上大功告成了。
效果图

总结
本文主要介绍了基于IOS下载中的几个关键方法,还是主要以介绍思路为主。
为了便于展示,文章中的代码示例拆得比较分散,大家还是以熟悉主要流程和主要方法为先,至于实现方式,八仙过海各显神通。
关于NSURLSessionDownloadTask 更多的内容请参考官方文档
https://developer.apple.com/documentation/foundation/nsurlsessiondownloadtask
最后,由于文章篇幅有限,对于UI部分渲染的部分并没有展示,由于数据渲染还是比较简单,大家可以基于Blazor实现,也可直接使用MAUI ProgressBar等,这里就不过多介绍,对MAUI与Blazor感兴趣的朋友可自行深入研究。
MASA MAUI iOS 文件下载与断点续传的更多相关文章
- iOS 文件下载及断点续传
ios的下载我们可以使用的方法有:NSData.NSURLConnection.NSURLSession还有第三方框架AFNetworking和ASI 利用NSData方法和NSURLConnecti ...
- 【转】iOS 文件下载及断点续传
ios的下载我们可以使用的方法有:NSData.NSURLConnection.NSURLSession还有第三方框架AFNetworking和ASI 利用NSData方法和NSURLConnecti ...
- iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) <进度值显示优化>
前言:根据前篇<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>或者<iOS开发之网络编程--3.NSURLSessionDataTask实现文 ...
- 【SFTP】使用Jsch实现Sftp文件下载-支持断点续传和进程监控
参考上篇文章: <[SFTP]使用Jsch实现Sftp文件下载-支持断点续传和进程监控>:http://www.cnblogs.com/ssslinppp/p/6248763.html ...
- 在 M1 Mac 上开发 .NET MAUI (iOS)
在 M1 Mac 上开始使用 .NET MAUI 开发 (iOS) 的最简单方法. .NET 多平台应用程序 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动 ...
- iOS开发之网络编程--3、NSURLSessionDataTask实现文件下载(离线断点续传下载)
前言:使用NSURLSessionDownloadTask满足不这个需要离线断点续传的下载需求,所以这里就需要使用NSURLSessionDataTask的代理方法来处理下载大文件,并且实现离线断点续 ...
- iOS 文件下载
iOS 视频音乐类等应用会用到“文件下载”.文件下载在iOS中的实现如下: 1.小文件下载 @interface ViewController () <NSURLConnectionDataDe ...
- 李洪强iOS开发之断点续传1
未完待续.. // // ViewController.m // A18 - duo wen jian shang chuan // // Created by 李洪强 on 16/6/29. ...
- C# 文件下载之断点续传
注意,本文所说的断点续传特指 HTTP 协议中的断点续传.本文主要聊聊思路和关键代码,更多细节请参考本文附带的 demo. 工作原理 HTTP 协议中定义了一些请求/响应头,通过组合使用这些头信息.我 ...
- Winform文件下载之断点续传
在本系列的前两篇文章中,分别向大家介绍了用于完成下载任务的 WebClinet 和 WinINet 的基本用法和一些实用技巧. 今天来为大家讲述下载过程中最常遇到的断点续传问题. 首先明确一点,本文所 ...
随机推荐
- Cronjob 定时任务
Job: 负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束. CronJob: 则就是在Job上加上了时间调度. 我们用Job这个资源对象来创建一个任务,我们定一个Job来 ...
- 【后端面经】MySQL主键、唯一索引、联合索引的区别和作用
目录 0. 简介 1. 主键 2. 唯一索引 3. 联合索引 4. 索引对数据库操作的影响 5. 其他索引 5.1 普通索引 5.2 全文索引 5.3 前缀索引 6. 总结 7. 参考资料 0. 简介 ...
- 【webpack系列】从核心概念到上手配置
前言 作为前端开发者,相信大家或多或少都接触过webpack,现如今webpack已经渗透在了前端的各个方面,所以我们有必要来了解并学习webpack,webpack 是一种用于构建 JavaScri ...
- MyBatis实现动态SQL更新
博主记得在一个周五快下班的下午,产品找到我(为什么总感觉周五快下班就来活 ),跟我说有几个业务列表查询需要加上时间条件过滤数据,这个条件可能会变,不保证以后不修改,这个改动涉及到多个列表查询,于是博主 ...
- quarkus实战之一:准备工作
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<quarkus实战>系列 <q ...
- Linux 日志服务管理
日志管理 1 系统日志管理 1 rsyslog系统日志服务 日志记录的内容包括: 历史事件:时间,地点,人物,事件 Jul 18 14:30:53 # 时间 ubuntu2204 # 地点 (在哪个主 ...
- ROS的通信机制
通信机制 节点--执行单元 执行具体任务的进程.独立运行的可执行文件: 不同节点可以使用不同的编程语言,可分布式运行在不同的主机上. 节点在系统中的名称是必须是唯一的. 节点管理器(ROS Maste ...
- 【微信小程序的开发】初步认识
目录 项目结构 页面组成 json配置文件 app.json project.config.json sitemap.json 每个页面的json 实例 wxml 标签名称 ...
- pandas 字典创建Dataframe
所有的ndarrays必须具有相同的长度.如果传递了索引(index),则索引的长度应等于数组的长度.如果没有传递索引,则默认情况下,索引为range(n),其中n为数组长度. import pand ...
- 达梦数据库: SQL查询报错《不是 GROUP BY 表达式解决方法》
报错信息: ****: 第4 行附近出现错误: 不是 GROUP BY 表达式 修改办法: 达梦可以配置兼容参数,COMPATIBLE_MODE=4,静态参数,需要重启数据库后生效! sp_set_p ...