Фоновые задачи и обновление
Планируйте работу в фоне с помощью BGTaskScheduler.
«Фоновые задачи и обновление» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Зачем нужны Background Tasks
iOS активно приостанавливает приложения для экономии заряда. Чтобы выполнять полезную работу в фоне — обновлять ленту или обрабатывать загрузку, — запланируйте её через BGTaskScheduler. Система сама решает, когда её запустить, сопоставляя ваши потребности с расходом энергии и особенностями использования устройства.
import BackgroundTasks
// You request work; the system schedules it later
// at an opportune moment (charging, on Wi-Fi, etc.)Два типа задач
Существует два типа задач: BGAppRefreshTask для коротких частых обновлений продолжительностью в несколько секунд и BGProcessingTask для более длительной и ресурсоёмкой работы продолжительностью в несколько минут, например обслуживания базы данных, при необходимости с требованием питания или сети.
import BackgroundTasks
// BGAppRefreshTask -> quick content refresh
// BGProcessingTask -> long maintenance, can require
// external power / networkОбъявление идентификаторов
Для каждой задачи нужен уникальный идентификатор, который следует указать в Info.plist в разделе BGTaskSchedulerPermittedIdentifiers. Без этого объявления регистрация завершается ошибкой. Используйте строки в формате обратной записи DNS.
// Info.plist:
// BGTaskSchedulerPermittedIdentifiers = [
// "com.example.app.refresh",
// "com.example.app.cleanup"
// ]
let ids = "declare every identifier in Info.plist"
_ = idsРегистрация обработчика
При запуске зарегистрируйте обработчик для каждого идентификатора с помощью BGTaskScheduler.shared.register. Это необходимо сделать до завершения запуска приложения. Впоследствии обработчик будет выполняться всякий раз, когда система решит запустить задачу.
import BackgroundTasks
func registerTasks() {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.app.refresh",
using: nil) { task in
handleRefresh(task as! BGAppRefreshTask)
}
}Отправка запроса
Регистрация только подключает обработчик. Чтобы действительно запросить запуск, создайте BGAppRefreshTaskRequest, задайте самую раннюю дату начала и вызовите submit. Система воспринимает эту дату как подсказку, а не как гарантию.
import BackgroundTasks
func scheduleRefresh() {
let request = BGAppRefreshTaskRequest(
identifier: "com.example.app.refresh")
request.earliestBeginDate = Date(
timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
}Всегда планируйте следующий запуск
Отправленный запрос выполняется не более одного раза. Чтобы обновления продолжались, обработчик должен отправить следующий запрос до завершения текущего. Сначала запланируйте следующий запуск, а затем выполняйте работу: так сбой во время работы не остановит цикл.
import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
scheduleRefresh() // queue the next run first
// ... then perform this run's work
}Сигнал о завершении
После завершения необходимо вызвать task.setTaskCompleted(success:). Если забыть об этом, будет напрасно потрачен фоновый ресурс, а приоритет будущих задач может снизиться. Передайте сведения об успешности работы, чтобы система могла скорректировать расписание.
import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
scheduleRefresh()
Task {
let ok = await fetchLatest()
task.setTaskCompleted(success: ok)
}
}
func fetchLatest() async -> Bool { true }Обработка обработчика истечения времени
Система может досрочно отобрать время выполнения. Задайте task.expirationHandler, чтобы отменить текущую работу и выполнить очистку; тогда приложение корректно завершит её при принудительном сокращении времени. Воспринимайте этот обработчик как сигнал о приближении крайнего срока.
import BackgroundTasks
func handle(_ task: BGAppRefreshTask) {
let work = Task { await fetchLatest() }
task.expirationHandler = {
work.cancel() // stop before the OS suspends us
}
}
func fetchLatest() async -> Bool { true }Задачи обработки с требованиями
Для ресурсоёмкой работы BGProcessingTaskRequest позволяет задать requiresNetworkConnectivity и requiresExternalPower. Система дождётся выполнения этих условий, поэтому длительные задачи смогут работать ночью, когда устройство заряжается и подключено к Wi-Fi.
import BackgroundTasks
func scheduleCleanup() {
let req = BGProcessingTaskRequest(
identifier: "com.example.app.cleanup")
req.requiresExternalPower = true
req.requiresNetworkConnectivity = false
try? BGTaskScheduler.shared.submit(req)
}Тестирование в отладчике
Вам не придётся ждать часами, пока система запланирует задачу. Приостановите выполнение в отладчике и выполните команду LLDB, чтобы немедленно запустить зарегистрированную задачу и проверить обработчик от начала до конца.
// In LLDB while paused:
// e -l objc -- (void)[[BGTaskScheduler sharedScheduler]
// _simulateLaunchForTaskWithIdentifier:
// @"com.example.app.refresh"]
let test = "force-launch task via LLDB"
_ = testПолный цикл обновления
Объединим всё: зарегистрируйте задачу при запуске, отправьте запрос при переходе в фон, а в обработчике запланируйте следующий запуск, установите обработчик истечения времени, выполните асинхронную работу и сообщите о завершении.
import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
scheduleRefresh()
let work = Task { await fetchLatest() }
task.expirationHandler = { work.cancel() }
Task {
let ok = await work.value
task.setTaskCompleted(success: ok)
}
}
func fetchLatest() async -> Bool { true }Быстрая проверка
Вспомните жизненный цикл повторяющейся задачи обновления.
Повторение
Вы изучили планирование фоновых задач:
BGAppRefreshTaskпредназначен для коротких обновлений, аBGProcessingTask— для длительного обслуживания с требованиями к питанию или сети.- Объявляйте идентификаторы в
Info.plist, регистрируйте обработчики при запуске с помощьюregisterи отправляйте запросы черезsubmit, указываяearliestBeginDate. - Планируйте следующий запуск внутри обработчика, задавайте
expirationHandlerи всегда вызывайтеsetTaskCompleted. - Принудительно запускайте задачи через LLDB, чтобы выполнить test.
Изучай Swift с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 122
- Уроки
- 409
Часто задаваемые вопросы
Урок «Фоновые задачи и обновление» бесплатный?
Да — полный текст урока «Фоновые задачи и обновление» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Фоновые задачи и обновление»?
Планируйте работу в фоне с помощью BGTaskScheduler. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Фоновые задачи и обновление»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Регистрация для push-уведомлений
- Обработка полезных данных уведомлений
- Фоновые задачи и обновление
- Действия и категории уведомлений