Что происходит с Timer в iOS при сворачивании приложения?

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

Ответ

По умолчанию Timer останавливается, когда приложение переходит в фоновый режим. Это происходит потому, что:

  • Timer привязан к RunLoop
  • RunLoop основного потока останавливается в фоне
  • Энергосбережение iOS приостанавливает выполнение

Решение для продолжения работы в фоне:

  1. Добавление Timer в режим .common:

    let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
    print("Тик")
    }
    RunLoop.current.add(timer, forMode: .common)
  2. Использование фоновых задач (ограничено по времени):

    // В Info.plist добавьте фоновый режим
    BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.app.refresh", 
                               using: nil) { task in
    // Выполните работу
    task.setTaskCompleted(success: true)
    }
  3. Альтернативные подходы:

    • Сравнение дат: При возврате в активное состояние сравнивайте Date() с сохранённым временем
    • Локальные уведомления: Используйте UNUserNotificationCenter для напоминаний
    • Серверные пуши: Для точного времени используйте remote notifications

Важные ограничения:

  • Фоновое выполнение ограничено ~30 секундами (для beginBackgroundTask)
  • Apple строго контролирует фоновую активность
  • Для периодических задач используйте Background Fetch или Push Notifications

Проверка состояния:

NotificationCenter.default.addObserver(
    forName: UIApplication.didEnterBackgroundNotification,
    object: nil,
    queue: .main
) { _ in
    print("Приложение ушло в фон, Timer может остановиться")
}