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) + } }