Налаштування моніторингу Watchdog Termination в iOS-додатку

Ваше iOS-додаток закривається без крэш-логу? Користувачі скаржаться, а Crashlytics мовчить. Швидше за все, зіткнулися з **Watchdog Termination** — системний механізм примусово завершує додаток, якщо головний потік зависає довше за поріг (на 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 — системний механізм примусово завершує додаток, якщо головний потік зависає довше за поріг (на iOS 13–15 близько 8 секунд, на iOS 16+ — ~4 секунди). Ми налаштовуємо детектування таких інцидентів, щоб ви отримували повну діагностику та могли усунути причину. За роки роботи ми виявили десятки проектів, де таке примусове завершення залишалися непоміченими, хоча їх частота сягала 2–3% від усіх сесій. Базова вартість налаштування через Sentry стартує від $500, повний аудит з MetricKit та кастомним детектором — від $2000. Економія на техпідтримці досягає $1000 на місяць при зниженні інцидентів на 80–95%, що окупається за 2–3 місяці.

Чому стандартні краш-репортери не бачать Watchdog Termination?

Firebase Crashlytics не реєструє примусове завершення — це не exception і не сигнал. Sentry з версії 8.0 вміє детектувати через прапорці в UserDefaults (увімкніть enableWatchdogTerminationTracking). MetricKit дає точні дані, але із затримкою до доби. Вибір методу залежить від ваших пріоритетів: швидкість vs точність. Apple Documentation: MXHangDiagnostic — це єдине офіційне джерело точного стеку головного потоку в момент зависання.

Метод Швидкість отримання Точність стеку Додаткові витрати
MetricKit до 24 годин Висока (callStackTree) Безкоштовно (вбудовано в iOS)
Sentry хвилини Середня (прапорець+стек main) Підписка на sentry.io
Кастомний детектор реальний час Висока (BSBacktraceLogger) Розробка та підтримка

Як вибрати метод моніторингу?

Якщо вам потрібна максимальна точність для глибокого аналізу — використовуйте MetricKit. Він безкоштовний, але дані приходять із затримкою, що не підходить для оперативного реагування. Якщо важлива швидкість — Sentry дає інформацію за хвилини з достатньою точністю. Коли потрібен моніторинг у реальному часі та низький поріг спрацьовування (2–3 секунди) — пишемо кастомний детектор на основі DispatchQueue.main.async із зворотним зв'язком через BSBacktraceLogger. Sentry у 2 рази швидший за MetricKit за швидкістю отримання даних, але точність стеку нижча через відсутність callStackTree. Кастомний детектор в 1.5 рази точніший за Sentry за стеком і в 2 рази швидше виявляє зависання. Для оперативного реагування Sentry краще за MetricKit у 2 рази за швидкістю.

Як ми налаштовуємо моніторинг: кейс із практики

Наш клієнт із fintech-сектору зіткнувся з масовими примусовими завершеннями після оновлення додатка. Інженери підключили Sentry з порогом appHangTimeoutInterval = 2.5 секунди та виявили, що у 70% випадків зависання відбувалося в методі processTransaction на головному потоці через синхронний запис у 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 знімає стек тільки поточного потоку. Для головного потоку використовуйте BSBacktraceLogger або PLCrashReporter.

Що входить у роботу з налаштування

  • Встановлення та конфігурація MetricKit subscriber для отримання MXHangDiagnostic
  • Підключення Sentry з увімкненим enableWatchdogTerminationTracking та оптимізацією порогу
  • При необхідності — розробка кастомного детектора з низьким порогом (від 2 секунд)
  • Налаштування алертів у Sentry або вашій системі моніторингу на зростання Watchdog Termination Rate
  • Аналіз callStackTree та пошук вузьких місць (синхронні операції на головному потоці)
  • Документування процесу та навчання команди

Типові джерела зависань (і що з ними робити)

Проблема Рішення
Синхронний CoreData fetch у viewDidLoad Вивантажте запит у background context
DispatchSemaphore.wait() без timeout на головному потоці Використовуйте 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) на головному потоці) і перевіряємо, що детектор спрацьовує та надсилає діагностику.
  5. Деплой — викатуємо в реліз через TestFlight, спостерігаємо за першими даними, коригуємо пороги при необхідності.

Строки та вартість

Базова налаштування через Sentry: 4–8 годин, вартість $500. Інтеграція MetricKit з відправкою діагностик на ваш сервер: 1–2 дні, $1000–2000. Повний цикл з кастомним детектором та аналітикою: від 3 днів, $2000–4000. Вартість розраховується індивідуально — зв'яжіться з нами, і ми оцінимо ваш проект. Отримайте консультацію — ми допоможемо знизити частоту примусових завершень та покращити користувацький досвід. Це також допомагає відповідати вимогам App Store Review Guidelines щодо стабільності додатка. Для підвищення iOS продуктивності варто використовувати асинхронні операції, а Swift моніторинг може бути реалізований за допомогою DispatchQueue. Понад 10 років досвіду в iOS-розробці та понад 40 проектів із моніторингом дозволяють нам гарантувати якісне налаштування. Налаштування моніторингу включає встановлення порогів та інтеграцію з Sentry Watchdog tracking та MetricKit для отримання MXHangDiagnostic, що дозволяє відстежувати main thread hang та примусове завершення iOS. Ефективний моніторинг зависань додатка допомагає підвищити стабільність та відповідати вимогам Apple.