Настройка мониторинга Watchdog Termination в iOS-приложении

Ваше iOS-приложение закрывается без крэш-лога? Пользователи жалуются, а Crashlytics молчит. Скорее всего, столкнулись с **Watchdog Termination** — системный механизм принудительно завершает приложение, если main thread зависает дольше порога (на iOS 13–15 около 8 секунд, на iOS 16+ — ~4 секунды). Мы

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Настройка мониторинга Watchdog Termination в iOS-приложении
Средний
от 4 часов до 2 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Ваше 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

Процесс работы

  1. Аналитика — изучаем текущую архитектуру, версии iOS, типичные сценарии. Собираем метрики через MetricKit (если уже используется).
  2. Проектирование — выбираем оптимальный стек: MetricKit + Sentry / только Sentry / кастом + Sentry. Определяем пороги срабатывания.
  3. Реализация — пишем и подключаем код, тестируем на симуляторе и реальных устройствах с разными версиями iOS.
  4. Тестирование — симулируем зависания (например, через sleep(10) на main thread) и проверяем, что детектор срабатывает и отправляет диагностику.
  5. Деплой — выкатываем в релиз через TestFlight, наблюдаем за первыми данными, корректируем пороги при необходимости.

Сроки и стоимость

Базовая настройка через Sentry: 4–8 часов. Интеграция MetricKit с отправкой диагностик на ваш сервер: 1–2 дня. Полный цикл с кастомным детектором и аналитикой: от 3 дней. Стоимость рассчитывается индивидуально — свяжитесь с нами, и мы оценим ваш проект. Получите консультацию — мы поможем снизить частоту Watchdog Termination и улучшить пользовательский опыт. Более 5 лет опыта в iOS-разработке и более 50 проектов с мониторингом позволяют нам гарантировать качественную настройку.