app_appversion 业务语义纠正:审核切换标志 0/1(非版本号)
调研 daoqi/msext NewRootVC.m:1190-1208 initJSdata 发现 app_appversion
真实业务语义是审核切换标志,**不是 App 的版本号**:
if (远端 ResolvedVersion.appVersion >= 本地 BundleConfig.appVersion) {
app_gameconfig = BundleConfig.gameConfig; // 正常业务接口
app_appversion = '0'; // 标志:正常
} else { // 远端 < 本地(罕见,审核期 / IPA 已升远端未跟上)
app_gameconfig = BundleConfig.appleConfig; // 苹果审核期接口
app_appversion = '1'; // 标志:审核期
}
H5 端 if (app_appversion === '1') 切苹果审核期分支;99% 时间下都是 '0'
+ gameconfig。
当前代码两处错误:
❌ app_appversion 写成 "43"(版本号字符串)
❌ app_gameconfig 永远是 BundleConfig.gameConfig 硬编码
不符合契约(H5 拿到错误标志会走错分支)。按 CLAUDE.md 原则 A 第一准则
必须 1:1 等价 msext。
修复(Source/WebView/AppDataWriter.swift writeAppData):
- 加 result 计算:localAppVer = Int(bc.appVersion), remoteAppVer =
resolvedVersion?.appVersion ?? localAppVer;result = remoteAppVer >=
localAppVer ? 0 : 1
- 加 gameConfigStr 切换:result == 0 ? bc.gameConfig : bc.appleConfig
- app_appversion 写字面 '\(result)' 单引号包裹(与 msext "var
app_appversion='%d';" 等价)
- Logger 输出加 result 说明 + local/remote 版本号便于调试
Contract §4.2:新增详细业务语义说明段(含 msext 原 ObjC 代码 + result
0/1 含义解读 + app_gameconfig 动态切换说明),修订记录加一行。
Design §7.5.1 表格:#2 app_gameconfig 数据源改为"动态切换",#6
app_appversion 数据源改为"审核切换标志"。
Plan §6.4 里程碑加一行。
BuildProject 通过
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
7c856d0d66
commit
0a313afe8e
@@ -769,7 +769,8 @@ H5 调 `OpenurlTitleData` 打开弹层 WebView,弹层内 H5 用 `window.settin
|
||||
| 2026-06-22 | **§7.5 重大路径调整**:从「原生 `writeToFile` 写 4 个 `app_*.js` 文件」改为「H5 团队 zip 自带 + 原生 `WKUserScript(.atDocumentEnd)` / `evaluateJavaScript` 覆盖 `window.app_xxx` 全局变量」 | `246f215` |
|
||||
| 2026-06-22 | **CLAUDE.md 原则 A 升级为第一准则**:H5 端零修改不可妥协,禁止任何"H5 改一行 / 改一个文件 / 加 polyfill / 调时机"的妥协方案。加典型案例 3 复盘 `app_*` 注入时序问题 | `3039daf` |
|
||||
| 2026-06-22 | **§7.5 路径再次回退(最终)**:撤销 `246f215`,回到 msext 原写文件路径 `AppDataWriter`。原因:WKUserScript 时序(documentStart 被 H5 自带 var 覆盖、documentEnd 又太晚)无法 1:1 等价 msext,任何要求 H5 配合改动的方案违反原则 A 第一准则。Design §7.5 + Contract §4.2 + §10 全面同步回退 | `13cc24b` |
|
||||
| 2026-06-22 | **AppDataWriter 代码落地**:新增 `Source/WebView/AppDataWriter.swift` + `Source/Resource/NetworkMonitor.swift`;WebContainer.runBootPipelineSteps 在 step 5 后、step 6 loadFileURL 前调 `writeAppDataFiles(resolved:)` 写 4 个 app_*.js 文件 + 挂 battery/network 变化重写监听。BuildProject 通过 | 本次 commit |
|
||||
| 2026-06-22 | **AppDataWriter 代码落地**:新增 `Source/WebView/AppDataWriter.swift` + `Source/Resource/NetworkMonitor.swift`;WebContainer.runBootPipelineSteps 在 step 5 后、step 6 loadFileURL 前调 `writeAppDataFiles(resolved:)` 写 4 个 app_*.js 文件 + 挂 battery/network 变化重写监听。BuildProject 通过 | `829cc8f` |
|
||||
| 2026-06-22 | **`app_appversion` / `app_gameconfig` 业务语义纠正**:grep `daoqi/msext/NewRootVC.m:1190-1208` 发现 `app_appversion` 不是版本号、是审核切换标志(`'0'` 正常 / `'1'` 审核期);`app_gameconfig` 也跟着 result 在 `BundleConfig.gameConfig` / `appleConfig` 切换。AppDataWriter.writeAppData 加 result 计算逻辑;Contract §4.2 + Design §7.5.1 同步纠正;Contract §4.2 修订记录加一行 | 本次 commit |
|
||||
|
||||
> **§3.4.1 撤销说明**:早期 commit `82bad8a` 实现的 `window.settings.getXxx()` polyfill 已撤销 — Contract §附录 A 自身明示「iOS<9 路径,新外壳如最低系统 ≥ iOS 14 可不实现」,本项目最低 iOS 15.6 → polyfill 路径未启用,H5 用 §7.5 的 `app_*.js` 文件路径作为唯一主路径。详细缘由见 Design §3.4.1(撤销说明)和 CLAUDE.md「典型案例」段。
|
||||
|
||||
|
||||
+37
-10
@@ -715,20 +715,46 @@ H5 业务读 `app_getbattery`(带 get 前缀),**不是** `app_battery`。
|
||||
12 个变量(**没有** `app_gameid` / `app_compareCode`,那两个是 §4.2 早期文档错误记录,原项目代码 `NewRootVC.m:1204` / `gameController.m:2160` 字面字符串里**根本不写**它们):
|
||||
|
||||
```js
|
||||
var app_version = "1"; // 硬编码,沿用历史
|
||||
var app_gameconfig = "<gameconfig>";
|
||||
var app_gamedir = "<gamedir>";
|
||||
var app_gamestart = "<gamestart>";
|
||||
var app_agent = "<agent>";
|
||||
var app_appversion = "<appversion>"; // int 字面,msext "var app_appversion='%d'"
|
||||
var app_market = "<market>";
|
||||
var app_channel = "<channel>";
|
||||
var app_version = 1; // 硬编码,沿用历史,无引号数字
|
||||
var app_gameconfig = '<动态>'; // ⚠️ 动态切换,见下方 result 计算
|
||||
var app_gamedir = '<gamedir>';
|
||||
var app_gamestart = '<gamestart>';
|
||||
var app_agent = '<agent>';
|
||||
var app_appversion = '<0或1>'; // ⚠️ 不是版本号,是审核切换标志!见下方说明
|
||||
var app_market = '<market>';
|
||||
var app_channel = '<channel>';
|
||||
var app_Launchtype = 0; // ⚠️ L 大写!大厅=0 / 子游戏=1
|
||||
var app_getwifisignalLevel = 1; // ⚠️ wifi 小写、signal/Level 区分大小写,硬编码 1
|
||||
var app_gamename = "<gamename>";
|
||||
var app_invitationcode = "<tuiguang_id>"; // 推广码 / 邀请码
|
||||
var app_gamename = '<gamename>';
|
||||
var app_invitationcode = '<tuiguang_id>'; // 推广码 / 邀请码
|
||||
```
|
||||
|
||||
> **⚠️ `app_appversion` 真实业务语义(msext `NewRootVC.m:1190-1208` initJSdata)**:
|
||||
>
|
||||
> 不是 "App 的版本号",是**审核切换标志**:
|
||||
>
|
||||
> ```objc
|
||||
> int result;
|
||||
> NSString *str;
|
||||
> if ([self.version_ios intValue] >= [self.iosNumber intValue]) // 远端 >= 本地
|
||||
> {
|
||||
> str = [FuncPublic filename:@"gameconfig"]; // app_gameconfig 取 gameconfig
|
||||
> result = 0; // app_appversion = '0'
|
||||
> }
|
||||
> else { // 远端 < 本地
|
||||
> str = [FuncPublic filename:@"appleconfig"]; // app_gameconfig 取 appleconfig
|
||||
> result = 1; // app_appversion = '1'
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> 含义:
|
||||
> - `result = 0`(远端 ResolvedVersion.appVersion ≥ 本地 BundleConfig.appVersion):**正常业务模式**,H5 用 `gameconfig` 字段配置接口
|
||||
> - `result = 1`(远端 < 本地,罕见,可能审核期 / IPA 已升远端未跟上):**审核期模式**,H5 用 `appleconfig` 字段配置接口(无害业务展示给审核员)
|
||||
>
|
||||
> H5 读到 `app_appversion === '1'` 时切到苹果审核期分支;99% 时间下都是 `'0'`。
|
||||
>
|
||||
> 因此 `app_gameconfig` 不是简单读 `BundleConfig.gameConfig` 硬编码,而是根据 `result` 动态在 `gameConfig` / `appleConfig` 两个 plist 字段间切换。
|
||||
|
||||
> 大厅 / 子游戏的字面差异(详见 §7.5 Design):
|
||||
> - `app_Launchtype`:大厅 `0` / 子游戏 `1`
|
||||
> - `app_gamedir`:大厅 = `self.gamedir`(即 BundleConfig.gameDir)/ 子游戏 = `self.gamefilepath`(子游戏目录)
|
||||
@@ -777,6 +803,7 @@ var app_gamesname = new Array('game1','game2',...); // ⚠️ var 后面两
|
||||
| 2026-06-22 | 新增 `app_version` / `app_Launchtype` / `app_getwifisignalLevel` / `app_gamename` / `app_invitationcode` / `app_gamesname` 共 6 项 | daoqi `NewRootVC.m:1204`、`gameController.m:2160`、`AppDelegate.m:259` |
|
||||
| 2026-06-22 | **路径调整**:从"原生 `writeToFile` 写 4 个 `.js` 文件"改为"H5 团队 zip 包自带 + 原生 `WKUserScript(.atDocumentEnd)` / `evaluateJavaScript` 覆盖 `window.app_xxx` 全局变量值" | H5 团队 / 项目方约定 |
|
||||
| 2026-06-22 | **路径再次调整(最终)**:撤销上一行的 evaluateJavaScript 路径,回到原 msext "原生 `writeToFile` 写文件"路径。原因:WKUserScript 时序无法 1:1 等价 msext(`.atDocumentStart` 被 H5 自带 var 覆盖,`.atDocumentEnd` 太晚 H5 业务已读默认值),任何要求 H5 配合改动的方案违反 CLAUDE.md 原则 A 第一准则。Design §7.5 + 本节同步回退 | CLAUDE.md 原则 A 升级为第一准则后的重新评估 |
|
||||
| 2026-06-22 | **`app_appversion` 业务语义重大纠正**:早期文档把 `app_appversion` 描述为"App 的版本号字符串",实际是 msext `NewRootVC.m:1190-1208` 的审核切换标志(`'0'` 或 `'1'`)。当远端 < 本地时切到 `'1'` + `app_gameconfig` 切到 `BundleConfig.appleConfig`(审核期接口);其它情况都是 `'0'` + `gameConfig`(正常业务)。`app_gameconfig` 数据源同步从"硬编码 gameConfig"改为"动态切换 gameConfig/appleConfig"。Design §7.5.1 同步、代码 AppDataWriter.writeAppData 修复 | daoqi `NewRootVC.m:1190-1208` initJSdata 全面 grep 重读 |
|
||||
|
||||
### 4.3 WKUIDelegate(H5 alert / confirm)
|
||||
|
||||
|
||||
@@ -1991,11 +1991,11 @@ done
|
||||
| # | 变量名 | 大厅值(NewRootVC)| 子游戏值(gameController)| 数据源(新外壳) | 写入文件 |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | `app_version` | `"1"` 硬编码 | `"1"` 硬编码 | 硬编码 string `"1"`(沿用历史,H5 不会读出不同值) | `app_data.js` |
|
||||
| 2 | `app_gameconfig` | `self.gameconfig` | `self.gameconfig` | `BundleConfig.shared.gameConfig` | `app_data.js` |
|
||||
| 2 | `app_gameconfig` | `[FuncPublic filename:@"gameconfig"]` 或 `[FuncPublic filename:@"appleconfig"]`(动态切换,见下方)| 同左 | **动态切换**:`result==0` → `BundleConfig.gameConfig` / `result==1` → `BundleConfig.appleConfig`(详见 #6 app_appversion 计算)| `app_data.js` |
|
||||
| 3 | `app_gamedir` | `self.gamedir` | `self.gamefilepath` | 大厅 `BundleConfig.shared.gameDir` / 子游戏 `subGameDir` | `app_data.js` |
|
||||
| 4 | `app_gamestart` | `self.gamestart` | `self.game_name` | 大厅 `BundleConfig.shared.gameStart` / 子游戏 `subGameName` | `app_data.js` |
|
||||
| 5 | `app_agent` | `self.agentinfo` | `self.agentinfo` | `BundleConfig.shared.agent` | `app_data.js` |
|
||||
| 6 | `app_appversion` | 远端 `result` 解析后的 appVersion | `self.result_state` | `ResolvedVersion.appVersion` 或 `BundleConfig.shared.appVersion`(启动早期 fallback)| `app_data.js` |
|
||||
| 6 | `app_appversion` | `result`(0/1 二值标志,**不是版本号**) | `self.result_state`(同上) | **审核切换标志**(msext NewRootVC.m:1190-1208):`远端 ResolvedVersion.appVersion >= 本地 BundleConfig.appVersion` → `result=0`(正常 gameconfig),否则 `result=1`(审核期 appleconfig)。写入字面 `'0'` / `'1'` 单引号包裹数字(与 msext `'%d'` 等价)| `app_data.js` |
|
||||
| 7 | `app_market` | `self.market` | `self.market` | `BundleConfig.shared.market` | `app_data.js` |
|
||||
| 8 | `app_channel` | `self.channel_id` | `self.channel_id` | `BundleConfig.shared.channel` | `app_data.js` |
|
||||
| 9 | `app_Launchtype` | `"0"` 硬编码 | `"1"` 硬编码 | 大厅 `"0"` / 子游戏 `"1"`(⚠️ L 大写) | `app_data.js` |
|
||||
|
||||
Reference in New Issue
Block a user