我在使用Swift 4解码功能解码JSON响应方面遇到了问题。 我有主要构造,它有一个内部构造var hr_employees:[Employee]? = []。问题是JSON没有映射'var hr_employees:[Employee]? = []。
我得到三个根值response_status,access_level,session_token的正确值。
////////////结构代码////////////////////////
struct EmployeeData: Codable {
var response_status:Int=0
var access_level:Int=0
var session_token:String=""
var hr_employees: [Employee]? = []
}
private enum CodingKeys: String, CodingKey {
case response_status="response_status"
case access_level="access_level"
case session_token="session_token"
case hr_employees="hr_employees"
}
init() {
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
response_status = try values.decode(Int.self, forKey: .response_status)
do{
session_token = try values.decode(String.self, forKey: .session_token)
}catch {
print( "No value associated with key title (\"session_token\").")
}
do{
access_level = try values.decode(Int.self, forKey: .access_level)
}
catch {
print( "No value associated with key access_level ")
}
}
/////////////////内部结构///////////////////////
struct Employee: Codable {
var userId:Int=0
var nameFirst:String=""
var nameLast:String=""
var position:String=""
var company:String=""
var supervisor:String=""
var assistant:String=""
var phone:String=""
var email:String=""
var address:String=""
var gender:String=""
var age:Int=0
var nationality:String=""
var firstLanguage:String=""
var inFieldOfView:String = "0"
var photo:String="user-default"
var status:String="3"
}
////////////以下是JSON //////////////////////
{
"response_status":1
,"access_level":2
,"hr_employees":[
{
"user_id":4226
,"name_last":"Sampe"
,"name_first":"Frederica"
,"position":"Systems Maint"
,"phone":"123456"
,"email":"omega@demo.mobile"
,"address":"00100 Helsinki 1"
,"age":67
,"company":"Omega Enterprise"
}
,{
"user_id":5656
,"name_last":"Aalto"
,"name_first":"Antero"
,"position":"Programming Methodology and Languages Researcher"
,"supervisor":"Mayo Georgia"
,"phone":"123456"
,"email":"omega@demo.mobile"
,"address":"00100 Finland "
,"age":51
,"company":"Omega Fire Related Equipment"
}
]
}
答案 0 :(得分:1)
一个问题是JSON中的内容与您的Employee定义不匹配。例如,nameFirst
不存在且name_first
是。
另一个是您有init(from:)
的自定义实现,它永远不会获取hr_employees
值!
答案 1 :(得分:0)
您需要改进的一些事项:
Struct
以利用Codable
协议的自动化功能。CodingKeys
枚举
Struct
内部)init(from:Decoder)
根据您给定的JSON示例,您可以简单地执行以下操作
但是...... 请注意,这不是为了提供默认值。即如果json中缺少某个键,例如status
,则status
结构中的参数Employee
将为nil
,而不是默认值{{ 1}}。
"3"
struct EmployeeData: Codable {
var responseStatus: Int
var accessLevel: Int
/*
sessionToken is optional because as per your JSON
it seems it not always available
*/
var sessionToken: String?
var hrEmployees: [Employee]
/*
CodingKeys is inside the struct
It's used if the JSON key names are different than
the ones you plan to use.
i.e. JSON has keys in snake_case but we want camelCase
*/
enum CodingKeys: String, CodingKey {
case responseStatus = "response_status"
case accessLevel = "access_level"
case sessionToken = "session_token"
case hrEmployees = "hr_employees"
}
}
检查:
struct Employee: Codable {
var userId: Int
var nameFirst: String
var nameLast: String
var position: String
var company: String
var supervisor: String?
var assistant: String?
var phone: String
var email: String
var address: String
var gender: String?
var age: Int
var nationality: String?
var firstLanguage: String?
var inFieldOfView: String?
var photo: String?
var status: String?
enum CodingKeys: String, CodingKey {
case userId = "user_id"
case nameFirst = "name_first"
case nameLast = "name_last"
case firstLanguage = "first_language"
case inFieldOfView = "in_field_of_view"
/*
Keys names that are same in json as well as in your
model need not have a raw string value
but must be defined if it's to be encoded/decoded
from the json else it can be omitted and a default
value will be required which won't affect the encoding
or decoding process
*/
case position
case company
case supervisor
case assistant
case phone
case email
case address
case gender
case age
case nationality
case photo
case status
}
}
如果你想要do {
let employeeData = try JSONDecoder().decode(EmployeeData.self,
from: jsonAsData)
print(employeeData)
}
catch {
/*
If it comes here then debug, it's most probably nil keys
meaning you need more optional parameters in your struct
*/
print(error)
}
中的默认值,而上面的例子对你来说是一个破坏者,那么请检查以下答案: