On-Demand Resources is Apple’s technology for deferred loading of app content. Instead of including all resources in the installation package, developers host them on App Store servers and request them as needed. According to Apple ODR Guide, this reduces the initial installation size and allows adding new content without updating the app version.
Key Takeaways
On-Demand Resources (ODR) is a content management system built into iOS, tvOS, and macOS. It allows developers to split app resources into mandatory (included in the installation package) and on-demand (stored in App Store and downloaded when needed).
The ODR system operates with three key entities: tags, resource packages, and requests. A tag is a string identifier that groups a set of files. A resource package is a data set associated with a tag. A request is a programmatic call to NSBundleResourceRequest that initiates package loading.
Resource loading goes through several stages: initializing a request with specified tags, checking availability in local storage, downloading from Apple servers if absent, notifying the app when ready, and releasing the resource after use. The system automatically manages caching and removal of unused resources.
| Stage | System Action | Execution Time |
|---|---|---|
| Initialization | Creating NSBundleResourceRequest with a tag | Instant |
| Cache Check | Searching for resource in local storage | 0.1–0.5 s |
| Download | Downloading from Apple CDN | Depends on size |
| Notification | Calling completion handler or delegate | Instant |
| Release | Marking resource as removable by system | On iOS request |
ODR mechanism is based on a background service that manages resource requests from the App Store cloud storage. When the app requests a tag, the system checks if the resource exists in the local cache. If not — it starts downloading via a background URL session with resume support for interrupted connections.
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()
}
}
The conditionallyBeginAccessingResources method checks for resource availability in cache without immediate loading. If the availability flag is positive — the app continues without delay. If the resource is absent, beginAccessingResources starts downloading with progress indication via the progress property.
iOS manages ODR resource loading priorities based on current app activity. When the app is in the foreground, loading is performed with high priority. In the background, iOS may delay loading or pause it during low battery.
ODR resources can include images, videos, audio files, sprites, level data, and any other files not critical for app launch. Each resource is tied to one or more tags that determine its functional block membership.
In Xcode, tags are configured through the Resource Tags inspector in the Target Membership tab. The developer specifies for each project file whether it is included in the main bundle or loaded by tag. One file can belong to multiple tags, allowing resource reuse across different app sections.
<!-- Example of Resource Tags configuration in 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 distinguishes three ODR tag categories based on how long a resource should remain on the device. Initial Install Tags are loaded with the app and are never deleted by the system. Prefetch Tag Order determines the background preloading order immediately after installation. Main tags are requested on demand and may be deleted by iOS when storage is low.
In addition to categories, each tag can have a download priority. Tags with high priority are loaded before low-priority ones, even if they were requested later. This allows developers to control content appearance order: first critical resources for the main screen, then additional materials for deep app sections.
ODR setup in Xcode includes three stages: categorizing resources by tags, configuring download parameters in Info.plist, and programmatic request implementation via NSBundleResourceRequest. Most of the work is done on the build side.
// Checking ODR status and progress monitoring
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)% loaded")
}
}
}
Download progress is tracked via the progress property of the NSProgress class with KVO observation support. The app can display a loading indicator to the user during resource downloading. After download completion, resources are available in the main app bundle through standard FileManager and NSDataAsset mechanisms.
ODR quotas depend on iOS version. Starting with iOS 13, a device can store up to 20 GB of on-demand resources per account. This space is shared among all apps installed on the device — if one app takes up a lot of space, less remains for others.
Used space monitoring is done via NSBundleResourceRequest. The app can check available ODR storage and decide which resources to load first accordingly. It is recommended to implement a fallback mechanism: if ODR storage is full, use reduced quality resources from the main bundle.
When the quota is exceeded, the system removes On-Demand tagged resources in least recently used order, starting with the oldest ones. The Resource Manager in the app code can track the current ODR storage usage via the NSBundleResourceRequest property.Developers must consider that iOS may decide to delete On-Demand resources at any time — the app must correctly handle situations where a previously loaded resource suddenly becomes unavailable. It is recommended to intercept resource access errors and re-request them via beginAccessingResources. For critical resources without which the app cannot function, use Initial Install Tags that are not removed by the system.
On-Demand Resources give developers a flexible tool for managing app size, but impose a number of limitations related to network availability and iOS storage policies.
The main advantage of ODR is a radical reduction in initial installation size. Games with multiple levels, apps with video content, or large image sets can load content in portions. The user gains access to basic functionality immediately, while additional resources are downloaded in the background.
ODR requires a constant internet connection for loading resources on first access. Users in areas with poor coverage may experience delays and download errors. Additionally, Apple does not guarantee that downloaded resources will remain on the device — when storage is low, iOS may delete On-Demand tags without warning.
Frequently Asked Questions
ODR allows adding and modifying resources without publishing a new version in App Store. Simply update the files on Apple’s server via Xcode and assign them to the same tags. On the next request, the app will receive the latest version of the resource. This is convenient for seasonal content, temporary promotions, and A/B testing of new images and layouts.
The system deletes On-Demand tagged resources when it needs to free up space for other apps. Initial Install Tags resources are not deleted. The deletion order is determined by the LRU (Least Recently Used) algorithm — resources that haven’t been accessed for the longest time are deleted first.
Since iOS 13, the total ODR storage limit is 20 GB per Apple ID user. The size of a single tag should not exceed 512 MB for optimal download performance. When the limit is exceeded, requests fail with NSBundleResourceRequestLowDiskSpaceError.
Yes, after downloading, the resource is saved in the local cache and is available in offline mode without an internet connection. Issues only arise if iOS has deleted the resource due to low storage and the user tries to access it without a network.
ODR is integrated with the App Store infrastructure: resources are hosted on Apple’s CDN, managed by the caching system, and do not require the developer to set up their own server. URLSession requires server infrastructure, version control, and manual cache management. ODR also automatically handles download resumption on connection interruption.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also