From a1332ed942ca47c04b9dd6ad406ab5b9d48e5dea Mon Sep 17 00:00:00 2001 From: joywayer Date: Wed, 24 Jun 2026 09:07:36 +0800 Subject: [PATCH] =?UTF-8?q?4.B=20FriendsShareHandler=20=E5=8A=A0=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=97=A5=E5=BF=97=EF=BC=9A=E5=8E=9F=E5=A7=8B=20JSON?= =?UTF-8?q?=20+=20=E8=A7=A3=E6=9E=90=E5=AD=97=E6=AE=B5=20+=20=E5=88=86?= =?UTF-8?q?=E5=8F=91=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit H5 调用分享接口时,按以下顺序输出到 Console(subsystem=ylgamehall, category=FriendsShare): ← H5 friendsShare mode=lobby raw={"sharefriend":"1",...} friendsShare parsed: sharefriend = "1" (1=好友/SharePanel, 2/其他=朋友圈) sharetype = "1" (1/2=微信, 3=闲聊;新外壳忽略) type = "1" (1=链接, 2=截图, 其他=远端图) webpageUrl = "https://..." title = "..." description = "..." → H5 sharesuccess fired: success="2", type="1" dispatch → lobby (直发微信 3 type 分支) raw 字段直接 JSONSerialization 序列化整个 BridgeData,含 H5 传入的所有 键(不限于上面解析的 6 项),便于排查 H5 端偷偷加字段或类型漂移。 --- .../Bridge/Handlers/FriendsShareHandler.swift | 65 +++++++++++++++---- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/ylgamehall/Source/Bridge/Handlers/FriendsShareHandler.swift b/ylgamehall/Source/Bridge/Handlers/FriendsShareHandler.swift index 5ab707d..192e057 100644 --- a/ylgamehall/Source/Bridge/Handlers/FriendsShareHandler.swift +++ b/ylgamehall/Source/Bridge/Handlers/FriendsShareHandler.swift @@ -21,10 +21,13 @@ // import Foundation +import os.log @MainActor public enum FriendsShareHandler { + private static let log = Logger(subsystem: "ylgamehall", category: "FriendsShare") + /// 注册时机的页面 mode。 public enum Mode: Sendable { /// 大厅页:H5 在 WebContainer 调 friendsShare 时直发微信 @@ -42,18 +45,35 @@ public enum FriendsShareHandler { // 1. responseCallback —— msext 字面 "sharefriend" callback?(.string("sharefriend")) - guard let obj = data?.asObject else { return } - let content = ShareContent( - // 缺失默认空串 → ShareCenter default 分支兜底(与原 msext [nil intValue]==0 等价) - sharefriend: obj["sharefriend"]?.asString ?? "", - sharetype: obj["sharetype"]?.asString ?? "", - type: obj["type"]?.asString ?? "", - webpageUrl: obj["webpageUrl"]?.asString ?? "", - title: obj["title"]?.asString ?? "", - desc: obj["description"]?.asString ?? "" - ) - await MainActor.run { + // 0. 调试日志:H5 传入的原始 JSON(含未声明字段,便于排查 H5 端字段漂移) + Self.log.debug("← H5 friendsShare mode=\(String(describing: mode), privacy: .public) raw=\(Self.describe(data), privacy: .public)") + + guard let obj = data?.asObject else { + Self.log.error("friendsShare: data 不是 object,跳过分发") + return + } + let content = ShareContent( + // 缺失默认空串 → ShareCenter default 分支兜底(与原 msext [nil intValue]==0 等价) + sharefriend: obj["sharefriend"]?.asString ?? "", + sharetype: obj["sharetype"]?.asString ?? "", + type: obj["type"]?.asString ?? "", + webpageUrl: obj["webpageUrl"]?.asString ?? "", + title: obj["title"]?.asString ?? "", + desc: obj["description"]?.asString ?? "" + ) + + // 调试日志:解析后的 ShareContent 各字段(带语义注释方便定位行为分支) + Self.log.debug(""" + friendsShare parsed: + sharefriend = "\(content.sharefriend, privacy: .public)" (1=好友/SharePanel, 2/其他=朋友圈) + sharetype = "\(content.sharetype, privacy: .public)" (1/2=微信, 3=闲聊;新外壳忽略) + type = "\(content.type, privacy: .public)" (1=链接, 2=截图, 其他=远端图) + webpageUrl = "\(content.webpageUrl, privacy: .public)" + title = "\(content.title, privacy: .public)" + description = "\(content.desc, privacy: .public)" + """) + // 2. 立即触发 sharesuccess —— 有意为之:调用即视为成功 bridge?.call( "sharesuccess", @@ -63,13 +83,32 @@ public enum FriendsShareHandler { ]), callback: nil ) + Self.log.debug("→ H5 sharesuccess fired: success=\"2\", type=\"\(content.sharefriend, privacy: .public)\"") // 3. fire-and-forget 拉起真实分享 UI(按页面 mode 选路径) switch mode { - case .lobby: ShareCenter.dispatchLobby(content) - case .subGame: ShareCenter.dispatchSubGame(content) + case .lobby: + Self.log.debug("dispatch → lobby (直发微信 3 type 分支)") + ShareCenter.dispatchLobby(content) + case .subGame: + Self.log.debug("dispatch → subGame (SharePanel 或朋友圈兜底)") + ShareCenter.dispatchSubGame(content) } } } } + + /// 把 BridgeData 整体序列化为 JSON 字符串方便日志输出(含 H5 传入的所有字段, + /// 不限于上面解析的 6 项 —— 万一 H5 偷偷加了字段也能看到)。 + private static func describe(_ data: BridgeData?) -> String { + guard let data else { return "" } + let raw = data.jsonObject + if let bytes = try? JSONSerialization.data( + withJSONObject: raw, + options: [.fragmentsAllowed, .sortedKeys] + ), let s = String(data: bytes, encoding: .utf8) { + return s + } + return String(describing: raw) + } }