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:
@@ -109,6 +109,27 @@ extension BridgeData {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 宽松字符串:string 保持原样、number 自动转 String、bool 转 "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-437;H5 实测也会带 type 字段但 daoqi 注释掉、不用)。
|
||||||
|
//
|
||||||
|
// ⚠️ user 字段在 H5 实测中是 number(如 0、12345),不是 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)")
|
||||||
|
|||||||
Reference in New Issue
Block a user