// // OpenurlTitleDataHandler.swift // ylgamehall // // H5 → Native handler:OpenurlTitleData — 打开内嵌 WebView 弹层(msext threeView 等价)。 // 契约:docs/H5-Native-Contract.md §3.1 [15] // // ⚠️ 入参 key "title " 末尾有空格(msext 历史契约硬约束): // 必须 `data["title "]?.asString` 而不是 `data["title"]?.asString`, // H5 端 callHandler 时也是 `{"title ": "..."}`(带空格的字符串字面) // // 与 msext NewRootVC.m / gameController.m 等价: // - 大厅 + 子游戏页都注册(msext 两处都有),用户在哪一页调都能打开弹层 // - 3 秒节流由 AppCoordinator.showOverlay 守门(msext first_Time 等价) // - callback 字面始终回 "OpenurlTitleData",无论节流是否命中(msext 行为) // import Foundation public enum OpenurlTitleDataHandler { public static func register(on bridge: any BridgeProtocol) { // 【15】OpenurlTitleData // 入参 url / "title "(末尾空格!) / data / orientation // cb: "OpenurlTitleData" bridge.register("OpenurlTitleData") { data, callback in await MainActor.run { // ⚠️ "title " 末尾空格不可改;orientation 在 landscape-only app 中保留契约字段 let url = data?["url"]?.asString ?? "" let title = data?["title "]?.asString ?? "" let webData = data?["data"]?.asString ?? "" let orientation = data?["orientation"]?.asInt ?? Int(data?["orientation"]?.asString ?? "") ?? 0 let request = OverlayRequest( url: url, title: title, webData: webData, orientation: orientation ) AppCoordinator.shared.showOverlay(request) } // msext 行为:无论节流命中 / 入参缺失,都回 cb,避免 H5 等待 callback?(.string("OpenurlTitleData")) } } }