
-
バックグラウンドでのタスクの完了
バックグラウンド実行の機能強化を紹介し、システムがどのようにランタイムをスケジュールするかについて説明します。アプリでバックグラウンドランタイムを最大限に活用し、フォアグラウンドでの優れた体験を維持しつつ、バックグラウンドで機能を提供する方法を学びましょう。APIがアプリにバックグラウンドランタイムを提供する方法や、さまざまなユースケースに合わせて各APIをカスタマイズする方法について説明します。例えば、iOSおよびiPadOS26の新しいAPIを使用すると、アプリがフォアグラウンドからバックグラウンドに移行する際にタスクを完了できます。
関連する章
- 0:00 - ようこそ
- 1:22 - イントロダクション
- 2:09 - 動作と制約
- 7:29 - バックグラウンドタスクに関するAPI
- 11:23 - 継続的処理タスク
リソース
-
このビデオを検索
こんにちは Appleの ソフトウェアエンジニア Ryanです アプリでバックグラウンドランタイムを 活用する方法についてお話しします
App Storeには何百万ものアプリがあります それぞれにユニークなところがあります アプリは前面で注目を浴びるとき 一番輝きます ピクセル単位で自由に設計して ユーザーの記憶に残る体験を 作り出すことができます
みなさんのようなデベロッパには 速くて 便利で 作りこまれたアプリが 期待されています でも アプリがバックグラウンドに 遷移するとどうなりますか
このセッションでは バックグラウンド ランタイムについて説明します 効率が高く 正確に動作する アプリに適したツールキットを構築します ただ動作するだけでなく 実用的なアプリを目指します プリフェッチや同期 アップロードを行って 次回起動時の成功に向けて アプリを設定します バックグラウンドランタイムを上手に 活用すると アプリの体感スピードが増し とてもスムーズに 動くようになります
まず フォアグラウンドとバックグラウンドの 意味を簡単に説明します そして バックグラウンドでアプリが 実行されるタイミングと頻度を システムがどのように決定するか いくつかの原則を共有します
次に そのための 既存の手段の多くを取り上げます フォアグラウンドで開始されたタスクを 継続するための新しいAPIにも触れます
フォアグラウンドアプリには 共通したリズムがあります
アプリ本体 そしてアプリに 必要なものすべてです フレームワークやアセットなどが メモリに読み込まれます これが デバイスで アプリのインターフェイスに 光が当たっている状態です アプリは フォアグラウンドとして定義されます
ユーザーがアプリを離れても プロセスはまだ生きています バックグラウンドに入ります デフォルトでは バックグラウンド アプリは一時停止します CPU時間を使いません バッテリー駆動時間は減らず プライバシーが保護され フォアグラウンドアプリのために リソースを解放します
場合によっては アプリはバックグラウンド 稼働時間をリクエストして 一時停止される前に 実行中の作業を終わらせます ユーザーがAppスイッチャーで アプリに戻ってくると アプリはフォアグラウンドに移動し システムによって再開されます
バックグラウンド ランタイムを使用する前に システムがリソースに優先順位を付けて 管理する方法について理解し アプリで最適な体験を 構築するために何ができるかを 見てみましょう
システムの主な目標はシンプルです バッテリー駆動時間の保護 パフォーマンスの最適化 同時に 流動的で応答性の高い エクスペリエンスを維持することです つまり バックグラウンドでの 実行は保証されません むしろ 便宜的で 多くの場合に裁量的で 厳重に管理されています 成功するワークロードは このコンテキストを理解し システムに逆らうのではなく 連携して働くように設計されています
最も基本的な制約はエネルギーです
すべてのオペレーション CPUサイクル GPUレンダリング ネットワークリクエスト Neural Engine使用でさえ バッテリーを消費します バッテリー駆動時間は 有限のリソースです それを維持するため システムは デバイスのスリープ解除時に 作業をまとめて 不必要な バックグラウンドアクティビティを 削ります これを一日中行っています バックグラウンドランタイムは 有限なので アプリが 個別にカスタマイズした タスクとして実行すべきなのは 何か考えます 各タスクは効率よく動作して システムの優先順位と制約を常に意識します このバックグラウンド作業は バッテリー設定に反映されます ここで ユーザーはバッテリー駆動時間に 大きな影響を与えるアプリを確認できます iOS 26では アプリごとの詳細な内訳で デバイスバッテリーのパフォーマンスに関する たくさんの情報が得られます
ここでのベストアクションは 効率的であることです タスクをすぐに実行する必要がなければ デバイス充電まで延期することを 検討してください 実行する必要があるなら タスクを軽量化し 目的志向にします
バッテリーに加えて システムには メモリ CPU時間 ネットワーク帯域幅などの 他の共有リソースを管理する役割もあります デバイスの使用中には フォアグラウンドアプリが優先されます バックグラウンドアプリが メモリまたはCPUを大量に消費する場合 単に非効率的なだけでなく フォアグラウンドでの 体験とも競合します そうすると システムが介入します リソースを大量消費するプロセスを スロットリング 一時停止 または終了することもあります
要点はシンプルです バックグラウンド作業は 最小限にします 作業の肥大化を避け バッチ処理を優先させて メモリ占有量を最小限に抑えます
ワークロードが適切に動作している場合でも ずっと実行し続けられる 保証はありません バックグラウンド作業のキューが 空になることはありません それで システムは他のワークロードを 優先させるかもしれません とはいえ これはチーム作業です システムはフォアグラウンドの 体験を最大化するという 自分の仕事をこなしています
ワークロードには回復性が必要です 段階的な進捗を早い段階から 頻繁に保存しましょう 時間切れのシグナルに迅速に対応し システムがすぐに自分の ワークロードに戻ると信頼してください システムは協力的なプロセスを高く評価して これらの動作を参考に 将来のスケジュールを設定します でも結局のところ 最終決定権はデバイスを使用する ユーザーにあります ユーザーの設定変更は スケジュールに影響します 低電力モード Appのバックグラウンド更新 省データモードなどです システムは透明性を提供しており ユーザーが自分でこれらを 決定できるようにしています 例えば みなさんのアプリが バックグラウンドで 大量に バッテリーを消費する場合 ユーザーは みなさんにとって 不利になる決定をするかもしれません
それで バックグラウンド作業は 礼儀正しくあり 軽量であり 設定を尊重する 必要があります 提供する価値に見合った 存在感を心がけます さて システム内のすべてのプロセスが これらの原則を完全に採用したとしても 実行環境は複雑で非常に動的です
ネットワーク可用性 CPU負荷 デバイスアクティビティ 温度状態 バッテリーレベルなどはすべて スケジュールの決定に影響を与える コンテキストとして使用されます
幸いなことに システムは この大変な条件を把握して 常に最適な体験を構築しています つまり 適切に設計されたタスクでさえ 条件が適切でなければ 大局的な最適化のために 延期されるということです 適応性を維持することは 特に重要です 作業をアトミックで 軽量なものにしつつ 自分の要件も明確に通知します 中断箇所から再開するよう ワークロードを設計すると ランタイムが使用できるようになった時に 段階的に作業を進められます システムの状況や優先順位を 理解し 適応すればするほど ワークロードが成功する 確率も高くなります
効率的 最小限 回復性 礼儀正しさ 適応力 これらが プラットフォームに シームレスに適合する バックグラウンド作業を 構築するための鍵です 開発中には いくつか 鍵となる質問をしてみましょう
タスクを開始したのは誰ですか 作業は明示的に開始されましたか それとも 後で実行されるような 裁量的なものでしたか
作業時間はどれほどですか タスクの持続期間を 短期 中期 長期で分類してみてください この作業は アプリの状態や 最新化に不可欠でしょうか バックグラウンドのダウンロードで アプリは生き生きとしますが テレメトリをアップロードしても デバイスユーザーに 直接のメリットはありません 最後に その作業には同意や インプットが必要でしょうか
バックグラウンドランタイムはこの種類の ワークロードには適していません その場合は 別のアプローチを お勧めします このベースが整ったら タスク設計を 効果的に行う方法を 見ていきましょう iOSには バックグラウンドランタイムを リクエストできるさまざまなAPIがあります 各APIは 作業のサポート内容に 応じて 異なるタイプや プロファイルを想定しています これにより システムは 先ほどお話しした 制約と条件に合わせて アプリランタイムを 調整できます 例えば ユーザーは自分が最も 頻繁に使用するアプリのコンテンツが 常に最新で最高であることを 期待しています システムがアプリの使用パターンを理解して バックグラウンドタスクや サポートを最適化するのは合理的と言えます
ここで最初のAPI BGAppRefreshTaskが使用できます
このAPIで アプリはサーバのコンテンツを 使用直前に 目に見える動作なしで フェッチできます 礼儀正しさの 考え方も十分に反映されています システムはこれらのタスクを アプリの使用履歴と連携させます 頻繁に使用するアプリは スケジュールされる可能性が高くなり 起動のたびに 確実に 最新のコンテンツになります
SwiftUIでアプリの 更新タスクを作成するには BackgroundTask修飾子を シーンに追加します システムはバックグラウンドで アプリをスリープ解除するとき このクロージャを呼び出し クロージャが返されたときに アプリを一時停止します
更新タスクはフェッチベースの ユースケースをサポートしますが 更新頻度が低い または不規則な リモートドキュメントを管理する 必要があるかもしれません バックグラウンドプッシュ通知が 見事なソリューションを提供します サーバが新しいコンテンツに 関する通知を送信すると システムはアプリを適切なタイミングで スリープ解除し フェッチします 注意点として これは アプリの更新とは異なります この場合 便宜的にデータを フェッチするのではなく 更新がデバイスにプッシュされます
バックグラウンドプッシュ通知は 新しいリモートコンテンツを 知らせるためのものなので 常に裁量的なものと見なされます
また 低い優先度でまとめて送信され オーバーヘッドと電力消費を 最小限に抑えます
また ユーザーがAppスイッチャーから アプリを削除すると システムは ユーザーの意図を尊重します アプリがもう一度起動されるまで 通知はアプリに配信されません
ただし 場合によっては アプリに他の種類の 作業をさせたい場合があります 生成されたデータに対する MLモデルの実行や 単にデータベースの メンテナンス処理などです
BGProcessingTask APIは まさにそのためにあります
このタスクの登録は簡単です 必要なのは タスク識別子 コールバックキュー 実行時に呼び出されるクロージャです
BackgroundTasksは起動時に すぐに登録する必要があります そうすると システムは タスクがバックグラウンドで 起動したときに迅速に認識し そのハンドラをすぐに呼び出します 先ほど説明した 原則を達成するために 処理タスクも追加の構成を サポートします 例えば 遅延時間がそれほど 問題にならない作業の場合 賢いタスクは デバイスが充電器と ネットワークに接続されている時のみ 実行するという選択を するかもしれません アプリの占有量とバッテリー設定を 減らし バッテリーへの影響を 最小限にできます バックグラウンドで開始するタスク用に アプリがランタイムを取得するための APIについて説明しました 時には バックグラウンドに遷移する間 実行し続けるための 時間がもう少しだけ 欲しいかもしれません 開始と終了のバックグラウンドタスクAPIは 作業が中断し 未完で放置されると 回復できなくなる場合 アプリがその作業を 完了できるようにします
例として 状態の保存を 考えてみましょう 作業によっては 作業途中での終了は 質の低い体験につながります
これらのAPI呼び出しで コードをラップすると アプリは 中断できない重要な 作業の処理中だということが システムに通知されます このAPIは ファイルハンドルを クリーンアップしたり データベース接続を 切断する場合に最適です
iOSのバックグラウンド サポートは幅広く ユーザーが開始したものも含め さまざまなタスクを 処理できるように設計されています ユーザーが開始した操作を 確実に完了させることが 優れた体験には欠かせません iPadOSおよびiOS 26では BG継続的処理タスクが まさにこの機能をサポートします このタスクで アプリがバックグラウンドに なった後でも作業を続行できます システムはUIで進捗状況を伝えます 例えば ジャーナルアプリです 継続的処理タスクを使用して バックグラウンドでエクスポートを実行し 進捗状況を 開始者に反映します 完了すると システムは 一時的に更新され UIが自動的に閉じます 引き続き ユーザーに 主導権があります タスクの進捗状況を確認して いつでも作業をキャンセルでき 複雑な機能を有効にできます
継続的処理タスクはいつも ユーザーがアプリ内で実行する 明示的なアクションで開始されます ボタンのタップや ジェスチャーなどです 各タスクは ユーザーが アプリに実行させたい 明確で 直近の目標を表しています ファイルのエクスポートや ソーシャルメディアコンテンツの公開 接続されたアクセサリの 更新の完了などです このようなタスクの進捗は測定可能で タスクの終了が何を意味するかを 簡単に理解できます
ユーザーは 以前に アプリで設定済みだとしても タスクが自動的に開始するとは 思っていません メンテナンス バックアップ 写真の同期などの 自動ワークロードは 避けてください 明示的なアクションなしで タスクが始まると ユーザーはタスクの目的が理解できなかったり 何の進捗状況なのか わからないかもしれません このような想定外の作業を行うと アプリの タスクがキャンセルされる可能性があります これらのニーズについては より適した他のAPIを検討してください
これらのことが 頭に入っていれば 継続的処理タスクを 導入するのは簡単です まず タスク識別子を Info.plistに追加します これを使用して 状態と進捗状況の レポートを管理する起動ハンドラを 登録します 次に プロンプトが表示されたら タスクリクエストを送信します 識別子から始めましょう Info.plistにある 許可された バックグラウンドタスクのスケジューラ 識別子の配列に新しい値を追加して 定義します 先頭に自分のApp Bundle IDが 付いているか確認します
静的識別子以外にも 継続的処理タスクは 動的接尾辞を使用する 新しいワイルドカード表記も サポートします
ワイルドカード識別子は 常に自分のBundle IDで始まり その後にセマンティックな コンテキストが続きます ここでの新しいコンポーネントは ドットアスタリスクです 登録と送信の際に 動的接尾辞が 識別子に 追加されることを示します
登録と送信に使用される 完全に構成された識別子は このような形になります
ここでは より静的なものを使用します
これを選択した場合 スケジューラは 継続的処理タスクが 実行を求められたとき どのコードを 実行するかを知る必要があります 以前と同じように タスクリクエストの送信後に スケジューラに提供された クロージャが呼び出されます ここで重要な変更があります アプリの起動が完了する前に 起動ハンドラを 登録する必要はありません 代わりに 使用の意思が表明された時点で これらのハンドラを 動的に登録することになります
ジャーナルと同じように ワークロードの進捗状況についての タイムリーな更新の提供は欠かせません その進捗が予想よりも遅い場合 システムは開始者に 作業を続行するかどうかたずねます システムは この 進捗の更新を信頼して 進行中の作業を管理します 結果として 進捗を報告しないタスクは 時間切れになり システムはリソースを回収して 再分配します アプリは 進捗レポートプロトコルを 使用して 更新を 積極的に通知します そうすることで システムは 継続的に監視し UIで進捗状況を表示します さて 引き続き 意識しなければならないのは システムは 状況に応じてタスクを 早期に停止するかもしれない ということです これに対処するために タスクは 停止時間になると呼び出される 時間切れ ハンドラを提供する必要があります そのハンドラを 変数をすばやく 反転するためのチャンスと考えてください タスクを正常に停止でき 余分な作業を回避できます
重要なこととして タスクの作業が完了したら setTaskCompletedを 呼び出す必要があります これにより 完了が システムに通知されます 進捗状況の更新を管理する方法 潜在的な中断に対処する方法 実行中のタスク完了を通知する方法について 説明しました ユーザーが開始した有効なタスクリクエストを 構築して送信することで まとめてみましょう
まず タスクリクエストオブジェクトを 初期化します これには3つの情報が必要です Info.plistのうちの1つに 一致する識別子 ローカライズ済みのタイトルと ローカライズ済みのサブタイトルです これらは システムUIで ユーザーに表示されます
次に システムに遵守させるための 送信戦略を 提供する必要があります デフォルトでは 継続的処理タスクは 発見されてすぐには 実行されません キューの後ろに追加されます さらに何かを指定する必要はありません ただし 場合によっては キューに入ることは 適切なアプローチではありません タスクを今すぐ開始しなければ 意味がない場合はどうでしょうか キューに入る代わりに 今すぐ開始できない場合は 送信が失敗するように システムに指示します これで アプリは すぐにフィードバックが得られ 状況を適切に処理できます
戦略を決定し リクエストを設定したら スケジューラに送信するだけで システムがワークロードを管理します これが継続的処理タスクで作業する時の コアプロセスです タイトルとサブタイトルを提供し 送信戦略を考えることで システムとスムーズに統合し 同意に関する重要な原則を 支持できます このAPIの機能は予想以上です iPadOS 26とiOS 26では 継続的処理タスクは サポート対象のデバイスでの バックグラウンドGPUアクセスの メリットも活用できます
そのためには必ず Xcodeのプロジェクト設定で バックグラウンドGPU機能を 追加してください
追加すると スケジューラの サポートされている リソースプロパティを動的にクエリできます ぜひやってみてください アプリは 現在のデバイスが 何をサポートしているか 実行時に正確に把握でき タスク要件を適切に調整できます この確認は大切です システムはこれらの要件を適用します 利用できないリソースに対する リクエストは送信時に拒否され システムとタスクを 健全で既知の状態に保ちます
最後に システムの優先順位に関する より広いコンテキストに注意してください iOSはフォアグラウンド体験を優先します つまり バックグラウンドタスクへの サービスの品質は アプリがアクティブな時に 比べると低くなります でも システムは賢いので アプリがフォアグラウンドに戻ると タスクの優先順位をインテリジェントに高めて 円滑な機能性と 高い応答性を保証します これらの新しいAPIにより 最もパワフルで シームレスなバックグラウンド 実行機能が実現します 重要なBGContinuedProcessingTaskが ツールキットに追加されます これらのタスクを完全に理解し より広いシステムに適合する方法を知ることで 導入に向けた準備ができます みなさんがツールを活用して よりスマートで効率的な バックグラウンド体験を創造するのを 楽しみにしています ありがとうございました
-
-
8:27 - Register an app refresh task
import BackgroundTasks import SwiftUI @main struct ColorFeed: App { var body: some Scene { WindowGroup { // ... } .backgroundTask(.appRefresh("com.colorfeed.wwdc25.appRefresh")) { await self.handleAppRefreshTask() } } }
-
9:45 - Register a processing task
import BackgroundTasks import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { BGTaskScheduler.shared.register( forTaskWithIdentifier: "com.example.apple-samplecode.ColorFeed.db_cleaning", using: nil ) { task in self.handleAppRefresh(task: task as! BGProcessingTask) } } func submitProcessingTaskRequest() { let request = BGProcessingTaskRequest( identifier: "com.example.apple-samplecode.ColorFeed.db_cleaning" ) request.requiresNetworkConnectivity = true request.requiresExternalPower = true BGTaskScheduler.shared.submit(request)! } }
-
10:51 - Begin and end background task
import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid func saveState() { /* ... */ } func handlePersistence() { let app = UIApplication.shared guard backgroundTaskID != .invalid else { return } backgroundTaskID = app.beginBackgroundTask(withName: "Finish Export") { app.endBackgroundTask(self.backgroundTaskID) self.backgroundTaskID = .invalid } self.saveState() app.endBackgroundTask(backgroundTaskID) backgroundTaskID = .invalid } }
-
14:00 - Continued processing task registration
import BackgroundTasks func handleDialogConfirmation() { BGTaskScheduler.shared.register("com.colorfeed.wwdc25.userTask") { task in let task = task as! BGContinuedProcessingTask var shouldContinue = true task.expirationHandler = { shouldContinue = false } task.progress.totalUnitCount = 100 task.progress.completedUnitCount = 0 while shouldContinue { // Do some work task.progress.completedUnitCount += 1 } task.setTaskCompleted(success: true) } }
-
15:47 - Continued processing task submission
import BackgroundTasks func submitContinuedProcessingTaskRequest() { let request = BGContinuedProcessingTaskRequest( identifier: "com.colorfeed.wwdc25.userTask", title: "A succinct title", subtitle: "A useful and informative subtitle" ) request.strategy = .fail BGTaskScheduler.shared.submit(request)! }
-
-
- 0:00 - ようこそ
Learn how apps can utilize background runtime to perform tasks like prefetching, syncing, and uploading when not in the foreground. This approach enhances user experience by making apps feel faster and more seamless. Also learn about foreground and background states, system principles, and existing APIs, including a new one for continuing foreground tasks.
- 1:22 - イントロダクション
Apps load into memory, become foregrounded, and are the main focus. When someone switches away from an app, it goes to the background, and the system suspends it to save battery and resources. The app can request a brief time to finish tasks. Upon return, it's resumed to the foreground.
- 2:09 - 動作と制約
In iOS, background runtime is tightly managed to prioritize battery life and optimize performance. Background execution is opportunistic and discretionary, with energy being the most fundamental constraint. You need to design your app's background tasks to be efficient, lightweight, and purpose-driven because the system coalesces work and may throttle, suspend, or terminate processes that consume too many resources. Keep background work minimal, defer nonessential tasks until charging, and ensure tasks are atomic and resilient. Apps must be courteous, honoring people's preferences and the system conditions. The system provides transparency to people, allowing them to influence scheduling decisions. Ultimately, the success of background workloads depends on their adaptability and alignment with the system's priorities.
- 7:29 - バックグラウンドタスクに関するAPI
iOS offers various APIs for designing tasks that run in the background. The system optimizes these tasks based on app usage patterns and device constraints. 'BGAppRefreshTask' allows apps to silently fetch content before use, with frequently used apps receiving more frequent scheduling. 'Background Push Notifications' wake the app to fetch new content when the server sends a notification, but these are considered discretionary and low-priority to minimize overhead. 'BGProcessingTask' enables apps to perform more complex work like running ML models or database maintenance. This task needs to be registered during launch, and you can configured it to run only when the device is on a charger and connected to a network. Begin and end background task APIs give apps extra time to complete crucial work, such as saving state or closing connections, when transitioning to the background. These APIs ensure user-initiated operations complete reliably.
- 11:23 - 継続的処理タスク
In iPadOS and iOS 26, there's a new 'BGContinuedProcessingTask' API, which allows apps to perform specific tasks even after being backgrounded. This feature enhance user experience by enabling the app to complete complex tasks without the app needing to be open. For example, the Journal app uses this API to export files in the background. Someone initiates the export with a button tap, and the app then provides progress updates through the system UI. The person can monitor the progress and cancel the task at any time, maintaining complete control. These tasks always need to start with an explicit user action, such as a button tap or gesture. They represent clear and immediate goals, like exporting files, publishing social media content, or completing updates on connected accessories. The system expects these tasks to make measurable progress, and if they don't, they may expire to reclaim resources. You need to register a launch handler to manage state and progress reporting. Provide timely updates about the workload progression using the progress-reporting protocol. If the task's progress is slower than expected, the system prompts the person to decide whether to continue. When the task completes, you need to inform the system by using the 'setTaskCompleted' method. Additionally, the app must handle potential interruptions gracefully by providing an expiration handler. The API also supports background GPU access on supported devices, allowing developers to create more powerful and efficient background experiences. However, iremember that iOS prioritizes the foreground experience, and background tasks may receive a lower quality of service. Nevertheless, the system intelligently boosts the task priority when the app returns to the foreground.