大多数浏览器和
Developer App 均支持流媒体播放。
-
Background Assets 的新动向
等待很久了吧!了解 Background Assets 如何帮助你的 App 在启动之前下载内容。我们将向你展示如何将 Background Assets 整合到现有的 App 中,探索使用必要或非必要资源的时机,并学习如何轻松调试扩展。
资源
相关视频
Tech Talks
WWDC22
-
下载
♪ ♪
Jared:你好 欢迎来到 “Background Assets 的新动向”讲座 我叫 Jared 是 Apple 的一名软件工程师 我很期待能与你分享 今年为 Background Assets 带来的所有更新 我们的团队在过去一年中 已经对部分内容进行了更改 但我还是建议你查看 我之前的介绍 Background Assets 讲座 该讲座中的很多细节 都是今天新讲座的基础 在今天的讲座中 我将首先为你 带来 Background Assets 的概述 以及你为何 应该在 App 中使用它 接下来 我将探讨 Background Assets 今年的更新 包括一项我们的团队迫不及待 要与你分享的全新功能 随后 我将用一个示例向你展示 Background Assets 的执行 你还可以自行下载此示例 同时我将讲解如何采用此技术 显著提升你 App 的用户体验 接下来 我将向你 提供一些调试 App 扩展 和模拟入口点的指导建议 好的!现在我们来快速回顾一下 Background Assets
Background Assets 的 主要目标之一就是避免等待 用户最不希望 获得的体验就是启动 App 后 不得不等待大量下载完成 Background Assets 结合自身框架和相关联的 App 扩展 解决了这个问题 这一新技术 在 iOS 16.1 版本推出 与 macOS Ventura 的首发同时进行 它支持使用你的 CDN 供应商 或你管理的服务器 下载额外内容至你的 App 比如说 该内容可以在 最初安装 App 时获取 也可以在 App 更新时 或者用户未使用 App 时 在后台周期性获取 通过配套的 App 扩展 你可以编写代码 在用户不经常使用 App 时运行 目前 macOS、iOS 和 iPadOS 均支持此技术 已覆盖了开发者喜爱的各个平台 使用 Background Assets 最大的好处之一 在于扩展可以在用户 启动你的 App 之前运行 这提供了一种在 App 通过 App Store 进行安装后 立刻开始获取资源的方法 扩展也可以由系统 在后台周期性启动 这是为了确保一切新资源或更新资源 在用户启动你的 App 时已经就绪 扩展也用于满足 App 在未运行时的下载需求 比如说 在文件完成下载后 扩展将启动 并将文件 移动到最终目的地 需要记住的一点是 扩展的运行时间是有限的 这是为了确保用户设备 电量和性能的优化 我稍后会对此进行详细讲解 还有一点很重要 你为了 与 Background Assets 配合使用而开发的 App 扩展 会被放置在专门的沙盒中 这是为了确保扩展仅用于 通过 Background Assets 管理内容 如果你发现某一功能 或 API 在沙盒中不可用 请通过反馈助理与我们联系 我先前提到你的 App 扩展 将在三个系统事件中启用: App 安装、App 更新 以及周期性地在后台启用 我们来看看如何管理这一生命周期
你扩展的生命周期开始于 App Store 在设备上安装或升级你的 App Background Assets 系统服务 此时将收到提醒 并阻止 App 启动 系统随后将检查你的 App 包 并读取其 Info.plist 获得 BAManifestURL 键值 系统将开始下载该键值引用的清单 并向 App Store 回报下载进度 清单下载完成后 系统将针对此安装或升级事件 发布内容请求 来唤醒你的扩展 内容请求中包含 指向已下载清单的路径 你的扩展 应当使用清单来确定 URL、 文件大小 以及安排哪些资源进行下载 一旦扩展确定了需要下载的资源 它将以 BADownloads 集的 形式回传下载 系统随后暂停你的 App 扩展 有时候甚至会终止它 以节约设备的电量和性能 下载随后开始 你的扩展将在 下载完成后不久收到告知
周期性的内容请求和 App 安装事件的情况几乎完全相同 唯一的关键区别在于你的设备将决定 事件在何时发生 设备将基于 用户使用习惯来做出决定 低电量模式、后台 App 刷新 或你 App 的启动频率等 关键因素都被纳入考量 现在让我们更深入地检视哪些因素 会影响你扩展周期性运行的时间
我们非常关注 设备的整体性能和电量使用 这也是 Background Assets 对扩展的运行时间设置限制的原因 你扩展的内存使用也受到严格控制 如果扩展占用的内存超过几兆 就有可能被系统终止 你可以考虑对扩展需要读取的 任何大型文件进行内存映射 因为由设备存储支持的内存映射数据 并不算在此限制之内
App 在最初安装时会得到 每天几分钟的默认运行时间配额 也许听起来不算多 但借助设计得当的扩展 便可以实现细水长流 运行时间也会 根据 App 的使用而变化 如果 App 有一段时间没有启动 系统可能会开始限制扩展的启动 举例来说 偶尔使用的 App 运行时间可能被大幅缩减 而经常使用的 App 可能会得到额外的运行时间
BADownloaderExtension 协议定义了 作为你 App 扩展入口点使用的函数 运行时间的计算 开始于函数被系统调用 结束于该函数退出作用域 函数退出作用域时 或你扩展的运行时间用完时 系统可能会暂停或终止该扩展 稍后我将展示一个案例
不过 还是有一种例外情况 函数作用域会对 你扩展的运行时间进行控制 如果调用了异步独占控制 API 你的扩展会一直保持运行 直到完成处理程序被调用并返回 用户有几种方法可以控制 扩展的运行时间 比如说 如果设备处于低电量模式 或者禁用了后台 App 刷新 无论是针对全局 还是你的 App 你的扩展将无法运行 之前 我提到扩展运行时间是如何 基于函数作用域决定的 让我们来看一个案例 以便更好地理解其中的原理
这段代码表示扩展服务于 后台下载的接口 BADownloaderExtension 协议 定义了系统将调用到 你扩展中的函数 现在我们来添加 必需的函数以符合此协议 “downloads for request”函数 是进入扩展的 主要入口点之一 它的 BAContentRequest 定义了 在 App 安装、App 更新 或作为后台 周期性检查的一部分时是否被调用 manifestURL 参数提供了通往 扩展调用之前 下载的本地文件的路径 清单文件常常 用于对比正在下载的内容 和服务器上或许可用的下载内容 函数定义的返回类型要求 符合 BADownload 类型的 下载对象集 这意味着响应此函数的请求 要求你在函数 退出作用域之前同步返回 一切需要下载的内容 但是 在这个特别设计的示例中 我们可以假设调用 名为 parseManifest 的函数的情况 该函数将读取已下载的清单 并返回需要下载的 BADownload 对象
但是 假设 parseManifest 函数的执行情况非常糟糕 花了 30 分钟去解析和构造下载 结果就是严重超出扩展的运行时间 导致扩展将被终止 必须牢记的重要一点是 扩展运行时间的计算 是从“downloads for request” 函数调用的瞬间开始 直到它退出作用域并返回为止 让我们来看看 另一个出现问题的案例
只要任何 BADownloaderExtension 协议函数退出作用域 扩展就可能会被暂停 随后终止 你可以看到协议并不会 将它的任何函数定义为变异 这是有充分理由的 你的扩展终止时 任何实例变量 或内存状态都不会被保存 如果你的扩展需要保持任何状态 就必须序列化该状态到磁盘 接下来 我们来谈谈你在 扩展和 App 中 将用来管理下载内容的 API 框架内的下载管理器是 与 Background Assets 系统服务 进行通讯的主要方式 管理器是一个单例对象 可以在你的整个 App 中使用 有了该管理器 你可以安排资源 在后台进行下载 并将已安排的下载任务提到前台 在下载管理器中 你也可以管理 飞行中的下载任务 我之前也提到 这些任务 可以在你的 App 启动之前 由扩展安排下载 你还可以使用一种同步机制 来确保你的 App 和与之关联的扩展 不同时执行类似操作 关于下载管理器 我最后想提到的一点是 它有一个用于接收下载回调的代理 和 BADownloaderExtension 协议相似 如果你在 BADownloadManager 上 寄存一个代理 它将会代替你的扩展接收回调 这项功能非常有用 因为它让你的 App 可以在运行时管理下载任务 你已快速回顾了如何管理下载任务 现在我们来谈谈 文件下载到用户设备上之后 应该如何进行管理
你使用 Background Assets 下载的 所有文件都被标记为可清除的 这意味着在紧急情况下 系统可能会将它们移除 设想一下 系统可能需要 进行安全升级 或用户可能会想拍摄 孩子第一次走路的视频
但是 如果你 修改或展开已下载的资源 系统就不再追踪那些文件 它们也就不再处于可清除状态 你应该仔细考虑该如何修改资源 或从中提取数据 如果你对下载资源的管理方式不当 就会增加用户设备备份的大小 或者让关键的安全升级无法下载 因此 你应该尽量 将已下载资源存储在 你的缓存目录中 这样一来 系统就知道可以 在紧急情况下清除它们 现在所有回顾已经完成 我们来看看 Background Assets 今年有哪些更新
今年的早些时候 我们引入了必要下载功能 提供了一种在你的 App 进行安装或更新时获取内容的方法 这意味着你的下载任务完全整合到了 iOS 主屏幕、macOS 启动台 和 App Store 中 在最终用户看来 下载资源就像 App 仍处于从 App Store 进行下载的流程中 这也意味着 在你的必要下载处于飞行中时 用户无法启动 App 用户能做的只有取消或暂停安装 由于支持暂停功能 你的服务器应当支持 HTTP 域 使进度可以恢复 因为必要下载 在 App 安装过程中进行 它们比 任何非必要下载的优先级都高 我们来看看 整个过程开始于你的 App 在 App Store 或 TestFlight 中被请求 如果 App 的 Info.plist 包含必要资源键值 设备上就将建立进程 我们会进入此工作流 一旦你的 App 下载或安装完成 系统将通过发布内容请求 来唤醒你的扩展 包括请求是针对 App 安装、 App 更新还是周期性获取 在此期间可能会发送身份验证质询 以进行清单的下载 接下来 你的扩展将发回必要 和非必要下载的组合 顺带一提 很重要的一点是 你的扩展 必须快速发回下载任务 因为在函数传回前 你 App 的下载进度 在用户看来是停滞的
扩展提供下载任务的瞬间 任何被标记为 必要的下载会立即开始 你的扩展在此期间 也可能会收到额外的 身份验证质询 在所有必要下载完成后 系统将终止你的扩展 用户也可以启动 App 了 随后 扩展将收到一批成功 以及可能失败的下载任务 如果有任何下载任务失败了 你可以使用 BADownloadManager 将它们作为 非必要下载重新排入队列 由于你的扩展收到必要下载 已完成的信息 系统将立即开始下载非必要资源 非必要下载任务在完成下载后 将被发送到扩展 现在我们来看看 必要下载任务如何整合到 iOS 主屏幕上的 App Store 安装流程中 进度指示条的一部分会分给 下载基础 App 的时间 加上安装时间 再加上下载必要资源所需的时间 在你 App 的 Info.plist 中定义的 新 BAEssentialDownloadAllowance 键值 将用于创建最初的整体进度指示条 一旦 contentForRequest 调用到你的扩展中 且你的扩展传回下载任务 所有必要下载文件的 大小会被加到一起 来确定实际下载量 如果你安排的下载任务量远低于 必要下载限额 进度指示条可能会移动得很快 你的目标应当是使必要下载限额 接近实际下载量 以确保向用户展示流畅的进程 需要记住的重点在于 我们讨论的所有功能 都可以被用户禁用 在 App Store 设置窗格中 有一部分是关于 禁用 App 内呈现的内容 虽然这无法 完全禁用 Background Assets 但确实能阻止必要资源的下载 以及在用户启动 App 之前 运行扩展的功能 所以 这样设想必要资源很重要: 它们是必要的 但不是你的 App 启动所必需的 因此 很重要的一点是 你的 App 可以在 必要资源还没下载到设备上时 在启动 App 后处理工作流 使用必要资源的功能实际上是在 春季早些时候作为 iOS 16.4 和 macOS Ventura 13.3 的一部分引入 新的 API 非常精简 应该可以轻松地 添加到你已有的扩展中
为了支持必要下载 而创建的第一个 API 其实是 BAURLDownload 上的 一个全新初始化程序 为了支持此功能 我们特别添加了两项参数 必要参数 正如它的名字所示 指出下载是否应当被标记为必要 必要意味着在 App 的整体下载 和安装过程中发挥作用 文件大小参数 则表示将被下载的资源大小 在创建必要下载时 文件大小必须准确 系统需要这一信息 以便在用户的设备上 恰当地显示 App 的安装进度 如果 Background Assets 下载的文件 与此处提供的文件大小不匹配 那么在任务被标记为 必要的情况下 下载将会失败 如果你的扩展不知道文件大小 那么文件大小信息 应该包含在扩展启动前 提供给扩展的 BAManifestURL 中
我们引入的另一个 API 提供了简单的单行代码 来创建非必要下载的表述 由于必要下载只能排在 contentForRequest 函数队列中 这个 API 在不少情况下都很有用 比如说 假设我们获取必要下载失败 也许是因为网络问题 也许只是因为文件暂不可用 那么 在扩展中的后台下载失败 函数中 你可以轻松创建 该下载的非必要表述 并重新将其排入队列中 随后 下载将在后台开始 你的扩展或 App 会在下载完成后收到通知 现在我们来看几个你 App 的 Info.plist 中必须出现的键值
在去年的讲座中 我逐一详细讲解了这些键值 如果需要更加深入的解析 我建议你查看该讲座 需要记住的重点在于 这些键值不仅是 使用 Background Assets 框架 所必需的 也是提交你的 App 到 App Store 所必需的 今年新增了两个支持必要下载 所需的键值: BAEssentialDownloadAllowance 和 BAEssentialMaxInstallSize 必要下载限额以字节表示 并定义了你所有必要资源 下载总大小的上限 重要的是你应当尽量让这个数字 接近你排入队列的必要资源的大小 这样在用户安装你的 App 时 下载进度才能保持流畅 另一个新键值 BAEssentialMaxInstallSize 表示的是最多可以 提取多大的资源到用户的设备 这一数字将出现在 App Store 中 用于告知用户 在必要资源安装后 你的 App 将占用的存储容量大小 这就是我们为必要下载 新增的 API 的大致情况 正如你所见 将必要下载支持 添加到已有的 App 只需要改变极少的代码 就是这么简单 现在到有趣的部分了 让我们看看 如何将使用 URLSession 的 现有 App 扩展为 使用 Background Assets 框架 我即将向你展示的 App 可以下载 WWDC 讲座 比如你正在观看的这个 并将视频存储在设备上供离线观看 现在 App 必须先启动 才能进行视频下载 采用 Background Assets 之后 我们再也无需等待 可以让视频在 App 启动之前就率先下载完成 我们来看一看 这是我们今天要继续构建的 App
你可以看到在启动的瞬间 讲座立即开始下载 这个 App 现在的运行方式是 从包含 WWDC 讲座 列表的服务器下载清单 在获取清单后 讲座开始下载 并可以在轻点之后进行观看 让我们来看看在这个项目中使用 Background Assets 还需要些什么 在你开始使用 Background Assets API 之前 首先要添加我刚才提到的 初始 Info.plist 键值 这些键值必须出现在你 App 包的 Info.plist 文件中 接下来你需要做的是 添加后台下载扩展 并将其嵌入你的 App 你需要确保你扩展的包标识符 以 App 的包标识符为前缀 你还需要确保 App 及其扩展 位于同一个 App 组中 因为你的扩展要通过 App 组 与你的 App 共享下载资源 最后需要确保的是你的 App 及其扩展使用你的团队标识符签名 完成这些步骤之后 你就可以开始 采用 Background Assets 框架了
现在你看到的就是 刚才那个 App 的 Xcode 项目 我已经进入并创建了下载扩展 并将它嵌入到 App 之中 我也添加了 必需的 Info.plist 键值 完成所有这些之后 我们首先前往 SessionManager
这个项目的 SessionManager 目前使用 URLSession 来获取最新的下载任务 URLSession 是一个出色的 API 我们会继续在 App 中用它来获取清单 但是 我们将迁移到使用 Background Assets 框架 来获取会话本身 这样做是为了让 App 在启动时可以充分利用 我们将要创建的扩展 将后台安排的 任意资源提到前台 首先 我们将导入 Background Assets 框架模块
接下来 我将向下滚动 并移除与 URLSession 关联的变量 因为已经不需要它们了 现在我将前往 “start download”方法 正如你所见 现有的代码 通过 URLSession 下载任务 追踪会话进行下载 现在已经不需要了 我们把它移除 从这里开始事情变得有意思起来 在使用 Background Assets 时 很重要的一点是去考虑 你的扩展和 App 有可能同时运行的情况 为了能轻松地协调它们 你需要使用 withExclusiveControl 来确保 任何需要与另一流程 互斥的工作都可以实现 我们现在进行添加
你可以看到 这个 API 是异步和转义的 任何排入此闭包的工作都确保 在扩展同样使用此 API 的情况下 独立于扩展外运行 我们稍后会执行扩展 现在先把注意力集中在 App 上 既然我们知道 正在互斥的语境中运行 就可以询问下载管理器 目前是否有任何飞行中的下载任务
没有理由在扩展已经安排下载任务时 再去重新安排 但是 我们可以做的一件事是 如果找到了已有的下载任务 我们可以将它提到前台
将下载提到前台可以大幅缩减 下载完成所需的时间 由于用户正在使用 App 这是一个尽快获取 下载任务的绝好机会 用户或许想要观看 如果还没有下载任务 我们就进行创建
然后 不论是我们还是 扩展创建的任务 都直接开始在前台下载 将下载任务从后台提到前台 并不会让下载重新开始 它只会从转换时停下的地方继续 接下来要做的是执行 BADownloadManagerDelegate 但在此之前 我要 先删除旧的 URLSessionDelegate
现在旧的代理已经移除 我们就可以创建 Background Assets 代理了
由于会话管理器现在符合代理 很重要的一点是 它已经为实际接收信息做好准备 我将前往初始化程序 并将它连接上
由于 BADownloadManager 直接和系统调度程序连接 它是一个单例对象 让这个代理附加到下载管理器上 会让你的 App 在运行中的情况下 越过扩展收取信息 现在我们回到需要执行的函数
对于这个 App 来说 有三个关于代理协议的 特定函数需要执行 第一个是针对进度处理的 我们现在就来执行
在我们开始 盲目更新 UI 中的进度之前 首先要确保 我们接收进度信息的下载任务 是清单正在追踪的 如果下载正在被追踪 我们就调用 updateDownloadProgress 这是 App 中的一个辅助函数 用于直接将进度发送到 SwiftUI 接下来 我将执行 下载完成时需要的函数
开始的方式几乎一样 用来确保 它只处理预期中的下载任务 接下来使用 replaceItemAt 将对象从 Background Assets 给我们的临时位置移动到最终位置 重点是在这里使用移动操作 因为系统会在设备空间不足的情况下 追踪并清除文件 因此你必须确保 App 始终检查 是否有文件丢失 并在有必要时重新获取 最后会出现的情况是 一项 Task 会从 MainActor 中衍生、 状态被标记为已下载 并且 App 开始获取讲座的缩略图 现在我希望所有下载都会成功 但不幸的事实是它们可能会失败 可能是因为 这项资源已经不在服务器上 或是因为网络问题 Background Assets 确实会重新尝试 并在遭遇网络连接问题时等待 但到了一定时间之后 你总会知道文件并未获取 另一件需要牢记的事是 提到前台的下载任务 在出现网络连接问题时 几乎会立即下载失败 下载失败时 我们的 App 没有太多要做的 可以展示 UI 或者重新调度 但针对这个案例 让我们记录一下出现了一个问题
由于代理已经完全执行 我们重新启动 App 来看看现在是什么样
毫不意外 它看起来一模一样 这也就是我们想看到的结果 添加 Background Assets 来取代 URLSession 非常轻松 接下来 我将向你展示如何执行 处理后台下载的 App 扩展 添加此 App 扩展 让你可以充分利用 Background Assets 在 App 安装或更新之前获取内容 它也为必要资源的 队列安排提供支持 本质上来说 这个扩展负责的是 在 App 不运行时安排下载任务 我们来看一看 我们现在来到了后台下载处理器 它在你的扩展中接收 与 Background Assets 有关的信息 在扩展中 我要做的 第一件事是创建记录器 以便从 Console.app 中 看到扩展何时在运行
接下来 我将执行 contentForRequest 函数 它是 BADownloaderExtension 协议的一部分
扩展会做的第一件事是 在扩展启动前解析预下载的清单 如果下载的清单 出于某些原因是无效的 扩展将被配置为 不安排任何下载任务 一旦扩展得知清单是有效的 它将使用原子操作存入 App 组中 这是为了让 App 和扩展 都在本地拥有最新版的清单 以便稍后引用 因为保存是通过原子操作完成的 就不需要使用 withExclusiveControl 了 扩展随后将创建可变的下载对象集 由扩展返回系统进行调度 我们之前探讨过 只有在 App 安装和 App 更新 过程中才支持必要下载 接下来 我将通过 清单迭代所有远程讲座 在这个语境中 意味着它们还未被下载 然后为每个需要调度的下载任务 创建 BAURLDownload 对象 下载任务将分配到唯一标识符、 URLRequest、 该下载是否以必要方式获取的注释、 文件大小、资源下载的目标 App 组 以及相对优先级 来控制调度器应该首先 开始进行哪些下载 需要牢记的一个重点是 任何标记为必要的下载任务 文件大小都必须正确 否则下载将被标记为失败 这是为了支持 在 iOS 主屏幕、macOS 启动台 和 App Store 中能流畅显示进度 我们已经获取了 安排下载任务的支持 让我们来看看 怎么处理成功的下载任务 如果 App 没有运行 或者 App 没有分配给 BADownloadManager 的代理 就由扩展负责处理下载任务 我在下载完成处理器中首先执行的是 异步获取独占控制 由于获取独占控制是异步的 我们需要保留 扩展刚才发来的临时文件 正如你所见 我实现的方法是将文件移动到 一个比该函数作用域 持续时间更长的临时位置 我也将添加 Swift 延迟器 来确保扩展下载的 临时文件始终会被清理 尽管系统会替你删除文件 最好的做法还是由自己进行管理 接下来 我将从 App 组中加载清单 并确认它是否有效 扩展随后会检查以确保 已下载并在处理中的标识符 与清单中预期的某讲座匹配 接下来扩展会将文件从临时位置 移动到 App 组中的最终目的位置 随后创建 LocalSession 来快速确认 讲座是否下载到了合适的位置 最后需要处理的是失败的下载任务
经常被忘记的一个重点是 如果 BAManifestURL 下载失败 扩展事实上会收到通知 它的类型继承了 BAURLDownload 但是 那不是它准确的内部类型 因此 扩展会进行筛选 来确保只处理 BAURLDownload 对象 由于必要资源下载在前台进行 它们只会花几秒钟等待网络连接 因为这些下载任务 会影响 App 的安装进度 所以 一个好方法是 在必要下载失败的情况下 重新将它们排入非必要下载队列 一种可以轻松将必要下载转为 非必要下载的方法是使用 新的 removingEssential() 函数 该函数返回非必要的副本 接下来就将这个副本发给 BADownloadManager 的 scheduleDownload 函数 系统将在合适的时间获取下载任务 我们的 App 及其扩展已经 完全采用了 Background Assets 我们来添加一些 提示某一特定讲座 作为必要下载的 UI
请记住 必要意味着 App 安装和 App 更新 将阻止 App 启动 直到资源下载完成 然而 由于 App 被阻止启动的情况只出现在 从 App Store 或 TestFlight 安装的过程中 使用指示器是一种 进行可视化识别的出色方法 该指示器会在 SwiftUI 内的 VideoSelector 视图中执行
如果讲座在清单中被标记为必要 导航视图中将出现绿色的圆点 这样就完成了 你已经看到执行 Background Assets 是多么简单 现在我们来看看调试扩展 并模拟其入口点 我之前谈到过 扩展会在 App 安装、App 更新期间启动 或在后台周期性启动 由于 App 安装由 App Store 控制 而周期性事件由设备控制 你需要一种方法来强制扩展启动 以便进行调试
幸运的是 我们的团队 随 Xcode 推出了一项工具 可以用于启动扩展并模拟其入口点 该工具可以从 Terminal 获取 输入 xcrun backgroundassets-debug 来启动 工具还附带帮助信息和手册页 使用 backgroundassets-debug 时 你将传递具备触发 BAContentRequests 不同类型功能的模拟参数 在任意模拟信息发送到设备上时 扩展运行时间将被重置 以帮助你顺利进行调试 backgroundassets-debug 提供多种多样的功能 包括多设备支持 只要设备和你的 Mac 配对 就可以用于模拟你的扩展 这些指令可以通过 蓝牙或 Wi-Fi 进行传递 这样你的设备 也无需通过 USB 与 Mac 进行连接 最后 开发者模式 必须开启 以便设备 履行 backgroundassets-debug 所触发的模拟事件 你可以在设备的“设置”App 中的 “隐私与安全”部分轻松启用 现在我们来看看 在我们刚刚构建的演示 App 中 使用 backgroundassets-debug 工具 我们现在来到了 Terminal 由于这台 Mac 上已经安装了 Xcode 我就直接进行下一步 列出与其连接的设备 你可以看到 目前只有一台已连接设备 正好是我的 iPhone 你需要复制 选择进行模拟的设备的 UUID 在提供的参数中 你可以看到设备的 UUID 和 App 的包标识符一同显示 我将使用模拟参数 混合 App 安装参数 来调用此工具 这会唤醒 App 扩展 就像它在最初的 App 安装事件中被唤醒 现在我按下回车键 工具告知你 App 安装事件已经发送到设备 我们来启动 App 看看情况如何
你可以看到 所有演讲视频都在队列中进行下载 在我说话时 有些已经下载完成了 这就是 Background Assets 在起作用 如果你像我一样 或许已经开始考虑 各种可能的方法 以减少 App 中的等待时间 我已经向你展示了 如何调试 App 扩展 接下来是几个必须牢记的重点
必要资源随 App 一同下载 并影响 App 的安装进程 因此 这类资源只可以在扩展中的 BAContentRequest 安装或更新 事件期间进行调度 如果扩展排入序列的 任何必要下载任务失败 App 最终仍然可以启动 如果需要那些资源 你必须确保将必要下载 重新安排为非必要下载 无论是在扩展内 还是在 App 首次启动时 任何未被标记为必要的下载都将在 App 完成安装或更新后下载 并获得后台下载优先权 还有一个重点必须牢记 那就是扩展受到内存使用的限制 所以请一定要 调试扩展来确保你所写的代码 大大低于内存阈值 如果你的扩展使用超额内存 它将会在调试中 因为内存异常而崩溃 如果扩展在 App 安装或 App 更新内容请求期间崩溃 那么 App 将立刻可以启动 最后 请你记住 一定要让 App 成为模范公民 妥善管理下载的资源 一种管理资源的方式是将其放入 你 App 的缓存目录 这就是我们今年关于 Background Assets 的全部内容 要说今天的讲座 能让你得到什么启示的话 那就是必须消除 App 的等待时间 一种消除等待时间的方法 就是采用 Background Assets 框架 并使用全新的必要资源功能 请确保在将 App 提交 到 App Store 前使用 TestFlight 通过使用 TestFlight 你可以看到必要资源 随 App 进行下载的情形 如果你在任何时候有问题 请查看开发者文件 并随时在 Apple 开发者论坛上寻求帮助 我也想鼓励你积极使用反馈助理 我们的团队正不断对 Background Assets 进行升级 也期待你在 App 中使用它 对了 如果你还没熟悉该框架 我推荐你查看 引入 Background Assets 时我所做的讲座 里面有很多补充内容 在此 感谢你参加今天的讲座 我谨代表 Apple 整个团队 感谢你的观看
-
-
16:09 - Info.plist requirements (old)
|Key|Type|Description| |-|-|-| |BAInitialDownloadRestrictions|Dictionary|The restrictions that apply to the set of assets that download prior to first app launch. |BADownloadAllowance|Number|The combined size of the initial set of non-Essential asset downloads. Stored inside the BAInitialDownloadRestrictions dictionary. |BADownloadDomainAllowList|Array|Array of domains that can assets can be downloaded from prior to first app launch. Stored inside the BAInitialDownloadRestrictions dictionary. |BAMaxInstallSize|Number|The combined size (in bytes) on disk of the Non-Essential assets that download immediately after app installation. |BAManifestURL|String|URL of the application's manifest.
-
16:22 - Info.plist requirements (new)
|Key|Type|Description| |-|-|-| |BAInitialDownloadRestrictions|Dictionary|The restrictions that apply to the set of assets that download prior to first app launch. |BADownloadAllowance|Number|The combined size of the initial set of non-Essential asset downloads. Stored inside the BAInitialDownloadRestrictions dictionary. |**BAEssentialDownloadAllowance**|Number|The combined size (in bytes) of the initial set of Essential asset downloads, including your manifest. Stored inside the BAInitialDownloadRestrictions dictionary. |BADownloadDomainAllowList|Array|Array of domains that can assets can be downloaded from prior to first app launch. Stored inside the BAInitialDownloadRestrictions dictionary. |BAMaxInstallSize|Number|The combined size (in bytes) on disk of the Non-Essential assets that download immediately after app installation. |**BAEssentialMaxInstallSize**|Number|The combined size (in bytes) on disk of the Essential downloads that occur during app installation. |BAManifestURL|String|URL of the application's manifest.
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。