Commit Graph
3 Commits
Author SHA1 Message Date
joywayerandClaude Opus 4.7 83d9502dee ADR-009 凭证集中化:AppSecrets.plist + 七牛运行参数走 RemoteConfig.audio_*(契约影响)
【数据流改造(三分制)】
- 微信 AppID  唯一源 = Info.plist CFBundleURLTypes (URLName=weixin first scheme)
- 应用级凭证 唯一源 = AppSecrets.plist (wxAppSecret/qiniuAccessKey/qiniuSecretKey)
- 七牛运行参数 唯一源 = RemoteConfig 顶层 audio_domain / audio_bucket(远端动态注入)

【契约影响】
- ChannelConfig.plist:11 key → 10 key,移除 qiniudomain(ADR-007 守护规则同步)
- BundleConfig:删除 qiniuDomain 属性
- RemoteConfig:顶层新增可选字段 audioDomain / audioBucket(JSON snake_case 自动归一化)
- 启动期:WebContainerViewController parsed 分支校验 audio_domain/audio_bucket 非空,
  缺失抛 BootError.audioConfigMissing 弹 modal 永停(与 showmessage 同等致命)
- 上线前置:测试 / 生产远端 .txt 配置必须先补 audio_domain / audio_bucket 两个顶层 key
- WeChatSDK.appID / WeChatAuth.appSecret / QiniuConfig.* 调用方零签名变化

【新增】
- ylgamehall/Resources/AppSecrets.plist(3 key)
- ylgamehall/Source/Resource/AppSecrets.swift(单例加载,对齐 BundleConfig 模式)
- QiniuConfig 改 actor:cdnDomain/bucketName 进 actor 状态 + update(...) async;
  accessKey/secretKey 仍 nonisolated(直接读 AppSecrets)
- QiniuTokenSigner.uploadToken() 改 async(bucketName 来自 actor)
- QiniuUploader 预取 cdnDomain 闭包外,SDK 同步 callback 内直接拼 URL

【删除】
- WeChatSDK.swift  static let appID  硬编码 → Info.plist 启动期解析
- WeChatAuth.swift static let appSecret 硬编码 → AppSecrets.shared.wxAppSecret
- QiniuConfig 中 accessKey / secretKey / bucketName / cdnDomain 四处硬编码
- ChannelConfig.plist 的 qiniudomain 字段(plist 与代码双源僵尸字段)

【文档同步】
- Plan:新增 ADR-009 + ADR-007 守护规则改 10 key + §236 BundleConfig 描述
- Design §3.4 多处 "11 项" → "10 项";§7.0.3 plist 示例 + BundleConfig 代码骨架
  + Scripts/inject_channel.sh 同步
- SDK-Integration-Guide §0 凭证位置改三分制 + §尾"七牛域名读取"加新外壳路径
- Verification-Checklist L69 "(11 项)" → "(10 项)"

参考契约章节:docs/Development-Plan.md ADR-009、docs/H5-Native-Implementation-Design.md §7.0.3
BuildProject 通过,Xcode 即时诊断 0 警告。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-27 21:07:55 +08:00
joywayer 463f0fc6fe Phase 1.5:ResourceUnzipper 解压 gamehall.zip 到 Caches 全链路打通
启动期完成「ChannelConfig.plist 读 → SandboxPaths 算路径 →
gamehall.zip 解压」三步,lobbyIndex 真实存在于沙盒 Caches,
为 Phase 1.10 WebContainer file:// 加载就绪。

- 新增 ylgamehall/Source/Resource/ResourceUnzipper.swift
  - public actor,全局单例 ResourceUnzipper.shared
  - ensureReady() async throws:检查 lobbyVersionXML 不存在则调
    FileManager.unzipItem (ZIPFoundation 扩展) 解压 Bundle 内
    gamehall.zip 到 SandboxPaths.lobbyRoot
  - UnzipError 类型化错误(bundleZipNotFound / unzipFailed)
  - 幂等:已就绪直接 return,并发调用安全(actor 串行)
- 新增 ylgamehall/Resources/gamehall.zip:从 docs/res 拷一份入
  Bundle(11.5 MB,2023-12 旧版;上线前由 H5 团队替换最新版,
  ADR-002 已记录)
- Swift 6 严格并发适配:
  - SandboxPaths:所有 static 成员标 nonisolated(无状态命名空间,
    从 actor / 非 MainActor 上下文都能直接读 caches/documents/bundle
    及 lobby 路径计算)
  - BundleConfig:class 整体 nonisolated(Sendable + all-let 属性,
    跨 actor 边界安全),允许 ResourceUnzipper actor 读 channel 配置
- RootViewController 补 ResourceUnzipper 烟雾测试 Task:
  await ensureReady() 后打印耗时 + lobbyIndex 是否真实存在
- 真机验证(iOS Simulator):首次 1.266s 解压成功,二次启动 0s 跳过
2026-06-22 00:01:08 +08:00
joywayer dcc12bb76d Phase 1.2:BundleConfig 读 ChannelConfig.plist 完成 11 项渠道注入加载
- 新增 ylgamehall/Source/Resource/BundleConfig.swift
  - 11 个 public let 属性(qiniuDomain / gameId / channel / gameDir
    / gameStart / gameConfig / market / agent / appVersion / other
    / appleConfig)
  - public init(bundle: Bundle = .main) —— 默认走 main bundle,单测
    可注入 mock bundle 验证不同 plist fixture
  - PropertyListSerialization 反序列化 ChannelConfig.plist
  - final class + Sendable(all-let,String 是 Sendable,Swift 6
    严格并发下编译器静态校验通过)
  - 单例 BundleConfig.shared,业务统一通过此访问
- RootViewController.viewDidLoad 加烟雾测试 print 11 项值,首次运行
  真机/模拟器即可在 console 验证读取正确
- BuildProject 通过,synchronized group 自动收编 BundleConfig.swift
  为 source(.swift 文件类型走 SwiftCompile,不再卡 plist 那样的
  resource 扁平化问题)
- 单元测试待 Phase 0.2 单测 target 建立后补齐
2026-06-21 23:47:23 +08:00