Files
youle_app_ios_v2/ylgamehall/Source/Bridge/Handlers/BackGameDataHandler.swift
T
joywayerandClaude Opus 4.7 a3679aba7d 修复 SDK 真实接入后的 Swift 编译错误 + Xcode 链接配置
实测三个 SDK(微信 / 高德 / 七牛)链接进 Target 后,暴露出 9 个 Swift 编译错误,逐一修正:

代码侧(5 个 Swift 文件):
- AMapWrapper:updatePrivacyShow / updatePrivacyAgree 是 AMapLocationManager
  类方法(since 2.8.0),不在 AMapServices 上;改为 AMapLocationManager.*
  并补 import AMapLocationKit
- BackGameDataHandler:删 `WXApi.delegate = nil`。新版 SDK 2.x 无 static
  delegate API,delegate 由调用方逐次传给 handleOpenURL/sendAuthReq 并被
  SDK 弱引用;WeChatManager singleton 长生命周期不析构,无需 cleanup
- QiniuConfig / QiniuTokenSigner:所有 static 成员标 nonisolated,让 actor
  QiniuUploader 可直接调,无需 await MainActor.run
- QiniuUploader:QNUploadManager() 在七牛 SDK 8.x 已 kQNDeprecated,改用
  initWithConfiguration: + defaultConfigurationV2

工程侧(pbxproj,Xcode UI 自动写入):
- 新 Frameworks group 容纳 Vendor/WechatSDK / Vendor/AMap 引用
- WechatOpenSDK-NoPay.xcframework:Embed & Sign(动态库)
- AMapFoundationKit / AMapLocationKit:Do Not Embed(静态 fat .framework)

BuildProject 验证:Swift 全部编译通过;剩余 AMap fat framework arch 冲突
(M Mac iOS-simulator)是工程配置选择,下个 commit 处理。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 01:03:29 +08:00

83 lines
4.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// BackGameDataHandler.swift
// ylgamehall
//
// H5 → Native handlerbackgameData — 子游戏退出并把数据回传给大厅。
// 契约:docs/H5-Native-Contract.md §3.1 18
//
// 与 msext gameController.m:691-709 等价:
// 1) 停背景音(无条件,与 stopBackground 不同 — msext 不看 type 直接 nil
// 2) AppCoordinator.shared.popSubGame(returningData: data)
// 内部 popViewController + 发 .subGameDidReturn 通知,由大厅监听后
// 回调 H5 `getWebdata` 完成反向闭环
// 3) responseCallback("backgameData") 无论 data 是否解析成功都回(msext 字面)
//
// ⚠️ 仅注册到子游戏 SubGameViewController;大厅 WebContainerViewController 不注册。
// H5 大厅页若误调 backgameData 会落空(bridge 无对应 handler → JS 端的 callback 直接卡),
// msext 同款行为 — 这是契约边界,不在原生侧兜底。
//
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// SDK 清理钩子状态(每接入新 SDK 都必须确认或新增):
//
// ✅ Phase 4.E 微信:新版 SDK2.x)无 static delegate API,逐次调用 handleOpenURL/sendAuthReq
// 时传入并被 SDK 弱引用;WeChatManager singleton 长生命周期,子游戏 pop 不析构,无需清理
// ✅ Phase 5 高德定位:`LocationService.shared.stop()`(已加,canImport 守卫,
// Xcode Embed AMapLocationKit 后激活)
// ⏳ Phase 3.B/C/D 录音 / 七牛上传:`AudioRecorder.shared.cancel()` 待 opencore-amr
// 接入后取消注释;`QiniuUploader.cancelInFlight()` 依赖 Task.cancel 传播无需显式调
// ⏳ Phase 8 Agora(若未来重启视频):`agoraKit.leaveChannel(...)`
// (目前 VideoRoomHandlers 是 stub 无需清理)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//
import Foundation
public enum BackGameDataHandler {
public static func register(on bridge: any BridgeProtocol) {
// 【18】backgameData
// 入参 data(字符串,子游戏 H5 自定义透传给大厅 getWebdata
// cb: "backgameData"
bridge.register("backgameData") { data, callback in
await MainActor.run {
// data 可能是 string / object,统一序列化为 stringmsext NSString 透传等价)。
// - 直接是 .string → 取字面
// - 其它类型 → JSON 序列化(保留对象结构传给大厅 H5)
let payload = serialize(data)
// 子游戏 push 期间挂载的 SDK 资源在 pop 前显式清理(避免 delegate 悬挂 /
// 后台任务残留),与 msext gameController.m:691-709 + cleanUpAction 等价。
AudioPlayer.shared.stopAllBackground()
// 微信 SDK 新版(2.xdelegate 由 handleOpenURL: / sendAuthReq:...:delegate:
// 逐次调用时传入并被 SDK 弱引用,无 static delegate 可清。WeChatManager
// 作为 shared singleton 长生命周期持有,子游戏 pop 不会让它析构,无悬挂回调风险。
// 旧 msext gameController.m:699 的 [WXApi setDelegate:nil] 是 1.x SDK API,新版已删除。
#if canImport(AMapLocationKit)
// msext gameController.m:2473-2478 cleanUpAction 等价
LocationService.shared.stop()
#endif
// Phase 3.C 录音 / Phase 3.B 七牛上传 清理(QiniuUploader.cancelInFlight 当前
// 依赖 Task.cancel 传播;AudioRecorder 待 opencore-amr 接入后激活清理)
// AudioRecorder.shared.cancel() // ← Phase 3.C 接入时取消注释
AppCoordinator.shared.popSubGame(returningData: payload)
}
callback?(.string("backgameData"))
}
}
private static func serialize(_ data: BridgeData?) -> String {
if let s = data?.asString { return s }
guard let data else { return "" }
let any = data.jsonObject
if let bytes = try? JSONSerialization.data(withJSONObject: any, options: [.fragmentsAllowed]),
let s = String(data: bytes, encoding: .utf8) {
return s
}
return ""
}
}