Commit Graph
6 Commits
Author SHA1 Message Date
joywayer c398a8dd58 3.C:录音组件落地(VoiceRecorder + Overlay + Presenter + Window 子类)
完整支撑 Phase 3.E prepareaudio handler 的录音子链路:用户按住 H5 麦克风按钮
→ Native 录音 → 松手停止 → 触发完成回调。

## 新增模块

- `RecordingAwareWindow`:UIWindow 子类,提供 touch 旁路监听通道
  (static touchObserver closure)。默认行为与 UIWindow 完全一致,仅
  RecordingPresenter 注册 observer 后才触发额外行为。daoqi msext
  CustomWindow.m + nScreenTouch 通知同款思路,改用 closure 注入
- `VoiceRecorder`:AVAudioRecorder + AudioSession + 0.1s 计时器封装。
  ObservableObject + @Published(暴露 averagePower / elapsed 给 SwiftUI)。
  录音参数 8kHz/16bit/mono PCM 严格对齐 daoqi(AMR-NB 编码硬要求)。
  60s 上限对齐 daoqi kDefaultMaxRecordTime
- `RecordingOverlay`:SwiftUI 浮层(UI 内部实现,按 CLAUDE.md「原则 B 原生
  内部自由」与 daoqi 不一致)。半透明黑底胶囊 + SF Symbols 麦克风 + 音量
  光晕动画 + 倒计时(剩 10s 显示秒数,对齐 daoqi UI 逻辑)
- `RecordingPresenter`:组装入口。挂载 overlay 到 hostVC 全屏覆盖 +
  注册 touchObserver。提供 `start(on:fileName:onFinish:)` 单一 API +
  `cancelActive()` 强制取消

## SceneDelegate 改动

UIWindow → RecordingAwareWindow 实例化。变量类型仍为 UIWindow?
(多态),sendEvent 走子类版本。零行为变化(observer 未注册时)。

## 为何必须走 UIWindow 子类

H5 麦克风按钮按下触发 prepareaudio → 录音浮层在按住状态下中途弹出。
iOS touch 事件流是 view hit-test 链,**in-flight touch 不传给中途加入
的 view**,浮层 view 自身收不到 touchesEnded,用户松手时检测不到。

唯一可靠路径是 UIWindow.sendEvent 旁路截获(UIWindow 接收所有 touch
event 无论 in-flight 还是新 touch)。daoqi msext 也是这条路。

## Combine 引入

VoiceRecorder 用 ObservableObject + @Published 给 SwiftUI 数据绑定,
需要 import Combine。CLAUDE.md「避免 Combine」精神是禁用 Publisher 链
替代 async/await,不是禁止 ObservableObject(iOS 15.6 无 @Observable
宏可替代)。已在 VoiceRecorder.swift 注释说明。

## 验证

BuildProject 通过 0 错误,全部新文件 XcodeRefreshCodeIssuesInFile 0 诊断。
2026-06-24 01:29:04 +08:00
joywayerandClaude Opus 4.7 1d7e258130 Phase 4.E + Phase 5 + Phase 3.C 七牛上传:代码侧 SDK 接入(SPM 优先 / Vendor 兜底)
选型(CLAUDE.md ADR-006「SPM 优先 + Vendor xcframework 兜底」):
- 微信 → SPM(Tencent 官方 https://github.com/Tencent/WechatOpenSDK-XCFramework);
  项目方下载的 WechatOpenSDK-NoPay.xcframework 已撤出 Vendor,docs/res 内副本作离线备份
- 高德 → Vendor 手动(官方未提供 SPM;Vendor/AMap/{AMapFoundationKit,AMapLocationKit}.framework
  随仓库分发,fat .framework 同时含 x86_64 + arm64,Do Not Embed)
- 七牛 → SPM(https://github.com/qiniu/objc-sdk v8.9.x)

代码侧(全部 #if canImport 守卫,Xcode 加 SDK 前编译为 no-op):
- Source/SDK/WeChat/WeChatSDK.swift:WXApi.registerApp + handleOpenURL(沿用 msext AppID
  wx586a9b321e56efb7,universalLink 空字符串走非 ULAPI 路径)
- Source/SDK/WeChat/WeChatManager.swift:WXApiDelegate + state UUID 配对的 authorize +
  FIFO 串行 share async/await wrapper
- Source/Login/WeChatAuth.swift:客户端直拼 sns/oauth2/access_token + sns/userinfo →
  7 字段(Province 大写 P / city 经 danbian 去单引号),沿用 msext 同款路径
- Source/SDK/AMap/AMapWrapper.swift:iOS 14+ 隐私合规 3 步 + apiKey 注入
- Source/Location/LocationService.swift:actor + AMapLocationManager 异步包装 + 9 字段
- Source/Network/QiniuConfig.swift:4 项常量沿用 msext(AccessKey/SecretKey/Bucket/Domain)
- Source/Network/QiniuTokenSigner.swift:纯 Swift CryptoKit HMAC-SHA1 + Base64URL 自签
  token(与 msext QiniuManager.m:200-230 等价,不依赖 Qiniu SDK 工作)
- Source/Network/QiniuUploader.swift:actor 包 QNUploadManager async/await

Handler 升级:
- AccreditLoginHandler:拉起授权 → 反向 callback sharelogin 7 字段
- WechatShare:真实链接分享(type=2/3 截图待 Phase 4.F)
- StartLocationHandler:真实定位 → 9 字段(latitude/longitude string, province 小写 p)

生命周期:
- AppDelegate.didFinishLaunchingWithOptions:WeChatSDK.register + AMapWrapper.bootstrap
- SceneDelegate.openURLContexts:WeChatSDK.handleOpenURL 接入回调
- BackGameDataHandler:子游戏 backgameData pop 时 WXApi.delegate=nil + LocationService.stop()

Info.plist:CFBundleURLTypes 加 wx586a9b321e56efb7;LSApplicationQueriesSchemes 追加
weixin/weixinULAPI/weixinURLParamsAPI;NSLocationWhenInUseUsageDescription +
NSMicrophoneUsageDescription(gamehallname 中文文案)。

.gitignore:排除 docs/res/{AMap_iOS_Loc_ALL,objc-sdk-8.9.2}/(235MB 项目方下载副本,
已走 SPM/Vendor 接入不需要副本)。

文档:docs/SDK-Integration-Guide.md 重写 §A 用户手动 Xcode UI 三步(SPM × 2 +
Add Files × 2);Vendor/{AMap,WechatSDK}/README.md 记录各自接入路径选型。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-22 22:22:23 +08:00
joywayerandClaude Opus 4.7 7a5644053d Phase 6 commit A:AppCoordinator + SubGameViewController 框架 + SwitchOverGameData push
- AppCoordinator:2s 节流 + 栈深 < 2 守门 + .subGameDidReturn 通知名(Design §2.4.3)
- SubGameViewController:复用 BridgedWebView/Splash/16:9 letterbox/ExternalSubscriptions,
  AppDataWriter(.subGame) 写 4 个 app_*.js;H5 未安装时抛错(待 commit B 接入下载)
- SwitchOverGameHandler:解 Gamedirectory/gamedownloadurl/data → AppCoordinator.showSubGame
  (msext NewRootVC.m:541-566 等价,节流与栈深由 Coordinator 守门,cb 字面始终回)
- SceneDelegate:UINavigationController 承载大厅,nav 引用交给 AppCoordinator
- Plan 进度已勾选 §5 / §8(commit B/C 留待 SubGameDownloader 与 backgameData/getWebdata 链路)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-22 20:59:00 +08:00
joywayerandClaude Opus 4.7 c95e80df9c Phase 1.16:SceneDelegate 接 WebContainer + 退役 RootViewController
- SceneDelegate.scene(_:willConnectTo:options:) 中 rootViewController
  从 M0 占位 RootViewController() 改为 WebContainerViewController()
- 删除 ylgamehall/RootViewController.swift(M0 + Phase 1.2–1.13 烟雾测试
  整体退役);所有 print 验证记录在 git log,留着是死代码
- File System Synchronized Group 自动适应文件删除,无需改 pbxproj
- BuildProject 通过

至此 Phase 1.16 完成;启动链路:
  SceneDelegate → WebContainerViewController.viewDidLoad
    → setupBridgedWebView + setupSplash + registerBridgeHandlers
    → runBootPipeline (ensureReady → fetch → resolve → upgrade → loadFileURL)
    → didFinish 淡出 splash

Plan 进度已勾选(§5 Phase 1.16 + §8)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-22 04:23:52 +08:00
joywayer 7a84223841 M0:项目基础配置就绪(横屏锁定、Swift 6、代码启动)
- 锁定 iPhone/iPad 仅横屏(LandscapeLeft/Right),契合 H5 端
  1280×720 设计分辨率;UIRequiresFullScreen=true 防 iPad
  多任务下方向不锁
- Swift Language Version 升到 6.0(配合已启用的
  Approachable Concurrency + MainActor 默认隔离)
- 删除默认 Main.storyboard / ViewController.swift 模板,
  改用 SceneDelegate 代码创建 RootViewController 启动,
  Build Settings 同步清空 INFOPLIST_KEY_UIMainStoryboardFile
- Info.plist 补齐契约项 UIStatusBarHidden=NO、
  UIViewControllerBasedStatusBarAppearance=YES,配合
  AppDelegate 启动时设置 applicationSupportsShakeToEdit=true
  覆盖契约 §4.2.1 摇一摇前置
- BuildProject 通过验证
2026-06-21 20:03:33 +08:00
joywayer 108b359f96 Initial Commit 2026-06-21 19:37:33 +08:00