SignalR-Client-Swift接收数据解析后值为nil问题求助
SignalR-Client-Swift 解析数据全为nil问题排查与修复
使用SignalR-Client-Swift接收数据时,调试日志可见接收数据,但解析后所有值均为nil,无法正常解析。相关代码及模型如下:
接收逻辑代码:
self.chatHubConnection!.on(method: "SendMessage", callback: { (payload: ArgumentExtractor?) in let response = try! payload?.getArgument(type: SignalR?.self) print("Response: \(response!)") })
数据模型代码:
struct SignalR: Codable { let type: Int? let target: String? let arguments: [Argument]? } struct Argument: Codable { let id: ID enum CodingKeys: String, CodingKey { case id = "_id" } } struct ID: Codable { let timestamp, machine, pid, increment: Int let creationTime: Date }
修复方案
1. 修正getArgument的类型参数
getArgument(type:)无需传入可选类型,直接传递SignalR.self即可。原代码中SignalR?.self会让库尝试解析可选容器,而非目标结构体本身,导致解析失败。同时替换try!为do-catch避免崩溃:
self.chatHubConnection!.on(method: "SendMessage", callback: { (payload: ArgumentExtractor?) in guard let payload = payload else { return } do { let response = try payload.getArgument(type: SignalR.self) print("Response: \(response)") } catch { print("解析失败: \(error.localizedDescription)") } })
2. 处理Date类型的解析兼容性
ID结构体中的creationTime为Date类型,默认JSONDecoder的日期策略可能与SignalR返回的格式不匹配(如返回字符串格式日期或毫秒时间戳)。需自定义解码策略:
extension JSONDecoder { static var signalRDecoder: JSONDecoder { let decoder = JSONDecoder() // 根据实际返回格式选择,示例为ISO8601格式 decoder.dateDecodingStrategy = .iso8601 // 若返回毫秒时间戳,替换为: // decoder.dateDecodingStrategy = .millisecondsSince1970 return decoder } }
解析时指定自定义解码器:
let response = try payload.getArgument(type: SignalR.self, decoder: .signalRDecoder)
3. 验证JSON结构与模型的匹配度
确认SignalR返回的JSON结构与模型完全对应:
- 确保
type、target、arguments的键名大小写完全一致(JSON大小写敏感) - 检查
arguments数组中每个元素是否包含_id字段,且_id的子字段与ID结构体完全匹配
若返回JSON结构与模型存在差异(如arguments是单个对象而非数组),需同步调整模型结构。
内容的提问来源于stack exchange,提问作者Edward Tattsyrup
相关产品推荐
相关产品推荐

