【数据流改造(三分制)】 - 微信 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>
58 lines
2.2 KiB
Swift
58 lines
2.2 KiB
Swift
//
|
|
// BundleConfig.swift
|
|
// ylgamehall
|
|
//
|
|
// 渠道注入配置:从 Bundle 内的 ChannelConfig.plist 读 10 个 string 值。
|
|
// 设计模式与契约见 docs/H5-Native-Implementation-Design.md §7 / ADR-007。
|
|
//
|
|
// 注:原有 qiniudomain 字段已于 2026-06-27 移除,七牛 CDN 域名改由
|
|
// RemoteConfig 顶层 audio_domain 单一权威源动态下发。
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// 渠道注入配置(10 项),由 `BundleConfig.shared` 在 App 启动时一次性加载,运行期不变。
|
|
///
|
|
/// 多渠道分发:构建后用 `plutil` 修改 `.app/ChannelConfig.plist` + 重签,
|
|
/// 不需要重新 Xcode build。详见 ADR-007。
|
|
nonisolated public final class BundleConfig: Sendable {
|
|
|
|
/// App 启动期默认读 main bundle 的 `ChannelConfig.plist`,业务代码统一通过此单例访问。
|
|
public static let shared = BundleConfig()
|
|
|
|
public let gameId: String
|
|
public let channel: String
|
|
public let gameDir: String
|
|
public let gameStart: String
|
|
public let gameConfig: String
|
|
public let market: String
|
|
public let agent: String
|
|
public let appVersion: String
|
|
public let other: String
|
|
public let appleConfig: String
|
|
|
|
/// 单测可注入任意 bundle 验证不同 plist fixture。
|
|
public init(bundle: Bundle = .main) {
|
|
let dict = Self.loadPlist(bundle: bundle)
|
|
gameId = dict["gameid"] ?? ""
|
|
channel = dict["channel"] ?? ""
|
|
gameDir = dict["gamedir"] ?? ""
|
|
gameStart = dict["gamestart"] ?? ""
|
|
gameConfig = dict["gameconfig"] ?? ""
|
|
market = dict["market"] ?? ""
|
|
agent = dict["agent"] ?? ""
|
|
appVersion = dict["appversion"] ?? ""
|
|
other = dict["other"] ?? ""
|
|
appleConfig = dict["appleconfig"] ?? ""
|
|
}
|
|
|
|
private static func loadPlist(bundle: Bundle) -> [String: String] {
|
|
guard let url = bundle.url(forResource: "ChannelConfig", withExtension: "plist"),
|
|
let data = try? Data(contentsOf: url),
|
|
let plist = try? PropertyListSerialization.propertyList(
|
|
from: data, format: nil) as? [String: String]
|
|
else { return [:] }
|
|
return plist
|
|
}
|
|
}
|