通过WCF服务从SQL Server取数据时Swift JSON解码报错求助
排查Swift调用WCF服务JSON解码keyNotFound错误
这个错误很常见,核心原因是你定义的student结构体和WCF返回的JSON结构不匹配,咱们一步步来解决:
第一步:先看WCF返回的真实JSON内容
你现在不知道服务到底返回了什么,所以首先要把原始响应打印出来。修改你的dataTask代码,在拿到data后先转成字符串输出:
URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else{ print("there is no data") return } // 新增:打印原始JSON字符串 if let rawJson = String(data: data, encoding: .utf8) { print("原始返回JSON:\n\(rawJson)") } do{ let students = try JSONDecoder().decode(student.self, from: data) print(students) } catch{ print("conversion error") print(error) } }.resume()
运行后看控制台输出,你会发现问题所在——比如常见的情况有三种:
情况1:WCF返回的JSON被包裹在根节点里
WCF默认会把返回结果包裹在和方法名对应的节点中,比如你的方法是GetData,返回的JSON可能是这样的:
{"GetDataResult":{"id":1,"name":"张三"}}
这时候你直接解码student.self肯定找不到id,因为id是在GetDataResult这个子节点里的。解决办法是定义一个外层结构体来匹配:
// 新增外层响应结构体 struct GetDataResponse: Decodable { let studentData: student // 用CodingKeys映射WCF返回的键名 enum CodingKeys: String, CodingKey { case studentData = "GetDataResult" } } // 解码时改成: let response = try JSONDecoder().decode(GetDataResponse.self, from: data) print(response.studentData)
情况2:JSON键名大小写不匹配
C#(WCF的开发语言)里的属性通常是PascalCase(首字母大写),比如Id、Name,而你的Swift结构体用的是camelCase(首字母小写)的id、name,这时候JSON里的键是"Id"而不是"id",自然会提示找不到key。解决办法有两种:
- 方法一:用
CodingKeys手动映射键名:
public struct student: Decodable { let id:Int let name:String enum CodingKeys: String, CodingKey { case id = "Id" case name = "Name" } }
- 方法二:让解码器自动处理大小写转换(适合大量属性的情况):
let decoder = JSONDecoder() // 自定义策略:把JSON里的PascalCase转成Swift的camelCase decoder.keyDecodingStrategy = .custom { codingKeys in let key = codingKeys.last!.stringValue guard key.count > 0 else { return codingKeys.last! } let firstChar = key.prefix(1).lowercased() let rest = key.dropFirst() return CodingKey(stringValue: firstChar + rest)! } // 然后用这个解码器解码 let students = try decoder.decode(student.self, from: data)
情况3:WCF返回的是数组而非单个对象
如果你的GetData方法返回的是多个student的集合,那JSON会是数组格式:
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]
这时候你应该解码数组类型[student].self,而不是单个student.self:
let students = try JSONDecoder().decode([student].self, from: data)
总结
先打印原始JSON确认结构,再根据实际返回调整你的解码逻辑——这是解决JSON解码错误最直接有效的办法。
内容的提问来源于stack exchange,提问作者saqib
相关产品推荐
相关产品推荐

