From 6dec6a60ecdb1fde472080b173b9bfc394ccbfe1 Mon Sep 17 00:00:00 2001 From: Eliot Andres Date: Sat, 17 Oct 2026 14:35:10 +0200 Subject: [PATCH] Fix launch crash when MetricKit delivers a diagnostic (#16) DebugLog.write is called from any thread, but its relay assumed the main actor. MetricKit delivers payloads on a background queue, so CrashReports.didReceive trapped in MainActor.assumeIsolated on launch, and every crash queued another payload for the next launch. Claude-Session: https://claude.ai/code/session_01KN6Wd5bdgWERis2b4x9Rm3 Co-authored-by: Claude Opus 5.5 --- ios/IPhoneAgent/App/AppModel.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/IPhoneAgent/App/AppModel.swift b/ios/IPhoneAgent/App/AppModel.swift index c4a26e6..7aa8a8b 100644 --- a/ios/IPhoneAgent/App/AppModel.swift +++ b/ios/IPhoneAgent/App/AppModel.swift @@ -92,7 +92,9 @@ import UIKit pointer.screenAspect = { DeviceScreen.aspect } pointer.locate = { [weak self] jpeg in await self?.locatePointer(jpeg) } DebugLog.relay = { [weak self] line in - MainActor.assumeIsolated { if !MockMode.on { self?.board.commands.relayLog(line) } } + // DebugLog.write runs on any thread (MetricKit delivers crash reports on a background queue). + let relay = { MainActor.assumeIsolated { if !MockMode.on { self?.board.commands.relayLog(line) } } } + Thread.isMainThread ? relay() : DispatchQueue.main.async(execute: relay) } board.commands.onAppCommand = { [weak self] line in self?.handleAppCommand(line) } DebugLog.write("app launched \(Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "")"