You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:11:04