Watchdog Termination Monitoring Setup for iOS App

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Watchdog Termination Monitoring Setup for iOS App
Medium
from 4 hours to 2 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Setting Up Watchdog Termination Monitoring for iOS Apps

Watchdog is an iOS system mechanism that forcibly terminates an app if it stops responding for too long. Unlike a normal crash, this is not an exception or signal. MetricKit calls such terminations MXHangDiagnostic, and ProcessInfo.processInfo.reason contains no trace — just the fact of termination.

Starting with iOS 13, Watchdog activates when the main thread hangs for > 8 seconds in foreground. On iOS 16+, the threshold dropped to ~4 seconds in some scenarios. Users simply see the app close without dialogs.

Why This is Hard to Monitor

Firebase Crashlytics does not register Watchdog Terminations — they don't pass through NSSetUncaughtExceptionHandler and don't generate a signal. Crashlytics only sees standard crashes.

Sentry from version 8.0 can detect Watchdog via SentryWatchdogTerminationTracker, but only if the SDK lived in memory before termination — on cold start after Watchdog, Sentry sees it through flags in UserDefaults.

Apple's MetricKit provides accurate data, but with delay: diagnostic payloads arrive once daily.

Detection via MetricKit

import MetricKit

class MetricsManager: NSObject, MXMetricManagerSubscriber {
    func didReceive(_ payloads: [MXMetricPayload]) {
        // Performance metrics
    }

    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        for payload in payloads {
            if let hangs = payload.hangDiagnostics, !hangs.isEmpty {
                hangs.forEach { hang in
                    // hang.callStackTree — call stack tree at hang moment
                    reportHangToServer(hang)
                }
            }
        }
    }
}

// Registration
MXMetricManager.shared.add(MetricsManager())

MXHangDiagnostic.callStackTree contains the symbolicated (if dSYM available) main thread stack at the hang moment. This is the only way to know exactly which method hung.

Custom Watchdog Detector

If waiting for MetricKit isn't possible, build a detector manually:

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() // schedule next ping
        }
    }

    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 {
                // Record main thread hang
                self.captureHang(duration: elapsed)
            }
            self.scheduleBackgroundCheck()
        }
    }

    private func captureHang(duration: TimeInterval) {
        // Thread.callStackSymbols — only current thread
        // For main thread: use BSBacktraceLogger or PLCrashReporter
        SentrySDK.capture(error: NSError(
            domain: "WatchdogHang",
            code: Int(duration * 1000),
            userInfo: [NSLocalizedDescriptionKey: "Main thread hung for \(duration)s"]
        ))
    }
}

Caution: Thread.callStackSymbols captures the stack of the current thread (background), not main. To capture another thread's stack, use BSBacktraceLogger (third-party library) or PLCrashReporter.

Sentry Watchdog Tracking

SentrySDK.start { options in
    options.dsn = "https://[email protected]/project"
    options.enableWatchdogTerminationTracking = true
    options.appHangTimeoutInterval = 3.0 // App Hang threshold in seconds
}

Sentry stores a sentryWatchdogTermination flag in UserDefaults on every startup. If the flag is set on next launch and the last termination wasn't clean — a Watchdog Termination is recorded. Not perfectly accurate (false positives from force-kill via Xcode), but works in production.

Typical Watchdog Termination Sources

  • Synchronous CoreData fetch in viewDidLoad on the main thread
  • DispatchSemaphore.wait() or DispatchGroup.wait() without timeout on main thread
  • Deadlock between @MainActor and synchronous Swift Concurrency code
  • Heavy JSON decode in URLSession.dataTask completion without dispatch to background queue

What We Do

  • Enable MetricKit subscriber to receive MXHangDiagnostic
  • Connect Sentry enableWatchdogTerminationTracking for real-time detection
  • When needed, implement custom Watchdog detector for lower threshold
  • Set up alerts for Watchdog Termination Rate growth
  • Analyze callStackTree to identify specific culprits

Timeline

Basic setup via Sentry: 4–8 hours. MetricKit integration with diagnostic delivery: 1–2 days. Pricing is calculated individually.