Phase 1.F: WebView 加载从 file:// 迁到 ylgame://h5 自定义 scheme
为未来 Cocos 子游戏 H5 build 适配铺路(file:// 下 Cocos XHR/fetch 受 null-origin 限制几乎必踩坑),同时保留大厅 + 子游戏跨页 localStorage 共享语义(用单虚拟 host `h5` 让所有 H5 same-origin)。 变更: - 新增 AppSchemeHandler(WKURLSchemeHandler 单例 + Range/MIME/异步 IO/ 取消语义;闭包只携 Sendable ObjectIdentifier,不捕获 task) - SandboxPaths 加 lobbyIndexAppURL / subGameIndexAppURL builders - BridgedWebView 注册 scheme handler(WKWebView init 前) - WebContainerViewController / SubGameViewController 的 loadFileURL → webView.load(URLRequest),OverlayViewController 不变 文档: - Plan 新增 Phase 1.F (1.18-1.21) + ADR-010 决策记录 + 进度勾选 - Design 新增 §7.6 包含 URL 结构 / 实现要点 / 等价性表 / Cocos 预检脚本 - Contract §0.2 / §4.1 / §10 验收清单同步切换说明(H5 可观察差异: location.protocol "file:" → "ylgame:",项目方已 grep 确认现网 H5 不依赖此字面) 存量影响:file:// → ylgame:// origin 切换时老用户 localStorage 一次性 清零,已与项目方确认业务可接受、不做迁移补偿。 BuildProject 通过。Plan 进度已勾选 1.18/1.19/1.20。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
960adc5491
commit
04e702a99b
@@ -46,7 +46,8 @@ iOS 26 时代 iOS 9 路径再也跑不到了(最低支持 iOS 9.0,但所有
|
||||
- H5 源码以 `gamehall.zip`(≈ 11 MB)形式打入 Bundle
|
||||
- 首次启动解压到沙盒 `Library/Caches/{gamedir}/`(`gamedir` 是渠道注入值)
|
||||
- 启动入口固定为:`Library/Caches/{gamedir}/{gamestart}/index.html`
|
||||
- WebView 直接 `loadFileURL:` 加载,**走 file:// 协议**,不依赖 HTTP 服务器
|
||||
- **加载方式(msext 现网行为)**:`loadFileURL:` 走 `file://` 协议,不依赖 HTTP 服务器
|
||||
- **新外壳(Phase 1.F 起)**:迁到自定义 scheme `ylgame://h5/lobby/<gameStart>/index.html` + `WKURLSchemeHandler`,反向映射回相同沙盒物理路径。H5 可观察差异 = `location.protocol` 由 `"file:"` 变为 `"ylgame:"`;项目方已 grep 确认现网 H5 不依赖此字面。详见 `docs/H5-Native-Implementation-Design.md` §7.6 / Plan ADR-010
|
||||
- 启动 query 参数:旧桥附 `?Launchtype=0`,新桥未附;新桥额外注入 `app_data.js`/`app_battery.js`/`app_network.js`
|
||||
|
||||
### 0.3 渠道注入机制("空目录名注入")
|
||||
@@ -696,9 +697,11 @@ _webView.scrollView.showsHorizontalScrollIndicator = NO;
|
||||
```
|
||||
|
||||
- 不设置自定义 User-Agent
|
||||
- 不显式管理 Cookie
|
||||
- LocalStorage 由 H5 自管(WKWebView 默认走 WebsiteDataStore)
|
||||
- 加载方式:**`loadFileURL:fileURL allowingReadAccessToURL:dirURL`**(file://),不走 HTTP
|
||||
- 不显式管理 Cookie(业务确认现网 H5 不用 cookies)
|
||||
- LocalStorage 由 H5 自管(WKWebView 默认走 `WKWebsiteDataStore.default()` 持久化);**跨 H5 共享语义**:大厅 + 所有子游戏共享同一 localStorage 命名空间(业务依赖)。msext 现网 file:// 下因 null origin 天然共享;新外壳 Phase 1.F 起用 `ylgame://h5/...` 单虚拟 host same-origin 保留此语义
|
||||
- 加载方式:
|
||||
- **msext 现网**:`loadFileURL:fileURL allowingReadAccessToURL:dirURL`(file://),不走 HTTP
|
||||
- **新外壳(Phase 1.F 起)**:`webView.load(URLRequest(url: ylgame://h5/...))` + `WKURLSchemeHandler` 反向映射;行为对 H5 等价(详见 Design §7.6.5 等价性表 / Plan ADR-010)
|
||||
|
||||
### 4.2 JS 注入(最终路径:原生 `writeToFile` 写文件,与 msext 1:1 等价)
|
||||
|
||||
@@ -1035,7 +1038,9 @@ Library/Caches/
|
||||
- [ ] 重装 + 热启动:< 1 秒进入大厅
|
||||
- [ ] 渠道注入:把 `msext/channel/xxx` 目录名改成 `yyy`,重打包后大厅显示的渠道 ID 变为 `yyy`
|
||||
- [ ] iOS 18 / 19 / 26 上启动不卡死
|
||||
- [ ] **`app_*.js` 4 个文件在沙盒**:`{gamedir}/{gamestart}/` 下 `app_data.js` / `app_battery.js` / `app_network.js` / `app_gamesname.js` 全部存在、loadFileURL 前已落盘(`xcrun simctl get_app_container booted <bundle>` + `cat` 验证)
|
||||
- [ ] **`app_*.js` 4 个文件在沙盒**:`{gamedir}/{gamestart}/` 下 `app_data.js` / `app_battery.js` / `app_network.js` / `app_gamesname.js` 全部存在、`webView.load(...)` 前已落盘(`xcrun simctl get_app_container booted <bundle>` + `cat` 验证)
|
||||
- [ ] **`window.location` 切到自定义 scheme**(Phase 1.F 起):H5 console `location.protocol` === `"ylgame:"`、`location.host` === `"h5"`;同样地大厅 + 子游戏 host 必须完全相同(保证 same-origin)
|
||||
- [ ] **跨页 localStorage 共享**:大厅 H5 `localStorage.setItem('k','v')` → push 子游戏 → 子游戏 `localStorage.getItem('k')` === `'v'`;pop 回大厅数据保留
|
||||
- [ ] **`app_*` 12 + 1 + 1 + 1 = 15 个全局变量命名 100% 正确**(参 §4.2):H5 console 检查 `app_version` / `app_gameconfig` / `app_gamedir` / `app_gamestart` / `app_agent` / `app_appversion` / `app_market` / `app_channel` / `app_Launchtype` / `app_getwifisignalLevel` / `app_gamename` / `app_invitationcode` / `app_getbattery` / `app_getnetwork` / `app_gamesname` 全部 `!== undefined`;尤其大小写 `app_Launchtype`(L 大写)/ `app_getwifisignalLevel`(wifi 小写 + signal/Level 区分)/ `app_getbattery`、`app_getnetwork`(带 get 前缀)必须精确
|
||||
- [ ] **值是实际渠道值而非占位**:H5 console 读 `app_channel` 应为 `ChannelConfig.plist` 的 channel 值(不是 H5 团队 zip 内可能预留的占位字符串)
|
||||
- [ ] **大厅 vs 子游戏字面差异**:大厅 H5 内 `app_Launchtype === 0`(数字 0,非字符串 `"0"`)、子游戏 H5 内 `app_Launchtype === 1`
|
||||
|
||||
Reference in New Issue
Block a user