On-Demand Resources:是什么、请求机制与资源存储

作者: IT Sectr 发布日期: 2026-04-17 阅读时间: 9 分钟

On-Demand Resources "是Apple用于延迟加载应用程序内容的技术。开发人员不是将所有资源包含在安装包中,而是将它们放置在App Store服务器上,并在需要时请求。根据Apple ODR Guide,这可以减少初始安装大小,并在不更新应用程序版本的情况下添加新内容。

要点

  • On-Demand Resources "应用程序安装后按需加载资源的机制
  • 资源存储在Apple服务器上,通过NSBundleResourceRequest请求
  • 标签按应用程序的功能块对资源进行分组
  • 预取允许提前加载资源以改善用户体验
  • 存储配额有限,需要开发人员监控

iOS中的On-Demand Resources是什么

On-Demand Resources (ODR) "是内置于iOS、tvOS和macOS的内容管理系统。它允许开发人员将应用程序资源分为必需资源(包含在安装包中)和按需加载资源(存储在App Store中,需要时下载)。

ODR基本概念

ODR系统使用三个关键实体:标签资源包请求。标签是连接一组文件的标识字符串。资源包是与标签关联的数据集。请求是启动资源包加载的NSBundleResourceRequest程序调用。

资源请求的生命周期

资源加载经历几个阶段:指定标签的请求初始化、检查本地存储中的可用性、如果不存在则从Apple服务器下载、通知应用程序准备就绪,以及使用后释放资源。系统自动管理缓存和未使用资源的删除。

阶段系统操作执行时间
初始化使用标签创建NSBundleResourceRequest立即
缓存检查在本地存储中搜索资源0.1–0.5秒
下载从Apple CDN下载取决于大小
通知调用完成处理器或委托立即
释放将资源标记为可被系统删除应iOS要求

iOS中ODR如何工作

ODR机制基于后台服务,该服务管理来自App Store云存储的资源请求。当应用程序请求标签时,系统检查资源是否在本地缓存中。如果没有"通过支持在连接中断时恢复的后台URL会话开始下载。

通过NSBundleResourceRequest管理请求

swift
import Foundation

class ResourceManager {
    let odrRequest = NSBundleResourceRequest(tags: ["level-3"])

    func loadLevel3() {
        odrRequest.conditionallyBeginAccessingResources { available in
            if available {
                self.startLevel3()
            } else {
                self.odrRequest.beginAccessingResources { error in
                    guard error == nil else { return }
                    self.startLevel3()
                }
            }
        }
    }

    func releaseResources() {
        odrRequest.endAccessingResources()
    }
}

conditionallyBeginAccessingResources方法检查资源在缓存中的可用性,而不立即加载。如果可用性标志为正"应用程序继续工作而无需延迟。如果资源缺失,beginAccessingResources通过progress属性启动带进度指示的下载。

后台加载和优先级

iOS系统根据应用程序的当前活动自行管理ODR资源的加载优先级。如果应用程序在前台,加载以高优先级进行。在后台,iOS可能会延迟加载或在电池电量低时暂停加载。

  • 高优先级 "立即加载即时需要的资源
  • 低优先级 "延迟加载用于预取和初步缓存
  • 后台 "仅在Wi-Fi激活且电池充足时加载

资源类型和ODR标签

ODR资源可以包括图像、视频、音频文件、精灵、关卡数据以及对启动应用程序不重要的任何其他文件。每个资源关联到一个或多个标签,这些标签确定其所属的功能块。

在Xcode中标记内容

在Xcode中,标签通过Target Membership选项卡上的Resource Tags检查器进行配置。开发人员为项目中的每个文件指定它是主包的一部分还是通过标签加载。一个文件可以属于多个标签,允许资源在应用程序的不同部分之间重复使用。

xml
<!-- Resource Tags 在 Info.plist 中的配置示例 -->
<key>NSBundleResourceRequestTags</key>
<dict>
    <key>level-3</key>
    <array>
        <string>levels/level3.scnassets</string>
        <string>textures/level3_tex.png</string>
    </array>
</dict>

根据生命周期分类标签

Apple根据资源在设备上应保留的时间长短区分三类ODR标签。Initial Install Tags随应用程序一起加载,永远不会被系统删除。Prefetch Tag Order确定安装后立即后台加载的顺序。主要标签按需加载,在空间不足时可能被iOS删除。

除了分类外,每个标签可以有加载优先级。高优先级标签优先于低优先级标签加载,即使它们后来才被请求。这允许开发人员管理内容出现的顺序:首先是主屏幕的关键资源,然后是应用程序深层部分的附加材料。

  • Initial install tags "首次安装时加载,不会被系统删除
  • Prefetched tags "安装后在后台下载以改善用户体验
  • On-demand tags "通过编程方式请求,空间不足时可能被iOS删除

在Xcode中配置On-Demand Resources

在Xcode中配置ODR包括三个阶段:按标签对资源进行分类、在Info.plist中配置加载参数以及通过NSBundleResourceRequest编程实现请求。大部分工作在项目构建方面完成。

在Target Membership中分类

swift
// 检查ODR状态和监控进度
func monitorODRProgress(tag: String) {
    let request = NSBundleResourceRequest(tags: [tag])
    let observer = request.progress.observe(\.fractionCompleted) { progress, _ in
        DispatchQueue.main.async {
            let percent = Int(progress.fractionCompleted * 100)
            print("ODR:\(percent)% 已加载")
        }
    }
}

加载进度通过NSProgress类的progress属性进行跟踪,支持KVO观察。应用程序可以在资源下载期间向用户显示进度指示器。加载完成后,资源通过FileManager和NSDataAsset的标准机制在应用程序的主包中可用。

配额和限制参数

ODR配额取决于iOS版本。从iOS 13开始,每个账户设备可以存储最多20GB按需加载的资源。这个容量在设备上安装的所有应用程序之间分配"如果一个应用程序占用很多空间,其他应用程序的空间就会减少。

监控已用空间通过NSBundleResourceRequest完成。应用程序可以检查可用的ODR存储空间,并据此决定首先加载哪些资源。建议实施备用机制:如果ODR存储空间已满,使用主包中降低质量的资源。

超过配额时,系统按最近最少使用的顺序删除带有On-Demand标签的资源,从最旧的开始。应用程序代码中的Resource Manager可以通过NSBundleResourceRequest属性跟踪当前占用的ODR存储容量。

开发人员必须考虑到iOS可能随时决定删除On-Demand资源"应用程序应正确处理之前加载的资源突然不可用的情况。建议捕获资源访问错误并通过beginAccessingResources重新请求它们。对于应用程序无法运行的关键资源,请使用系统不会删除的Initial Install Tags。

ODR的优势和限制

On-Demand Resources为开发人员提供了管理应用程序大小的灵活工具,但对网络可用性和iOS存储策略施加了一系列限制。

使用ODR的优势

ODR的主要优势是大幅减小初始安装大小。具有多个关卡的游戏、具有视频内容或大型图像集的应用程序可以分部分加载内容。用户立即获得基本功能的使用权,而额外资源在后台下载。

技术的限制

ODR在首次访问时需要持续的网络连接来加载资源。覆盖不良区域的用户可能会遇到加载延迟和错误。此外,Apple不保证加载的资源会保留在设备上"在空间不足时,iOS可能会在没有警告的情况下删除On-Demand标签。

  • 网络需求 "首次资源请求需要互联网连接
  • 自动删除 "iOS可能会在设备空间不足时清除缓存
  • 调试困难 "复现加载问题需要模拟不同的网络条件
  • 标签大小 "Apple建议每个标签不超过512MB以获得最佳性能
  • 错误处理 "应用程序必须正确处理加载错误并重试请求

常见问题

是否可以在不更新应用程序的情况下使用ODR动态添加内容?

ODR允许在不发布新版本到App Store的情况下添加和修改资源。只需通过Xcode更新Apple服务器上的文件,并将它们分配给相同的标签。在下次请求时,应用程序将收到资源的最新版本。这对于季节性内容、临时促销和新图像及布局的A/B测试很方便。

iOS如何在空间不足时管理ODR资源的删除?

系统在需要为其他应用程序释放空间时删除带有On-Demand标记的资源。Initial Install Tags资源不会被删除。删除顺序由LRU(最近最少使用)算法确定"首先删除最长时间未访问的资源。

一个应用程序的最大ODR资源容量是多少?

iOS 13开始,ODR存储的总限制为每个用户Apple ID 20GB。一个标签的大小不应超过512MB以获得最佳加载性能。超过限制时,请求会以NSBundleResourceRequestLowDiskSpaceError错误结束。

ODR在初始加载后是否在离线模式下工作?

是的,加载后资源保存在本地缓存中,在离线模式下无需互联网连接即可使用。只有当iOS因空间不足删除了资源且用户没有网络尝试访问时才会出现问题。

ODR与通过URLSession简单下载文件有何不同?

ODR与App Store基础设施集成:资源托管在Apple CDN上,由缓存系统管理,不需要开发人员搭建自己的服务器。URLSession需要服务器基础设施、版本控制和手动缓存管理。ODR还能自动处理连接中断后的下载恢复。

总结

  • On-Demand Resources "iOS和tvOS应用程序中延迟加载内容的技术
  • 系统基于对资源进行分组的标签和通过NSBundleResourceRequest的请求
  • 支持所有文件类型:图像、视频、音频、精灵和关卡数据
  • 标签类别 "Initial Install、Prefetched和On-Demand,具有不同的存储策略
  • 存储限制 "每个Apple ID 20GB,每个标签最多512MB
  • 安装大小通过将资源从主包转移到Apple服务器而减少
  • 建议 "对游戏、具有媒体内容的应用程序和多层结构的项目使用ODR

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读