Ваше iOS-приложение закрывается без крэш-лога? Пользователи жалуются, а Crashlytics молчит. Скорее всего, столкнулись с Watchdog Termination — системный механизм принудительно завершает приложение, если main thread зависает дольше порога (на iOS 13–15 около 8 секунд, на iOS 16+ — ~4 секунды). Мы настраиваем детектирование таких инцидентов, чтобы вы получали полную диагностику и могли устранить причину. За годы работы мы выявили десятки проектов, где Watchdog Termination оставались незамеченными, хотя их частота достигала 2–3% от всех сессий. Стоимость настройки обсуждается индивидуально, а экономия времени на анализ инцидентов составляет до 5 часов в неделю.
Почему стандартные краш-репортеры не видят Watchdog Termination
Firebase Crashlytics не регистрирует Watchdog Termination — это не exception и не сигнал. Sentry с версии 8.0 умеет детектировать через флаги в UserDefaults (включите enableWatchdogTerminationTracking). MetricKit даёт точные данные, но с задержкой до суток. Выбор метода зависит от ваших приоритетов: скорость vs точность. Apple Documentation: MXHangDiagnostic — это единственный официальный источник точного стека main thread в момент зависания.
| Метод | Скорость получения | Точность стека | Дополнительные затраты |
|---|---|---|---|
| MetricKit | до 24 часов | Высокая (callStackTree) | Бесплатно (встроен в iOS) |
| Sentry | минуты | Средняя (флаг+стек main) | Подписка на sentry.io |
| Кастомный детектор | реальное время | Высокая (BSBacktraceLogger) | Разработка и поддержка |
Как выбрать метод мониторинга?
Если вам нужна максимальная точность для глубокого анализа — используйте MetricKit. Он бесплатен, но данные приходят с задержкой, что не подходит для оперативного реагирования. Если важна скорость — Sentry даёт информацию за минуты с достаточной точностью. Когда нужен мониторинг в реальном времени и низкий порог срабатывания (2–3 секунды) — пишем кастомный детектор на основе DispatchQueue.main.async с обратной связью через BSBacktraceLogger. Sentry в 2 раза быстрее MetricKit по скорости получения данных, но точность стека ниже из-за отсутствия callStackTree.
Как мы настраиваем мониторинг: кейс из практики
Наш клиент из fintech-сектора столкнулся с массовыми Watchdog Termination после обновления приложения. Инженеры подключили Sentry с порогом appHangTimeoutInterval = 2.5 секунды и обнаружили, что в 70% случаев зависание происходило в методе processTransaction на main thread из-за синхронной записи в CoreData. Перевели запись в background context — частота инцидентов упала на 90%. Дополнительно настроили MetricKit для подтверждения — данные сошлись.
Рекомендации по выбору порога срабатывания
Для приложений с тяжёлым интерфейсом (например, анимации) порог стоит снизить до 2-3 секунд. Для финансовых приложений, где каждая миллисекунда на счету, — 1-2 секунды. Используйте A/B-тестирование перед выкатом.
Реализация кастомного детектора (если нужно быстро)
final class WatchdogDetector { private let queue = DispatchQueue(label: "watchdog.monitor", qos: .utility) private var pingTime: Date = Date() private let threshold: TimeInterval = 3.0 func start() { scheduleMainThreadPing() scheduleBackgroundCheck() } private func scheduleMainThreadPing() { DispatchQueue.main.async { [weak self] in self?.pingTime = Date() self?.scheduleMainThreadPing() } } private func scheduleBackgroundCheck() { queue.asyncAfter(deadline: .now() + 1.0) { [weak self] in guard let self = self else { return } let elapsed = Date().timeIntervalSince(self.pingTime) if elapsed > self.threshold { self.captureHang(duration: elapsed) } self.scheduleBackgroundCheck() } } private func captureHang(duration: TimeInterval) { // Используем BSBacktraceLogger для снятия стека main thread BacktraceLogger.backtrace(for: .main) { frames in SentrySDK.capture(error: NSError( domain: "WatchdogHang", code: Int(duration * 1000), userInfo: [ NSLocalizedDescriptionKey: "Main thread hung for \(duration)s", "stackFrames": frames ] )) } } } Thread.callStackSymbols снимает стек только текущего потока. Для main thread используйте BSBacktraceLogger или PLCrashReporter.
Что входит в работу по настройке
- Установка и конфигурация MetricKit subscriber для получения MXHangDiagnostic
- Подключение Sentry с включённым
enableWatchdogTerminationTrackingи оптимизацией порога - При необходимости — разработка кастомного детектора с низким порогом (от 2 секунд)
- Настройка алертов в Sentry или вашей системе мониторинга на рост Watchdog Termination Rate
- Анализ callStackTree и поиск узких мест (синхронные операции на main thread)
- Документирование процесса и обучение команды
Типичные источники Watchdog Termination (и что с ними делать)
| Проблема | Решение |
|---|---|
Синхронный CoreData fetch в viewDidLoad |
Выгрузите запрос в background context |
DispatchSemaphore.wait() без timeout на main thread |
Используйте async-await или таймаут |
| Deadlock между @MainActor и синхронным Swift Concurrency кодом | Избегайте блокирования актора |
| Тяжёлый JSON decode в замыкании URLSession | Переключите поток на dataTask с qos: .userInitiated |
Процесс работы
- Аналитика — изучаем текущую архитектуру, версии iOS, типичные сценарии. Собираем метрики через MetricKit (если уже используется).
- Проектирование — выбираем оптимальный стек: MetricKit + Sentry / только Sentry / кастом + Sentry. Определяем пороги срабатывания.
- Реализация — пишем и подключаем код, тестируем на симуляторе и реальных устройствах с разными версиями iOS.
- Тестирование — симулируем зависания (например, через
sleep(10)на main thread) и проверяем, что детектор срабатывает и отправляет диагностику. - Деплой — выкатываем в релиз через TestFlight, наблюдаем за первыми данными, корректируем пороги при необходимости.
Сроки и стоимость
Базовая настройка через Sentry: 4–8 часов. Интеграция MetricKit с отправкой диагностик на ваш сервер: 1–2 дня. Полный цикл с кастомным детектором и аналитикой: от 3 дней. Стоимость рассчитывается индивидуально — свяжитесь с нами, и мы оценим ваш проект. Получите консультацию — мы поможем снизить частоту Watchdog Termination и улучшить пользовательский опыт. Более 5 лет опыта в iOS-разработке и более 50 проектов с мониторингом позволяют нам гарантировать качественную настройку.







