Swift Academy · Урок

Фоновые задачи и обновление

Планируйте работу в фоне с помощью BGTaskScheduler.

Урок 3 из 413 шагов

«Фоновые задачи и обновление» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Регистрация для push-уведомлений
  2. Обработка полезных данных уведомлений
  3. Фоновые задачи и обновление
  4. Действия и категории уведомлений
← Назад к Swift Academy