Ответ
По умолчанию Timer останавливается, когда приложение переходит в фоновый режим. Это происходит потому, что:
- Timer привязан к RunLoop
- RunLoop основного потока останавливается в фоне
- Энергосбережение iOS приостанавливает выполнение
Решение для продолжения работы в фоне:
-
Добавление Timer в режим
.common:let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in print("Тик") } RunLoop.current.add(timer, forMode: .common) -
Использование фоновых задач (ограничено по времени):
// В Info.plist добавьте фоновый режим BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.app.refresh", using: nil) { task in // Выполните работу task.setTaskCompleted(success: true) } -
Альтернативные подходы:
- Сравнение дат: При возврате в активное состояние сравнивайте
Date()с сохранённым временем - Локальные уведомления: Используйте
UNUserNotificationCenterдля напоминаний - Серверные пуши: Для точного времени используйте remote notifications
- Сравнение дат: При возврате в активное состояние сравнивайте
Важные ограничения:
- Фоновое выполнение ограничено ~30 секундами (для
beginBackgroundTask) - Apple строго контролирует фоновую активность
- Для периодических задач используйте Background Fetch или Push Notifications
Проверка состояния:
NotificationCenter.default.addObserver(
forName: UIApplication.didEnterBackgroundNotification,
object: nil,
queue: .main
) { _ in
print("Приложение ушло в фон, Timer может остановиться")
}