Files
youle_app_ios_v2/ylgamehall/Source/Bridge/Handlers/VoicePlayingHandler.swift
T
joywayer 90a523736e 3.A/3.F 修复:voicePlaying 入参类型兼容 + mediaTypeAudio canPlay 诊断
## 发现的根因

实测日志 mediaTypeAudio 进入了 native(amrFileCodec frame=107 打印两次确认
转码运行),但缺 gameui_play_voice 触发 log → canPlay=false 被短路。
原因是 voicePlaying handler 解析 H5 入参时类型不容忍。

之前实现:
  let on = (data?.asInt ?? 0) == 1

asInt 只对 BridgeData.number case 返回值。若 H5 传 string "1"(实测确实
会传)→ asInt 返回 nil → `?? 0 = 0` → `0 == 1 = false` → 开关被关闭。

daoqi 用 ObjC `[data intValue]`(NSString/NSNumber 都能转),永远能
正确处理两种类型。

## 修复

VoicePlayingHandler:改用 asLooseString 比较 "1" 字符串,兼容 H5 传:
  - string "1"  → asLooseString → "1" → on=true ✓
  - number 1    → asLooseString → "1" → on=true ✓
  - string "0"  → asLooseString → "0" → on=false ✓
  - number 0    → asLooseString → "0" → on=false ✓
  - 其它       → on=false(保守拒绝)

同时加 log.debug 记录每次 voicePlaying 调用的 raw + 解析后值,便于后续
诊断 H5 业务行为。

## 诊断辅助

RemoteAudioHandler.handleMediaTypeAudio 增加 log.debug:
  mediaTypeAudio user=X transcoded=Y canPlay=Z

让真机测试能直接看到 canPlay 实际值,避免再次盲猜。

## 验证

BuildProject 通过 0 错误。真机重试 mediaTypeAudio 应能看到:
  voicePlaying H5 → raw=1 → isEnabled=true
  mediaTypeAudio user=0 transcoded=true canPlay=true
  gameui_play_voice user=0
2026-06-27 12:07:20 +08:00

48 lines
2.0 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.
//
// VoicePlayingHandler.swift
// ylgamehall
//
// H5 → Native handlervoicePlaying — 远端语音播放总开关
// 契约:docs/H5-Native-Contract.md §3.1 6
//
// 开关位由 actor VoiceCenter 持有,跨 handler 共享。Phase 3.F
// mediaTypeAudio handler 读 isEnabled 决定是否播放。
//
import Foundation
import os.log
/// 远端语音播放总开关(actor 隔离,跨 bridge handler 安全共享)。
///
/// 默认值 `true` 对齐 daoqi NewRootVC.m:255 / gameController.m:343 viewDidLoad
/// 早期 `canbofang=YES` 行为(ObjC BOOL 默认是 NO,但 daoqi 在 VC init 时主动
/// set YES)。
public actor VoiceCenter {
public static let shared = VoiceCenter()
public private(set) var isEnabled: Bool = true
public func setEnabled(_ on: Bool) { isEnabled = on }
}
public enum VoicePlayingHandler {
nonisolated private static let log = Logger(subsystem: "ylgamehall", category: "VoicePlaying")
public static func register(on bridge: any BridgeProtocol) {
// 【6】voicePlaying
// 入参 int 1=允许 / 其它=静默
// cb"voicePlaying"(字面与 handler 名相同,不是 "Response from voicePlaying"
bridge.register("voicePlaying") { data, callback in
// 兼容 H5 传 number 或 string"1" / 1 / 0 / "0")。原 asInt 实现遇到
// string 类型会返回 nil,导致 H5 调 voicePlaying("1") 时被当作 0 关闭开关。
let raw = data?.asLooseString ?? "<nil>"
let on = raw == "1"
Task { await VoiceCenter.shared.setEnabled(on) }
log.debug("voicePlaying H5 → raw=\(raw, privacy: .public) → isEnabled=\(on, privacy: .public)")
// 注意回包字面是 "voicePlaying",不是 "Response from voicePlaying"。
// 与其它 handler 的 "Response from XXX" 模式不一致是原项目历史包袱
// daoqi/msext gameController.m:573、NewRootVC.m:451 都是 responseCallback(@"voicePlaying")
callback?(.string("voicePlaying"))
}
}
}