On-Demand Resources は、アプリケーションコンテンツの遅延読み込みのためのAppleのテクノロジーです。すべてのリソースをインストールパッケージに含める代わりに、開発者はそれらをApp Storeサーバーにホストし、必要に応じてリクエストします。Apple ODR Guideによると、これにより初期インストールサイズが削減され、アプリのバージョンを更新することなく新しいコンテンツを追加できます。
重要なポイント
On-Demand Resources(ODR) は、iOS、tvOS、macOSに組み込まれたコンテンツ管理システムです。開発者はアプリのリソースを必須(インストールパッケージに含まれる)とオンデマンド(App Storeに保存され、必要に応じてダウンロード)に分割できます。
ODRシステムは3つの主要なエンティティで動作します:タグ、リソースパッケージ、リクエスト。タグはファイルのセットをグループ化する文字列識別子です。リソースパッケージはタグに関連付けられたデータセットです。リクエストはパッケージの読み込みを開始するNSBundleResourceRequestへのプログラム呼び出しです。
リソースの読み込み はいくつかの段階を経ます:指定されたタグでのリクエストの初期化、ローカルストレージでの可用性の確認、存在しない場合はAppleサーバーからのダウンロード、準備完了時のアプリへの通知、使用後のリソースの解放。システムはキャッシュと未使用リソースの削除を自動的に管理します。
| 段階 | システムの動作 | 実行時間 |
|---|---|---|
| 初期化 | タグ付きのNSBundleResourceRequestを作成 | 即時 |
| キャッシュ確認 | ローカルストレージでリソースを検索 | 0.1~0.5秒 |
| ダウンロード | Apple CDNからダウンロード | サイズに依存 |
| 通知 | 完了ハンドラまたはデリゲートを呼び出し | 即時 |
| 解放 | システムによる削除可能としてリソースをマーク | iOSの要求時 |
ODRの仕組み は、App Storeのクラウドストレージからのリソースリクエストを管理するバックグラウンドサービスに基づいています。アプリがタグをリクエストすると、システムはリソースがローカルキャッシュに存在するか確認します。存在しない場合は、中断された接続の再開をサポートするバックグラウンドURLセッションを介してダウンロードを開始します。
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はバッテリー残量が少ないときに読み込みを遅延または一時停止することがあります。
ODRリソース には、画像、動画、音声ファイル、スプライト、レベルデータ、およびアプリの起動に重要でないその他のファイルを含めることができます。各リソースは、機能ブロックへの所属を決定する1つ以上のタグに結び付けられます。
Xcodeでは、Target Membershipタブの Resource Tags インスペクターを介してタグを設定します。開発者はプロジェクトの各ファイルについて、メインバンドルに含めるかタグで読み込むかを指定します。1つのファイルが複数のタグに属することができ、アプリの異なるセクション間でリソースを再利用できます。
<!-- Info.plistでのResource Tags設定の例 -->
<key>NSBundleResourceRequestTags</key>
<dict>
<key>level-3</key>
<array>
<string>levels/level3.scnassets</string>
<string>textures/level3_tex.png</string>
</array>
</dict>
Appleは、リソースをデバイスに保持する期間に基づいて3つの ODRタグ カテゴリを区別しています。初期インストールタグはアプリとともに読み込まれ、システムによって削除されることはありません。プリフェッチタグ順序は、インストール直後のバックグラウンドプリロード順序を決定します。メインタグはオンデマンドでリクエストされ、ストレージが不足するとiOSによって削除される可能性があります。
カテゴリに加えて、各タグはダウンロード優先順位を持つことができます。高優先順位 のタグは、後でリクエストされた場合でも、低優先順位のタグよりも先に読み込まれます。これにより、開発者はコンテンツの表示順序を制御できます:最初にメイン画面の重要なリソース、次にアプリの詳細セクションの追加マテリアル。
ODRの設定 はXcodeで3つの段階を含みます:タグによるリソースの分類、Info.plistでのダウンロードパラメータの設定、NSBundleResourceRequestを介したプログラムによるリクエストの実装。作業の大部分はビルド側で行われます。
// 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)% 読み込み完了")
}
}
}
ダウンロードの進行状況 は、KVO観測をサポートするNSProgressクラスのprogressプロパティを介して追跡されます。アプリはリソースのダウンロード中にユーザーに読み込みインジケーターを表示できます。ダウンロード完了後、リソースは標準のFileManagerおよびNSDataAssetメカニズムを介してメインアプリバンドルで利用可能になります。
ODRクォータ はiOSのバージョンによって異なります。iOS 13以降、デバイスはアカウントごとに最大20GBのオンデマンドリソースを保存できます。この容量はデバイスにインストールされているすべてのアプリ間で共有されます — 1つのアプリが多くの容量を占めると、他のアプリに残る容量が少なくなります。
使用済み容量の監視 はNSBundleResourceRequestを介して行われます。アプリは利用可能なODRストレージを確認し、それに応じて最初にどのリソースを読み込むかを決定できます。フォールバックメカニズムを実装することをお勧めします:ODRストレージがいっぱいの場合は、メインバンドルから品質を落としたリソースを使用します。
クォータを超えると、システムは最も最近使用されていない順にオンデマンドタグのリソースを削除し、最も古いものから始めます。アプリコードのリソースマネージャーは、NSBundleResourceRequestプロパティを介して現在のODRストレージ使用量を追跡できます。開発者は、iOS がいつでもオンデマンドリソースを削除することを決定する可能性があることを考慮する必要があります — アプリは以前に読み込まれたリソースが突然利用できなくなる状況を正しく処理する必要があります。リソースアクセスエラーをインターセプトし、beginAccessingResourcesを介して再リクエストすることをお勧めします。アプリが機能するために不可欠な重要なリソースには、システムによって削除されない初期インストールタグを使用してください。
On-Demand Resources は開発者にアプリサイズ管理の柔軟なツールを提供しますが、ネットワークの可用性やiOSのストレージポリシーに関連するいくつかの制限があります。
ODR の主な利点は、初期インストールサイズの大幅な削減です。複数のレベルを持つゲーム、動画コンテンツを含むアプリ、または大規模な画像セットは、コンテンツを分割して読み込むことができます。ユーザーはすぐに基本機能にアクセスでき、追加のリソースはバックグラウンドでダウンロードされます。
ODR は最初のアクセス時にリソースを読み込むために常時インターネット接続が必要です。カバレッジが悪い地域のユーザーは遅延やダウンロードエラーが発生する可能性があります。さらに、Appleはダウンロードしたリソースがデバイスに残ることを保証しません — ストレージが不足すると、iOSは警告なしにオンデマンドタグを削除することがあります。
よくある質問
ODR を使用すると、App Storeで新しいバージョンを公開せずにリソースを追加および変更できます。Xcodeを介してAppleサーバー上のファイルを更新し、同じタグに割り当てるだけです。次のリクエスト時に、アプリはリソースの最新バージョンを受け取ります。これは季節限定コンテンツ、一時的なプロモーション、新しい画像やレイアウトのA/Bテストに便利です。
システム は、他のアプリの領域を解放する必要がある場合、オンデマンドタグのリソースを削除します。初期インストールタグのリソースは削除されません。削除順序は LRU(Least Recently Used) アルゴリズムによって決定されます — 最も長い間アクセスされていないリソースから最初に削除されます。
iOS 13 以降、ODRストレージの合計制限はApple IDユーザーあたり20 GBです。最適なダウンロードパフォーマンスのために、単一のタグサイズは 512 MB を超えないようにする必要があります。制限を超えると、リクエストはNSBundleResourceRequestLowDiskSpaceErrorで失敗します。
はい、ダウンロード後、リソースはローカルキャッシュに保存され、インターネット接続なしで オフラインモード で利用可能です。問題が発生するのは、iOSがストレージ不足のためにリソースを削除し、ユーザーがネットワークなしでアクセスしようとした場合のみです。
ODR はApp Storeインフラストラクチャと統合されています:リソースはAppleのCDNでホストされ、キャッシュシステムによって管理され、開発者が独自のサーバーをセットアップする必要はありません。URLSession にはサーバーインフラストラクチャ、バージョン管理、手動キャッシュ管理が必要です。ODRはまた、接続が中断された場合のダウンロード再開を自動的に処理します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。