Background Fetch は、新しいコンテンツをダウンロードするためにバックグラウンドで定期的にアプリを起動するiOSのメカニズムです。システムはユーザーの行動を分析し、最適な更新ウィンドウを選択します。Apple、2026年によると、アプリは操作を実行するために30〜120秒与えられ、その後システムはプロセスを中断または終了します。
主なポイント
Background Fetch は、アプリがバックグラウンドで定期的に新しいデータを受信できるようにするiOS APIです。iOS 7でBackground App Refreshメカニズムとともに初めて導入されました。主な目的は、ユーザーがアプリを開いたときにコンテンツが最新であり、読み込みを待つ必要がないようにすることです。
プッシュ通知 はサーバーによって開始されます。サーバーがデバイスに信号を送信し、システムがアプリを起動するかどうかを決定します。Background Fetchはデバイスの使用パターンに基づいてiOS自体によって開始されます。プッシュは緊急メッセージに適しており、Fetchは定期的なコンテンツ更新(ニュース、ソーシャルメディアフィード)に適しています。
Background Fetchは、iOSにおけるいくつかのバックグラウンド実行メカニズムの1つです。BGAppRefreshTask(iOS 13以降)は同じタスクを実行しますが、より柔軟なスケジューリングを提供します。Background Modes(オーディオ、位置情報)は継続的な操作のためのものです。Silent Pushはサーバー開始の更新です。FetchはiOS 12以前をサポートするプロジェクトに関連性があります。
iOS は機械学習アルゴリズムを使用して、アプリを起動する最適なタイミングを決定します。システムは、ユーザーが通常いつアプリを開くか、どのくらいの時間使用するか、どのくらいの頻度で戻ってくるかを分析します。このデータに基づいて、iOSはBackground Fetchのウィンドウを計算します。
システムがアプリを起動することを決定すると、AppDelegateのapplication(_:performFetchWithCompletionHandler:)メソッドを呼び出します。アプリは最小限の新しいデータを読み込み、3つのステータスのいずれかで完了ハンドラを呼び出す必要があります:.newData(データ読み込み完了)、.noData(新しいデータなし)、.failed(エラー)。ステータスは将来の起動頻度に影響します。
.newData ステータスはシステムに更新が有用だったことを伝えます。iOSは起動頻度を増やす可能性があります。.noDataはデータがないことを示します。頻度は同じままか減少します。.failedは問題を示します。システムはバッテリーを節約するために頻度を減らします。重要なのは誠実なステータスであり、.newDataを強制することではありません。
| ステータス | 意味 | 影響 |
|---|---|---|
| .newData | データが正常に読み込まれた | 頻度が増える可能性あり |
| .noData | チェックで新しいデータなし | 頻度は変わらない |
| .failed | ネットワークまたはサーバーエラー | 頻度が減る |
Background Fetch を有効にするには、2つのステップが必要です:Xcodeでケイパビリティをアクティブにし、コードで最小間隔を設定します。ケイパビリティはTarget — Signing & Capabilities — Background Modes — Background Fetchチェックボックスにあります。このステップがないと、システムはアプリを起動しません。
UIApplication.shared.setMinimumBackgroundFetchInterval メソッドは、Fetch呼び出しの間の最小時間を秒単位で設定します。値UIApplication.backgroundFetchIntervalMinimum(約15分)は、エネルギー効率が良い範囲で可能な限り頻繁にアプリを起動するようシステムに指示します。application(_:didFinishLaunchingWithOptions:)で間隔を設定するのが標準的な方法です。
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
return true
}
XcodeでBackground Fetchを有効にすると、自動的にInfo.plistが更新され、UIBackgroundModesキーに値fetchが追加されます。これは必須のステップです。これがないと、アプリはperformFetchWithCompletionHandler呼び出しを受信しません。P list SourceまたはBuild Settingsで確認できます。
ニュースアプリ向けの完全なBackground Fetch実装を見てみましょう。実装にはデータの読み込み、キャッシュ、完了ハンドラの呼び出しが含まれます。コードはAppDelegateで実行されます。システムがfetchを呼び出す唯一の場所です。
func application(
_ application: UIApplication,
performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
let url = URL(string: "https://api.example.com/latest")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
handler(.failed)
return
}
do {
let articles = try JSONDecoder().decode([Article].self, from: data)
cacheArticles(articles)
handler(articles.isEmpty ? .noData : .newData)
} catch {
handler(.failed)
}
}.resume()
}
Background Fetch でデータを読み込んだ後、ローカルストレージ(CoreData、UserDefaults、File Manager)に保存する必要があります。アプリを開くときにはデータが既に利用可能になっている必要があります。スレッドセーフな書き込みのために、バックグラウンドコンテキストでCoreDataを使用してください。保存後、メインスレッドでUIを更新します。
func cacheArticles(_ articles: [Article]) {
let container = NSPersistentContainer(name: "AppModel")
container.performBackgroundTask { context in
articles.forEach { article in
let entity = ArticleEntity(context: context)
entity.id = Int64(article.id)
entity.title = article.title
entity.body = article.body
}
try? context.save()
}
}
テストにはシミュレータを使用します。XcodeでDebug — Simulate Background Fetchを選択します。物理デバイスでは、システムがfetchを実行することを決定するまで待つ必要があります。高速化するには最小間隔を1分に設定できますが、バッテリー残量が少ないとシステムはこれを無視する可能性があります。
Background Fetch には、アプリのアーキテクチャを設計する際に考慮すべきいくつかの制限があります。主なものは、システムが呼び出し頻度を完全に制御しており、開発者がそれを保証できないことです。最小間隔を設定しても、システムが何時間もfetchを呼び出さないことがあります。
システムはタスクの実行にアプリに限られた時間(通常最大30秒)を割り当てます。アプリがその時間内に完了ハンドラを呼び出さない場合、システムは強制的にプロセスを終了し、将来の起動頻度を減らします。すべてのネットワークリクエストはコンパクトにし、1回の呼び出しで1〜2回までにしてください。
iOSはBackground Fetchをスケジュールする際にバッテリーレベルを考慮します。充電が20%未満の場合、起動頻度が低下します。低電力モードが有効な場合、システムはすべてのアプリのバックグラウンド更新を完全に無効にする可能性があります。ユーザーは設定で特定のアプリのBackground App Refreshを無効にすることもできます。
Background Fetchから開始されたURLSessionは、バックグラウンドセッションをサポートせずに標準モードで動作します。大きなダウンロードには、バックグラウンド設定のURLSessionを使用してください。システムはfetchの完了後もダウンロードを続行しますが、次の起動まで進行状況は追跡されません。
iOS 13以降、AppleはBGTaskSchedulerをBackground Fetchの代替として推奨しています。BGTaskSchedulerはより柔軟なスケジューリング、2種類のタスク(リフレッシュと処理)、および識別子によるタスク登録を提供します。移行にはいくつかのステップが含まれ、すべての新しいプロジェクトに推奨されます。
最初のステップは、BGTaskSchedulerPermittedIdentifiersキーを使用してInfo.plistでタスク識別子を定義することです。2番目は、BGTaskScheduler.shared.registerを介してAppDelegateでタスクを登録することです。3番目は、performFetchWithCompletionHandler呼び出しをregisterに渡されたハンドラに置き換えることです。4番目は、タスクをスケジュールするためにsubmitを呼び出すことです。
// 移行前(Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
// 移行後(BGTaskScheduler)
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
let request = BGAppRefreshTaskRequest(
identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
BGTaskSchedulerはより多くの制御を提供します:長時間の操作のためのBGProcessingTask(最大10分)、requiresNetworkConnectivityとrequiresExternalPowerによる実行条件、および正常終了のためのexpirationハンドラ。システムはアプリの使用状況も分析しますが、開発者はより正確な要件を設定できます。
アプリがiOS 12以前をサポートしている場合、Background Fetchが定期的な更新のための唯一のオプションです。BGTaskSchedulerはiOS 13以降でのみ利用可能です。この場合、ラッパーを使用して、if #available(iOS 13, *)で可用性を確認し、適切なAPIを呼び出します。
よくある質問
正確な頻度は文書化されておらず、ユーザーの行動に依存します。システムはユーザーがアプリを開く頻度を分析し、それに応じて頻度を調整します。平均的に、アクティブな使用では、fetchは1時間に1〜3回呼び出される可能性があります。使用頻度が低い場合は、1日1〜2回です。
3つの条件を確認してください:Background FetchケイパビリティがXcodeで有効になっている、minimumBackgroundFetchIntervalが設定されている、ユーザーが設定でアプリのBackground App Refreshを無効にしていない。また、デバイスが低電力モードでなく、バッテリーレベルが20%以上であることを確認してください。
Background Fetch は古いAPI(iOS 7)、BGAppRefreshTaskは新しいAPI(iOS 13以降)です。BGAppRefreshTaskはより多くの制御(expirationハンドラ、再スケジュール機能、ステータスチェック)を提供します。Background Fetchは実装が簡単ですが、柔軟性に欠けます。Appleは新しいプロジェクトにはBGAppRefreshTaskの使用を推奨しています。
推奨されません。Background Fetch は時間制限があります(最大30秒)。大きなダウンロードには、バックグラウンド設定のURLSessionを使用してください。システムはfetch完了後もダウンロードを続行します。代替案としてBGProcessingTask(iOS 13以降)があり、最大10分と充電条件を許可します。
はい、各起動はプロセッサの起動、ネットワークスタックの初期化、データの読み込みにエネルギーを消費します。iOSは影響を最小限に抑えるために頻度を最適化します。適切な実装(新しいデータのみの読み込み、迅速な完了ハンドラの呼び出し)により、バッテリーへの影響は最小限です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。