3.F 修复:mediaTypeAudio.user 字段兼容 number 与 string

## 问题

实测 H5 调 mediaTypeAudio 传入:
  {audiourl: "http://...amr", user: 0, type: 1}

user 是 number(0),不是 string。我之前用 obj["user"]?.asString 严格
要求 string,导致解析失败 → silent return,远端语音无法播放。

## 根因

daoqi 用 `[data objectForKey:@"user"]` 后 `[NSString stringWithFormat:
@"%@", userid]` 容忍 NSNumber(ObjC `%@` 对 NSNumber 调 description
自动转 string)。新外壳走 Swift 强类型解析,丢了这个隐式兼容。

## 修复

给 BridgeData 加 `asLooseString` 扩展:
  - string → 原样
  - number → 整数样 double 转 Int 字符串(0.0 → "0"),其它走 String(d)
  - bool   → "true"/"false"
  - null/array/object → nil

mediaTypeAudio handler 把 `obj["user"]?.asString` 改为
`obj["user"]?.asLooseString`。`audiourl` 保持 asString(URL 永远是
string)。

`asLooseString` 也可供其它 H5 字段类型不严格的 handler 复用。

## 验证

BuildProject 通过 0 错误。真机重试 mediaTypeAudio 应能正确解析
user=0 / user=12345 / user="abc" 等各种 H5 传入形态。
This commit is contained in:
joywayer
2026-06-24 02:12:21 +08:00
parent c3a0ddbf8b
commit b058990862
2 changed files with 27 additions and 3 deletions
@@ -109,6 +109,27 @@ extension BridgeData {
return nil return nil
} }
/// string number Stringbool "true"/"false"
///
/// H5 mediaTypeAudio.user number
/// 0/1/userId string daoqi `[NSString stringWithFormat:@"%@",
/// data[@"user"]]` ObjC `%@` NSNumber description
///
nonisolated public var asLooseString: String? {
switch self {
case .string(let s): return s
case .number(let d):
// double Int 0.0 "0" .0
if d == d.rounded(), d.isFinite, abs(d) < Double(Int.max) {
return String(Int(d))
}
return String(d)
case .bool(let b): return b ? "true" : "false"
case .null: return nil
case .array, .object: return nil
}
}
nonisolated public var asDouble: Double? { nonisolated public var asDouble: Double? {
if case .number(let d) = self { return d } if case .number(let d) = self { return d }
return nil return nil
@@ -247,11 +247,14 @@ public enum RemoteAudioHandler {
bridge: any BridgeProtocol, bridge: any BridgeProtocol,
callback: BridgeCallback? callback: BridgeCallback?
) async { ) async {
// 1. audiourl + user daoqi // 1. audiourl + user daoqi NewRootVC.m:326-328 /
// NewRootVC.m:326-328 / gameController.m:435-437 // gameController.m:435-437H5 type daoqi
//
// user H5 number 012345 string
// asLooseString daoqi `%@` NSNumber
guard let obj = data?.asObject, guard let obj = data?.asObject,
let urlString = obj["audiourl"]?.asString, let urlString = obj["audiourl"]?.asString,
let user = obj["user"]?.asString, let user = obj["user"]?.asLooseString,
let downloadURL = URL(string: urlString) let downloadURL = URL(string: urlString)
else { else {
log.error("mediaTypeAudio: bad params \(String(describing: data), privacy: .public)") log.error("mediaTypeAudio: bad params \(String(describing: data), privacy: .public)")