
-
Appleがホストするバックグラウンドアセットの詳細
このセッションでは、バックグラウンドアセットの知識に基づいて、ゲームやその他のアプリ向けのコンテンツのアセットパックをダウンロードする新しい機能を紹介します。Appleがこれらのアセットパックをホストする方法や、自己ホストのオプションを管理する方法を確認します。ネイティブのAPI統合と対応するApp Storeでの実装について詳しく説明し、アプリのコンテンツ配信とユーザー体験を向上させるためのツールを提供します。
関連する章
- 0:00 - イントロダクション
- 1:01 - バッググラウンドアセットの新機能
- 7:32 - サンプルアプリの開発
- 17:24 - ベータテストと配信
リソース
関連ビデオ
WWDC25
WWDC23
-
このビデオを検索
こんにちはGabrielです App Storeチームの ソフトウェアエンジニアです Jennyです App Processingチームのエンジニアです ここでは バックグラウンドアセットを 使用して App Storeで アプリのアセットを配信する 新しい方法を紹介します 皆さんのアプリとアセットがユーザーの デバイスでどのように連携するか説明します また アセットでAppleホスティングを 使用する方法を紹介します このセッションでは まず バックグラウンドアセットなど 現在利用可能なアセット配信技術を 確認します 次に 今年の新機能を紹介します バックグラウンドアセットを管理する SwiftとObjective-Cの新しいAPIや Appleホスティングなどです
iOS iPadOS macOS tvOS visionOSの アプリに新機能を組み込む方法と ローカルテストを実施する方法を紹介します
Appleによるアセットのホストと配信を 希望する皆さんのために ベータ版テストやApp Storeでの配信を 準備する方法を 説明します
ではGabrielがバックグラウンドアセットの 概要と新しい機能について説明します
ありがとう Jenny ユーザーはApp Storeから アプリをダウンロードするとき すぐに使用できると期待しています アプリを開いた後 別のダウンロードが 必要な場合 アプリを放置したり 削除したり することがあります
バックグラウンドアセットを使うと 優れた初回起動時の体験を 簡単に提供できます システムがアセットをデバイスに ダウンロードする方法を構成でき メインアプリを更新する必要なく アセットを更新できます 例えば ゲームを新しく ダウンロードしたユーザーにのみ すぐにプレイできるように チュートリアルレベルを提供し ゲームの残りの部分をバックグラウンドで ダウンロードできます アプリ内課金で有効になるダウンロード 可能なオプションコンテンツ 別名DLCを提供できます App Storeへの迅速な提出プロセスにより デバイス上の機械学習モデルを更新できます チュートリアルを含む複数の 異なるレベルがあるゲームを 開発しているとします 各レベルでアセットを配信する 次の4つのオプションがあります メインのApp Bundleにすべて保持 URLセッション オンデマンドリソース バックグラウンドアセット それぞれに長所と短所があるので それを説明します
メインのApp Bundleに すべて保持する場合 チュートリアルレベルを始める だけの場合でも ユーザーはアセットがすべてダウンロード されるのを待つ必要があります また ほとんどのプラットフォームで 4GBのサイズ制限に達する可能性があり アセットの一部を更新するために アプリ全体を再アップロードし 再提出する必要があります オンデマンドリソースの場合 ユーザーは より迅速にチュートリアルを開始できます TestFlightやApp Storeから App Bundleの一部を 個別にダウンロードできるからです ただこの場合も アセットファイル数個の更新に アプリ全体を更新する必要があります オンデマンドリソースは古い技術であり 非推奨になる予定です
その後継がバックグラウンドアセットであり デベロッパがアプリのアセットを 独自のサーバでホストします アセットはいつでも更新でき アプリ全体の更新は不要です Background Assetsの中核は ダウンローダー拡張機能です ユーザーがアプリを開く前に アセットを ダウンロードするスケジュールを コーディングできます これは ダウンロードの動作と後処理を 完全に制御する場合に 最適です しかし 皆さんの多くにとって 重要なことは アプリの アセットが利用可能で 最新の状態であることです 新しい Managed Background Assets機能では システムがアセットパックのダウンロード 更新 圧縮などを自動的に管理します 実際 当社はシステム提供のダウンロード または拡張機能を作成しました これはカスタムコードなしで アプリに組み込めます さらに TestFlightおよびApp Store上の アプリ向けの Appleがホストする 新しいバックグラウンドアセット サービスを使用すると Appleホスティングオプションを使用して 独自のサーバ上でアセットを ホストする必要がありません Apple Developer Programの メンバーシップに含まれる 200GBのAppleホスティング容量を 利用できます
現在オンデマンドリソースを 使用している場合は バックグラウンドアセットへの移行を 開始することをお勧めします Managed Background Assetsでは 複数のアセットパックを作成し ゲームのチュートリアルレベルのための テクスチャ サウンドエフェクト GPUシェーダなどアセットファイルの 一部をそれぞれのアセットパックに グループ化します システムはダウンロードポリシーに基づき アセットパックをユーザーのデバイスに 自動的にダウンロードします ダウンロードポリシーには 必須 プリフェッチ オンデマンドの 3つがあります 必須ダウンロードポリシーでは システムが自動的に アセットパックをダウンロードし インストールプロセスに ダウンロードを統合します アセットパックは App Store TestFlight ホーム画面でユーザーが目にする ダウンロードの進行状況全体に寄与します インストールが完了して ユーザーがアプリを開くと アセットパックは使用できる状態です
プリフェッチダウンロードポリシーでは アプリのインストール中にアセットパックの ダウンロードが開始されますが アプリのインストールが完了した後に ダウンロードがバックグラウンドで 続行される可能性があります オンデマンドダウンロードポリシーでは APIメソッドを明示的に呼び出して リクエストした場合のみ アセットパックがダウンロードされます アセットパックは自分でホストするほか Appleもホストできます ここからは Jennyが Appleのサーバでアセットパックとアプリの ビルドを配信する方法を説明します わかりました Appleがホストする各アセットパックは 複数のプラットフォームにわたる 1つのアプリに対して使用できます デバイスにアプリのバイナリとその アセットパックをダウンロードするには まず 両方をApp Store Connectに 別途アップロードする必要があります その後 TestFlightの外部テストおよび App Storeでの配信に関する 審査のために提出できます
アップロードされたアセットパックには バージョンが割り当てられます これは特定のアプリのビルドに 紐付けられていません デバイス上でのアプリと アセットパックの対応はアセットパック バージョンの状態で決まります 例を挙げて説明します
同じアセットパックに対して 3つの異なるバージョンが あるとします バージョン1はApp Storeで公開済みで バージョン2はTestFlightで 外部ベータ版として公開され バージョン3はTestFlightで内部ベータ版 として公開されます 各コンテキストで公開できる アセットパックのバージョンは1つだけです 同時に App Storeから ダウンロードした または TestFlightの 外部ベータ版や内部ベータ版として ダウンロードしたアプリのビルドが デバイス上にあります サーバは その特定のコンテキストにある すべてのアプリビルドに対応する アセットパックの公開バージョンを 配信します
つまり App Storeからダウンロードされた アプリのバージョン1.0ビルド1は アセットパックバージョン1を使用します
TestFlightの外部ベータ版で利用可能な アプリのバージョン2.0ビルド1は アセットパックバージョン2を使用します 内部ベータ版のアプリのバージョン2.0 ビルド2および3は アセットパックバージョン3を使用します
ここで アセットパックバージョンの 更新を行うときの動作を 理解することが重要です
例えば アセットパック バージョン2が完成した場合 App Storeでの配信用に提出できます それが古いバージョンの代わりに App Storeで公開されます
つまり App Storeから ダウンロードされたアプリの すべてのバージョンは ユーザーのデバイスにインストール されている古いバージョンも含め アセットパックバージョン2を 使用するように自動的に切り替えられます そのため アセットパックを更新する前に 古いビルドやバージョンでも 機能するか確認します 次にアプリのビルドを更新する 例を見てみましょう 例えば アプリのバージョン2.0ビルド3を 外部ベータ版テスト用に 送信するとします 承認後 外部ベータ版を通じて ビルドがダウンロードされた場合 そのビルドは古いアセットパックである バージョン2を使用します 新しいアセットパックバージョン3が 使用されるようにするには アセットパックバージョンも 確実に提出してください アセットパックの概念を 理解できたと思いますので Gabrielに作成方法とアプリでの使用方法を 説明してもらいましょう ありがとう Jenny では アプリでManaged Background Assetsを使用する方法を説明します
Managed Background Assetsの 使用を開始するには アセットパックを作成し 新しいAPIを採用して アプリとアセットパックを ローカルでテストします
アセットパックの作成方法を説明します
macOS Linux およびWindows用の 新しいパッケージ化ツールを使用して ソースリポジトリからファイルを取得し TestFlightやApp Storeへの 配信用に 圧縮アーカイブとしてパッケージ化できます パッケージ化ツールはmacOSの Xcodeに同梱されており Linux Windows用も Apple Developerサイトのダウンロードページで まもなく入手できます ツールの動作をお見せします
まず ターミナルコマンドを実行して マニフェストテンプレートを生成します macOSでXcodeをインストールしターミナルで xcrun ba-package templateを実行します LinuxまたはWindowsでは シェルの 検索パスでツールを使用可能にし ba-package templateを実行します パッケージ化ツールがマニフェスト テンプレートを生成します マニフェストはJSONファイルで 入力してAppleに アセットパックについて伝えます カスタムIDはデベロッパが選択できます これを使用して アプリのコード ダウンロードポリシー 対応プラットフォームで アセットパックを識別します
まず ファイルセレクタを入力しましょう ファイルセレクタはアセットパックに含める ソースリポジトリ内のファイルセットを 選択します ファイルセレクタは2種類あります 個々のファイルを選択するものと ディレクトリ全体を選択するものです
ソースリポジトリのルートからの 相対パスを使用して ゲームの紹介用カットシーンビデオの ファイルセレクタを追加しましょう
ゲームのチュートリアルレベルの アセットファイルが含まれるため IDはTutorialとします 次にダウンロードポリシーを設定します チュートリアルはユーザーが 最初に体験するため ユーザーが初めてゲームを開く前に アセットパックを ローカルで利用可能にします この状況は必須ダウンロードポリシーを 使用するのに最適です
このチュートリアルレベルは新規にゲームを インストールするユーザーにのみ関係します すでにゲームをプレイしているユーザーや 新バージョンに更新するユーザーは チュートリアルを再度ダウンロードする 必要がありません
そこで 必須ダウンロードポリシーを 最初のインストールのみに制限して 以降の更新は除外します つまり ダウンロードが初めての ユーザーのみ チュートリアルのアセットを取得します
マニフェストを入力したので パッケージ化ツールをもう一度実行して 圧縮アーカイブを生成しましょう 現在のディレクトリを リポジトリのルートに設定し マニフェストへのパスと アーカイブの保存先のパスを指定します アセットパックをパッケージ化したので ゲームで使用する方法を確認します
わずか数行のコードで バックグラウンド アセットの新しいAPIを使用して アセットパック内のファイルを 読み取ることができます まず ダウンローダー拡張機能を Xcodeに追加します ダウンローダー拡張機能は メインアプリが 動作していないインストール中などに アプリでアセットパックをダウンロード するようにスケジュールするものです
対象を追加し Background Download テンプレートを選択します
ここでは Appleホスティングを使用するか 独自にホストするかを選択できます
Swiftコードが生成されますが Objective-Cコードに 簡単に置き換えることができます
今年新たに システムはフル機能の ダウンローダー拡張機能を提供し 自動ダウンロードやバックグラウンド更新 などをサポートしており カスタムコードなしで アプリに組み込むことができます Background Downloadテンプレートで Xcodeが生成したスニペットは デフォルトでシステム実装を使用する ようにすでに設定されています 他の拡張機能コードは必要ありません
実際 ダウンロード動作をカスタマイズ する必要がない場合は スタブのshouldDownload(_:)メソッドを 削除できます つまり Xcodeが生成した わずか数行のコードを使用して アプリにダウンローダー拡張機能を 追加できます
ダウンロード動作をカスタマイズする場合は shouldDownload(_:)の カスタム実装を提供できます 新しいアセットパックごとに shouldDownload(_:)実装が呼び出され ダウンロードポリシーに基づいて バックグラウンドでの ダウンロードを計画し ダウンロードの続行を 決定するブール値を返せます これはアセットパックの一部に 特定の互換性要件がある場合に便利です ダウンローダー拡張機能を実装したので ダウンロードしたアセットパック内の ファイルをアプリで使う方法を説明します
最初のステップは 共有された AssetPackManagerにおいて ensureLocalAvailability(of:)を 呼び出すことです このメソッドはアセットパックが現在 ダウンロード済みかどうかを確認します そうでない場合は ダウンロードを開始し ダウンロードが完了するのを待ちます 多くの場合 ダウンローダー拡張機能がアセットパックを すでにダウンロードしているので メソッドはすぐに戻ります アセットパックを新規ダウンロードする 必要があるまれな状況では 目に見える進捗情報を アプリのユーザーに 提供することをお勧めします
SwiftではstatusUpdates(forAssetPackWithID:) メソッドが返す 非同期シーケンスのステータス更新情報を 待つことができます
Objective-Cでは BAManagedAssetPackDownloadDelegate プロトコルに適合するオブジェクトを作成し 共有されたアセットパックマネージャの delegateプロパティにアタッチできます
ダウンロードのキャンセルが必要な場合は ダウンロードステータスの 更新情報で受け取った 進捗構造体に対し cancel()を呼び出します ensureLocalAvailability(of:)がエラーを スローせずに戻ったら ローカルで リクエストしたアセットパックを 使用できます
ファイルを読み取るには contents(at:searchingInAssetPackWithID:options:) メソッドを マネージャに対して呼び出します 最初のパラメータはソースリポジトリの ルートからの相対パスです つまり以前にパッケージ化ツールを実行して アセットパックを作成したディレクトリから 読み取るファイルまでのパスです システムは すべてのアセットパックを 共有名前空間に自動的にマージし 開発マシンからユーザーのデバイスに コピー&ペーストしたかのように ソースリポジトリを 効果的に再構築します つまり 実行時に特定のファイルを 読み取る場合 どのアセットパックに そのファイルが含まれているかの トラッキングに煩わされません contents(at:searchingInAssetPackWithID:options:)は デフォルトで メモリマップトデータインスタンスを 返します メモリ内のスペースを多く消費する 大きなアセットファイルにも有効です
手続き的にファイルを メモリに読み込む場合など ファイル記述子への低レベル アクセスが必要な場合は descriptor(for:searchingInAssetPackWithID:) メソッドを 代わりに使用できます その場合 使い終わった記述子を 閉じる処理を 含める必要があります また どちらかのメソッドの assetPackIDパラメータに nilでない引数を指定することで 検索を特定のアセットパックに 制限することもできます ダウンロードしたパックを トラッキングし バックグラウンドで自動的に アセットパックを最新の状態に保ちます ただし アプリがインストール されている間は アセットパックは自動的に削除されません そのため 特定のアセットパックを 使用なくなった場合は 共有されたアセットパックマネージャに 対してremove(assetPackWithID:)メソッドを 呼び出してストレージ領域を 解放することをお勧めします 例えば ユーザーがチュートリアル レベルのプレイを終えたとき チュートリアルのアセットパックを 削除できます
ユーザーがゲームの進捗を リセットして チュートリアルを もう一度プレイし始めた場合など いつでも ensureLocalAvailability(of:)を呼び出し アセットパックを再度ダウンロード することができます
ユーザーはデバイスの設定アプリの ストレージビューで アプリとダウンロードしたアセット パックが消費しているストレージ容量を 確認できることに注意してください 次のステップはメインアプリと ダウンローダー拡張機能の両方を 同じアプリグループに追加することです システムは メインアプリと拡張機能の 間の調整を容易にするために アプリグループを使用します
アプリグループIDを文字列値として使用し BAAppGroupIDキーを メインアプリのInfo.plistに追加します
また trueまたはyesをブール値として指定し BAHasManagedAssetPacksキーを追加します
Appleホスティングを使用する場合は trueまたはyesをブール値として指定し BAUsesAppleHostingキーを追加します Appleホスティングを使用しない場合 このセッションのリソースセクションで 関連ドキュメントを参照して BAManifestURLなど 他の必要なInfo.plistキーの詳細を 確認してください アプリと拡張機能を設定したので 次にテストを行います
TestFlightまたはApp Storeにアプリを 提出する前に アセットパックの ダウンロードをテストするための macOS Linux Windows用のバックグラウンド アセット模擬サーバを作成しました パッケージ化ツールと同様に 模擬サーバは macOSのXcodeに同梱されており LinuxおよびWindows用もまもなく Apple Developer Webサイトの ダウンロードセクションで入手できます バックグラウンドアセットでは ダウンロードすべてにHTTPSを使用します 最初にSSL証明書を 発行する必要があります そのためにルート認証局を作成します さらに その認証局をテストデバイスに インストールします その後 認証局を使用して SSL証明書を発行し 最後に 模擬サーバを起動して そのSSL証明書を指定します 詳しくは このセッションの リソースセクションで 関連するドキュメントをご参照ください SSL証明書を発行したら ba-serveを実行して 模擬サーバを起動し 提供するアセットパックアーカイブへの それぞれのパスを渡して バインドするホストを設定します ホストには IPアドレス ホスト名 またはドメイン名を指定できます macOSでは IDを 選択するよう求められます これは証明書とキーチェーンから 得られる秘密鍵のペアです LinuxまたはWindowsでは証明書と秘密鍵を コマンドライン上で渡す必要があります helpフラグを渡すと カスタムポート番号を 設定するオプションなど 追加のオプションを確認できます また macOSでは IDのプロンプトを スキップする機能が近日追加される予定です iOS iPadOS visionOSや 近日公開予定のtvOSのテストデバイスでは の で ホストとポートを含め模擬サーバの ベースURLを入力します macOSのテストデバイスでは xcrun ba-serve url-overrideを実行し 同じ情報を入力します
Xcodeでアプリをビルドして実行する場合は 該当のアセットパックが 模擬サーバからダウンロードされます ここからは再びJennyが ベータ版テストとアセットパックの 配信について説明します - Jenny お願いします - ありがとう Gabriel 新しいアプリのバイナリパックと アセットパックを準備できたので TestFlightのベータテストと App Storeでの配信を 準備する方法を説明します
Appleホスティングを使用している場合は アプリバイナリとアセットパックの両方を 別途App Store Connectにアップロードし 必要に応じてTestFlightでテストし 最終的にApp Storeで配信します
アセットパックでの このプロセスを詳しく見てみましょう アセットパックは複数の方法で アップロードできます
ドラッグ&ドロップのUI体験を求める場合 macOS用のTransporterアプリが使えます
完全な制御と透明性を求める場合は App Store Connect REST APIで 独自の自動化を構築できます 簡素化されたコマンドライン操作を ご希望の場合は クロスプラットフォームの iTMSTransporterの便利なコマンドで App Store Connect APIを リクエストできます これらのツールの詳細については ドキュメントをご参照ください ここでは TransporterとApp Store Connect APIの使い方を説明します Transporterアプリでは Tutorial.aar アーカイブをTransporterのウィンドウに ドラッグ&ドロップするだけです
それを追加するアプリを選択し をクリックします チュートリアルのアセットパックの 新しいバージョンが生成されます
アセットパックのアップロードの状態を Transporterアプリで確認できます
アップロードプロセスの完全に 確認することを希望する場合は App Store Connect APIがお勧めです 次の3つの手順に従う必要があります アセットパックレコードを作成し アセット パックのバージョンレコードを作成します 次にアセットパックバージョンに対する アーカイブをアップロードします まず アセットパックレコードを 作成するには backgroundAssetsリソースに対する POST要求を行います
要求本文に アセットパックの名前 assetPackIdentifierを入力し アプリのApple IDを relationshipsセクションに 追加します これを呼び出すと応答として アセットパックのUUIDが返されます それを後のAPI呼び出しで使用できます
backgroundAssetVersionsリソースに POSTを要求して アセットパックの新しいバージョンを 作成します
relationshipsセクションには 前のAPI応答で提供された アセットパックのIDを使用します この操作により 既存のバージョンに 基づいてバージョン番号が 自動的に繰り上がります ここではバージョン1です また 応答で取得するIDでチュートリアルの アセットパックのバージョン1を 一意に特定できます
アセットパックバージョンを 正常に作成したら backgroundAssetUploadFilesリソースを 使用して Tutorial.aarアーカイブファイルの アップロードを予約します App Storeのスクリーンショットなどの 他のアップロード操作と似ています
ここでは アセットタイプ ファイル名 ファイルサイズ MD5チェックサムが必要です
また バックグラウンドアセットの バージョンIDとの関係も含めます この呼び出しの応答には アップロードファイルのIDと アップロード手順の詳細が含まれます
アーカイブのアップロードに成功したら アップロードファイルIDを指定して backgroundAssetUploadFilesに対する PATCH呼び出しを行うと アセットパックの処理が開始されます
アセットパックの進捗を確認するには App Store Connectや App Store Connect APIで 利用可能なアセットパックについての 最も包括的な情報を 常に得ることができます
App Store Connectでは タブで アセットパックの 処理ステータスを確認できます アップロードが正常に処理されると ステータスはになります TestFlightの内部テスト用に 公開されているアプリビルドで 新しいバージョンを使用できます アセットパックの新しいバージョンの準備が できたことを通知するメールが届きます この通知を受け取るために Webhookを設定することもできます
今年追加されたWebhookの機能は WWDC25の 「Automate your development process with the App Store Connect API」 セッションをご覧ください
ただし 処理中にアセットパックの アーカイブファイルに 問題が見つかった場合は バージョンの状態はになり 通知も送信されます その場合は問題を修正し アセットパックを新しいバージョンとして 再度アップロードできます App Store Connect APIを使用すると GET要求を行って様々な リソースを得ることができ アプリのすべてのアセットパックのリスト 各アセットパックのバージョンや 状態を確認できます backgroundAssetVersionsリソースで アップロードをトラッキングできます
アセットパックが処理されると 内部ベータ版リリースリソースが 作成されます アセットパックバージョンは READY_FOR_TESTINGです
アプリのバイナリとアセットパックの 両方を正常にアップロードしたら TestFlightで ベータ版テストを開始できます
App Store Connectでは 現在 チュートリアルのバージョン1が内部 テストの準備済みであることがわかります より多くの人たちを対象にアプリビルドと アセットパックバージョンを テストする場合 それらを外部テスト用に別途提出できます
アセットパックを提出するには 特定のバージョンをクリックし を 選択します バージョンが承認されると状態が に変化し 通知が届きます
App Store Connect APIでは betaBackgroundAssetReviewSubmissions リソースを使用して アセットパックバージョンを提出できます
外部ベータ版リリースリソースで 審査状況をトラッキングできます これはアセットパックバージョンの 外部テストの準備ができたことを示します
テスト後 アセットパックバージョンを App Storeで公開する 準備ができたら App Storeで配信するために App Reviewに提出できます
App Store Connectのタブに 移動してアセットパックを表示できます 1つのアセットパックバージョン のみを提出したり 他のアセットパック アプリバージョン または他の審査アイテムと 一緒に提出したりできます アセットパックバージョンと アプリバージョンを一緒に提出した場合 App Reviewチームは選択したアセット パックバージョンを使用して アプリを審査します
審査用のアセットパックを追加するには をクリックし
バージョンを選択して 審査用に追加します
提出が承認されると アセットパックバージョンが になります
App Store Connect APIを使用する場合 reviewSubmissionsリソースを使用して 審査に提出することもできます
審査中に App Storeリリース リソースで審査の状態を 確認できます 配信準備完了になった場合 アプリを使用しているユーザーは App Storeから新しいアセットを ダウンロードできます 今回は かなり多くのトピックを 取り上げました アセットパックの概要 アセットパックの 作成 アプリでの使用 Appleホスティング用の アップロードと提出です 新しいManaged Background Assetsを使うのに 役立てば幸いです
次は皆さんの番です パッケージ化ツールを使用して最初の アセットパックを作成してみてください さらに 現在オンデマンドリソースを アプリで使用している場合は バックグラウンドアセットに 移行する方法を評価してください ドキュメントを基に新しいバックグラウンド アセットAPIをアプリに採用してください ご意見をお待ちしています フィードバックアシスタントで 役立った内容や改善点を お知らせください App Store Connectに今年追加された その他の新しい機能については 「What's new in App Store Connect」を ご視聴ください さらに バックグラウンドアセットの 既存機能の詳細と ローカルテストに関する 役立つヒントについては WWDC23の「What's new in Background Assets」のセッションをご覧ください
ご視聴ありがとうございました ご意見をお待ちしています
-
-
8:26 - Fill out the manifest
{ "assetPackID": "[Asset-Pack ID]", "downloadPolicy": { "essential": { // Possible keys: “essential”, “prefetch”, or “onDemand” // Essential and prefetch download policies require a list of installation event types. For an on-demand download policy, the value for the “onDemand” key must be an empty object. "installationEventTypes": [ // Remove undesired elements from this array. "firstInstallation", "subsequentUpdate" ] } }, "fileSelectors": [ // You can add as many file and/or directory selectors as you want. { "file": "[Path to File]" }, { "directory": "[Path to Directory]" } ], "platforms": [ // Remove undesired elements from this array. "iOS", "macOS", "tvOS", "visionOS" ] }
-
10:44 - Add a downloader extension
import BackgroundAssets import ExtensionFoundation import StoreKit @main struct DownloaderExtension: StoreDownloaderExtension { func shouldDownload(_ assetPack: AssetPack) -> Bool { return true } }
-
11:39 - Download an asset pack
let assetPack = try await AssetPackManager.shared.assetPack(withID: "Tutorial") // Await status updates for progress information let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: "Tutorial") Task { for await statusUpdate in statusUpdates { // … } } // Download the asset pack try await AssetPackManager.shared.ensureLocalAvailability(of: assetPack)
-
12:22 - Receive download status updates in Objective-C
#import <BackgroundAssets/BackgroundAssets.h> @interface ManagedAssetPackDownloadDelegate : NSObject <BAManagedAssetPackDownloadDelegate> @end @implementation ManagedAssetPackDownloadDelegate - (void)downloadOfAssetPackBegan:(BAAssetPack *)assetPack { /* … */ } - (void)downloadOfAssetPackPaused:(BAAssetPack *)assetPack { /* … */ } - (void)downloadOfAssetPackFinished:(BAAssetPack *)assetPack { /* … */ } - (void)downloadOfAssetPack:(BAAssetPack *)assetPack hasProgress:(NSProgress *)progress { /* … */ } - (void)downloadOfAssetPack:(BAAssetPack *)assetPack failedWithError:(NSError *)error { /* … */ } @end
-
12:29 - Attach the delegate in Objective-C
static void attachDelegate(ManagedAssetPackDownloadDelegate *delegate) { [[BAAssetPackManager sharedManager] setDelegate:delegate]; }
-
12:33 - Cancel an asset-pack download
let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: "Tutorial") for await statusUpdate in statusUpdates { if case .downloading(_, let progress) = statusUpdate { progress.cancel() } }
-
12:41 - Use an asset pack
// Read a file into memory let videoData = try AssetPackManager.shared.contents(at: "Videos/Introduction.m4v") // Open a file descriptor let videoDescriptor = try AssetPackManager.shared.descriptor(for: "Videos/Introduction.m4v") defer { do { try videoDescriptor.close() } catch { // … } }
-
13:56 - Remove an asset pack
// Remove the asset pack try await AssetPackManager.shared.remove(assetPackWithID: "Tutorial") // Redownload the asset pack let assetPack = try await AssetPackManager.shared.assetPack(withID: "Tutorial") try await AssetPackManager.shared.ensureLocalAvailability(of: assetPack)
-
14:53 - Info.plist
<key>BAAppGroupID</key> <string>group.com.naturelab.thecoast</string> <key>BAHasManagedAssetPacks</key> <true/> <key>BAUsesAppleHosting</key> <true/>
-