// // BackGameDataHandler.swift // ylgamehall // // H5 → Native handler:backgameData — 子游戏退出并把数据回传给大厅。 // 契约:docs/H5-Native-Contract.md §3.1 [18] // // 与 msext gameController.m:691-709 等价: // 1) 停背景音(无条件,与 stopBackground 不同 — msext 不看 type 直接 nil) // 2) AppCoordinator.shared.popSubGame(returningData: data) // 内部 popViewController + 发 .subGameDidReturn 通知,由大厅监听后 // 回调 H5 `getWebdata` 完成反向闭环 // 3) responseCallback("backgameData") 无论 data 是否解析成功都回(msext 字面) // // ⚠️ 仅注册到子游戏 SubGameViewController;大厅 WebContainerViewController 不注册。 // H5 大厅页若误调 backgameData 会落空(bridge 无对应 handler → JS 端的 callback 直接卡), // msext 同款行为 — 这是契约边界,不在原生侧兜底。 // import Foundation public enum BackGameDataHandler { public static func register(on bridge: any BridgeProtocol) { // 【18】backgameData // 入参 data(字符串,子游戏 H5 自定义透传给大厅 getWebdata) // cb: "backgameData" bridge.register("backgameData") { data, callback in await MainActor.run { // data 可能是 string / object,统一序列化为 string(msext NSString 透传等价)。 // - 直接是 .string → 取字面 // - 其它类型 → JSON 序列化(保留对象结构传给大厅 H5) let payload = serialize(data) AudioPlayer.shared.stopAllBackground() AppCoordinator.shared.popSubGame(returningData: payload) } callback?(.string("backgameData")) } } private static func serialize(_ data: BridgeData?) -> String { if let s = data?.asString { return s } guard let data else { return "" } let any = data.jsonObject if let bytes = try? JSONSerialization.data(withJSONObject: any, options: [.fragmentsAllowed]), let s = String(data: bytes, encoding: .utf8) { return s } return "" } }