From becabb955dc210eaf664d851f860a4dd2e8eab58 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:41:34 +0000 Subject: [PATCH] ios: trace raw core->UI subs payload + actual app state in subs poll Add a second tracing layer to find why the chat-list indicator stays empty while the servers-summary detail view shows 100%: - API.swift sendSimpleXCmd: log the raw bytes the core returns for the "/get subs total" query, before decoding. getAgentSubsTotal is sent with log:false, so nothing currently records its raw response; and decodeAPIResult swallows decode errors (catch {}), so a JSON/shape mismatch would silently produce empty values. This shows what the core actually sends vs the decoded ssActive/ssPending we already log. - ChatListView poll: log the actual AppChatState value (not just the active bool) when a tick is gated out, to see which state it is stuck in in the lock / return-from-background cases. --- apps/ios/Shared/Views/ChatList/ChatListView.swift | 5 +++-- apps/ios/SimpleXChat/API.swift | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 984dc64892..cc74d9657b 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -605,7 +605,8 @@ struct SubsStatusIndicator: View { task = Task { logger.debug("SUBS_TRACE poll loop: started") while !Task.isCancelled { - let appActive = AppChatState.shared.value == .active + let appState = AppChatState.shared.value + let appActive = appState == .active let running = ChatModel.shared.chatRunning == true if appActive, running { do { @@ -620,7 +621,7 @@ struct SubsStatusIndicator: View { logger.error("getSubsTotal error: \(responseError(error))") } } else { - logger.debug("SUBS_TRACE poll skipped tick: appActive=\(appActive) chatRunning=\(running) (gated out, not fetching)") + logger.debug("SUBS_TRACE poll skipped tick: appState=\(appState.rawValue) appActive=\(appActive) chatRunning=\(running) (gated out, not fetching)") } try? await Task.sleep(nanoseconds: 1_000_000_000) // Sleep for 1 second } diff --git a/apps/ios/SimpleXChat/API.swift b/apps/ios/SimpleXChat/API.swift index 6bf46fb0dd..0b281f6850 100644 --- a/apps/ios/SimpleXChat/API.swift +++ b/apps/ios/SimpleXChat/API.swift @@ -114,9 +114,17 @@ public func resetChatCtrl() { @inline(__always) public func sendSimpleXCmd(_ cmd: ChatCmdProtocol, _ ctrl: chat_ctrl? = nil, retryNum: Int32 = 0) -> APIResult { if let d = sendSimpleXCmdStr(cmd.cmdString, ctrl, retryNum: retryNum) { - decodeAPIResult(d) + // SUBS_TRACE: log the exact bytes the core sends back for the subs-total query, + // before any decoding — this is what the UI actually receives from the core. + if cmd.cmdString.hasPrefix("/get subs total") { + logger.debug("SUBS_TRACE raw core->UI for '\(cmd.cmdString)': \(dataToString(d))") + } + return decodeAPIResult(d) } else { - APIResult.error(.invalidJSON(json: nil)) + if cmd.cmdString.hasPrefix("/get subs total") { + logger.debug("SUBS_TRACE raw core->UI for '\(cmd.cmdString)': nil (core returned no data)") + } + return APIResult.error(.invalidJSON(json: nil)) } }