Phase 1.14.c:LobbyZipUpgrader 加 0…1 progress 回调

- upgradeIfNeeded 新增 onProgress: @escaping @Sendable (Double) -> Void 参数,
  默认 no-op 兼容仅做版本对比的烟雾测试
- 新增文件内私有 DownloadProgressDelegate(URLSessionDownloadDelegate
  + @unchecked Sendable),在 didWriteData 回调里把 totalBytesWritten /
  totalBytesExpectedToWrite 换算成 0…1 上报,clamp 到 [0,1]
- 通过 session.download(from:delegate:) 注入;下载完成后兜底报 1.0
  (部分 server 不发 Content-Length 或末尾片段晚到,避免进度条停在 99%)
- RootViewController 烟雾测试用 ProgressTicker 把回调节流到 10% 阶梯打印,
  避免几百行刷屏(NSLock 保护单 Int 状态,@unchecked Sendable)
- BuildProject 通过

Plan 进度已勾选(§5 Phase 1.14.c + §8)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joywayer
2026-06-22 02:46:11 +08:00
co-authored by Claude Opus 4.7
parent ba34854133
commit f3c66b670d
3 changed files with 86 additions and 10 deletions
+29 -2
View File
@@ -129,10 +129,19 @@ final class RootViewController: UIViewController {
→ H5 zip 升级 = \(needZipUpgrade ? "需要" : "不需要")
""")
// Phase 1.13 LobbyZipUpgrader
// Phase 1.13 / 1.14.c LobbyZipUpgrader
// progress 10%
let upgradeStart = Date()
do {
let outcome = try await LobbyZipUpgrader.shared.upgradeIfNeeded(resolved: resolved)
let lastReported = ProgressTicker()
let outcome = try await LobbyZipUpgrader.shared.upgradeIfNeeded(
resolved: resolved,
onProgress: { p in
lastReported.tickIfPassed(p) { reported in
print(String(format: "[LobbyZipUpgrader] 下载进度 %3d%%", Int(reported * 100)))
}
}
)
let elapsed = Date().timeIntervalSince(upgradeStart)
switch outcome {
case .noop:
@@ -173,3 +182,21 @@ final class RootViewController: UIViewController {
override var prefersStatusBarHidden: Bool { false }
}
/// Phase 1.14.c 使 10% progress
/// `@unchecked Sendable` Int NSLock
private final class ProgressTicker: @unchecked Sendable {
private let lock = NSLock()
private var lastBucket: Int = -1
func tickIfPassed(_ progress: Double, action: (Double) -> Void) {
let bucket = Int(progress * 10)
lock.lock()
let shouldFire = bucket > lastBucket
if shouldFire { lastBucket = bucket }
lock.unlock()
if shouldFire {
action(Double(bucket) / 10.0)
}
}
}