Как в iOS реализовать выполнение задачи приложением в фоновом режиме?

«Как в iOS реализовать выполнение задачи приложением в фоновом режиме?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В iOS для фонового выполнения используются Background Modes и API beginBackgroundTask. Почему это важно: Система приостанавливает приложение в фоне для экономии заряда, поэтому для завершения критичных операций (например, сохранения данных или завершения сетевого запроса) требуется явно запросить дополнительное время.

Пример: Завершение сетевого запроса при уходе в фон

  1. Объявите capability в Xcode (например, Background fetch) или добавьте ключ в Info.plist для специальных режимов (аудио, локация, VOIP).
  2. Запросите фоновое время в AppDelegate или SceneDelegate:
func applicationDidEnterBackground(_ application: UIApplication) {
    // Объявляем идентификатор фоновой задачи
    var backgroundTask: UIBackgroundTaskIdentifier = .invalid

    // Запрашиваем у системы дополнительное время
    backgroundTask = application.beginBackgroundTask(withName: "Finish Network Call") {
        // Этот блок выполнится, если время истечёт. Нужно завершить операцию и очистить ресурсы.
        application.endBackgroundTask(backgroundTask)
        backgroundTask = .invalid
    }

    // Запускаем асинхронную операцию, которую нужно завершить
    DispatchQueue.global().async {
        // Выполняем долгую операцию (например, отправку логов на сервер)
        self.sendLogsToServer()

        // По завершении ОБЯЗАТЕЛЬНО сообщаем системе
        application.endBackgroundTask(backgroundTask)
        backgroundTask = .invalid
    }
}

Ключевые моменты:

  • Лимит времени: Обычно ~30 секунд. Точное время доступно через application.backgroundTimeRemaining.
  • Обязательная очистка: Всегда вызывайте endBackgroundTask, иначе приложение будет убито системой.
  • Для периодических задач (iOS 13+) используйте BackgroundTasks.framework для BGAppRefreshTask или BGProcessingTask.