Files
youle_app_ios_v2/ylgamehall
joywayer 0887088bb8 Phase 1.13:LobbyZipUpgrader 完成 H5 zip 升级端到端链路
Phase 1 远程配置链路(1.10-1.13)最后一环:把 VersionResolver 解出的
gameZip URL 下载 + 解压 + 原子 rename 到 lobbyRoot,触发条件是远端
gameVersion > 本地 version.xml /game/version@value。

- 新增 ylgamehall/Source/Resource/LobbyZipUpgrader.swift
  - public actor,单例 LobbyZipUpgrader.shared
  - upgradeIfNeeded(resolved:) async throws -> Outcome
    - .noop:远端版本 ≤ 本地,或 gameZip nil / 非法 URL,直接返回
    - .upgraded(from:to:):完成升级,附前后版本号
  - URLSession.download(from:) 异步下载(60s 请求 / 300s 资源超时),
    HTTP 状态码非 2xx 抛 .httpStatus
  - 解压到 caches/lobby-staging-{UUID}/ 隔离目录(不直接覆盖 lobbyRoot,
    msext "removeItem + ZipArchive overWrite:YES" 半途崩溃会留半残;
    我们 staging 完整解压成功后才 rename)
  - 原子 rename:fm.removeItem(lobbyRoot) → fm.moveItem(staging,
    to: lobbyRoot);任一步失败抛 .stagingMoveFailed,调用方决定回退
  - 类型化 UpgradeError 5 种:badGameZipURL / downloadFailed /
    httpStatus / unzipFailed / stagingMoveFailed
  - 实现照搬 msext NewRootVC.m:1789-1869 downFileFromServer + unzip
    + unzipDone 的语义,但用现代 async + 原子 rename 替代 ASIHTTPRequest
    + detachNewThreadSelector + ZipArchive overWrite:YES
- RootViewController 烟雾测试串接 LobbyZipUpgrader:
  调 upgradeIfNeeded → switch outcome → 升级后重新读 version.xml 验证
- 真机实测端到端链路:
  第一次:本地 260 vs 远端 261 → 升级完成 261,耗时 2.007s
    (下载 11.5 MB HTTP zip + ZIPFoundation 解压 + 原子 rename)
    重新读 version.xml = 261 ✓ lobbyIndex 仍存在 ✓
  第二次:本地 261 vs 远端 261 → .noop,耗时 0.001s(幂等验证)

Phase 1 远程配置链路(1.10-1.13)完整闭环。下一步 Phase 1.14
WebContainer 把这条链路插到 viewDidLoad 之前 + 16:9 letterbox 加载
lobbyIndex,第一次让真实大厅 H5 渲染出来。
2026-06-22 02:27:48 +08:00
..
2026-06-21 19:37:33 +08:00