Phase 1.9:BridgedWebView 封装 WKWebView + JS 注入 + BridgeBus

WebContainerViewController(Phase 1.10)的视图层依赖项:把 WKWebView 配置 /
WVJB.js 注入 / 桥总线 / scrollView 契约配置 4 件事一锅端打包成单一 UIView,
后续大厅 / 子游戏 / 弹层 VC 直接 add 进自己的内容区即可。

- 新增 ylgamehall/Source/WebView/BridgedWebView.swift
  - @MainActor final class,继承 UIView
  - 内含 public let webView: WKWebView 与 public let bridge: BridgeBus
  - init() 全自动:
    - WKWebViewConfiguration 按契约 §4.1:
      defaultWebpagePreferences.allowsContentJavaScript = true(iOS 14+
      现代 API,替代已弃用的 preferences.javaScriptEnabled)、
      javaScriptCanOpenWindowsAutomatically = NO、minimumFontSize = 10、
      allowsInlineMediaPlayback = true、processPool = SharedProcessPool.shared
    - 用 WKUserScript(.atDocumentStart) 把 WebViewJavascriptBridge.js 注入
      所有加载的 H5 页面,确保 H5 业务代码运行前 bridge 已就绪
    - 创建 BridgeBus,自动向 controller 注册 WVJBHandler 通道
    - scrollView:bounces=NO / isScrollEnabled=NO(契约硬约束,漏则 H5
      上下滑动失控)/ contentInsetAdjustmentBehavior=.never / 双向无指示器
    - WebView 撑满 self,自动布局
  - SharedProcessPool 命名空间:跨 WebView 共享 WKProcessPool,Cookie /
    资源缓存复用,启动加速(Design §3.5)
- BuildProject 通过,下一步 Phase 1.10 WebContainerViewController 用
  BridgedWebView 嵌入 + 16:9 letterbox + 加载 lobbyIndex
This commit is contained in:
joywayer
2026-06-22 00:19:51 +08:00
parent af1a2028e5
commit 65505b0a79
@@ -0,0 +1,89 @@
//
// BridgedWebView.swift
// ylgamehall
//
// WKWebView + WebViewJavascriptBridge.js + BridgeBus
// docs/H5-Native-Implementation-Design.md §3.3 / §4.1
//
import UIKit
import WebKit
/// H5 WebView WebContainerViewControllerPhase 1.10
/// view 16:9 letterbox /
@MainActor
public final class BridgedWebView: UIView {
public let webView: WKWebView
public let bridge: BridgeBus
public init() {
// WKWebViewConfiguration §4.1
let configuration = WKWebViewConfiguration()
configuration.defaultWebpagePreferences.allowsContentJavaScript = true
configuration.preferences.javaScriptCanOpenWindowsAutomatically = false
configuration.preferences.minimumFontSize = 10
configuration.allowsInlineMediaPlayback = true
configuration.processPool = SharedProcessPool.shared
// documentStart WebViewJavascriptBridge.js
// .atDocumentStart H5 window.WebViewJavascriptBridge
if let url = Bundle.main.url(forResource: "WebViewJavascriptBridge",
withExtension: "js"),
let source = try? String(contentsOf: url, encoding: .utf8) {
let userScript = WKUserScript(
source: source,
injectionTime: .atDocumentStart,
forMainFrameOnly: true
)
configuration.userContentController.addUserScript(userScript)
} else {
// print 便
print("[BridgedWebView] ERROR: WebViewJavascriptBridge.js 未在 Bundle 找到")
}
// WKWebView + BridgeBus
let webView = WKWebView(frame: .zero, configuration: configuration)
let bridge = BridgeBus(webView: webView,
controller: configuration.userContentController)
self.webView = webView
self.bridge = bridge
super.init(frame: .zero)
// ScrollView §4.1 / / inset
let scroll = webView.scrollView
scroll.bounces = false
scroll.isScrollEnabled = false // H5
scroll.contentInsetAdjustmentBehavior = .never
scroll.showsVerticalScrollIndicator = false
scroll.showsHorizontalScrollIndicator = false
// WebView self
webView.translatesAutoresizingMaskIntoConstraints = false
addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: topAnchor),
webView.bottomAnchor.constraint(equalTo: bottomAnchor),
webView.leadingAnchor.constraint(equalTo: leadingAnchor),
webView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
backgroundColor = .black
}
@available(*, unavailable)
public required init?(coder: NSCoder) {
fatalError("BridgedWebView does not support init(coder:)")
}
}
// MARK: - WebView
/// / / WKProcessPool Cookie /
/// Design §3.5
@MainActor
public enum SharedProcessPool {
public static let shared = WKProcessPool()
}