[英]Create Object from JSON Object in Swift 5
需要从 JSON 对象创建对象
来自 API 的 JSON 响应
{
"id": 1,
"name": "Cricket",
"slug": "cricket",
"banner_image": "https://cricket.jpg",
"icons": {
"green": "http://localhost:8000/sport_icon_cricket_green.png",
"grey": "http://localhost:8000/sport_icon_cricket_gray.png",
"white": "http://localhost:8000/sport_icon_cricket_white.png",
"black": "http://localhost:8000/sport_icon_cricket_black.png"
}
},
{
"id": 2,
"name": "Baseball",
"slug": "baseball",
"banner_image": "https://baseball.jpg",
"icons": {
"green": "http://localhost:8000/sport_icon_baseball_green.png",
"grey": "http://localhost:8000/sport_icon_baseball_gray.png",
"white": "http://localhost:8000/sport_icon_baseball_white.png",
"black": "http://localhost:8000/sport_icon_baseball_black.png"
}
},
我创建了如下struct
以下链接
struct ObjSportsList:Codable
struct ObjSportsList:Codable { // Error on this line -> Error : Type 'ObjSportsList' does not conform to protocol 'Decodable'
var id:Int
var name:String
var slug:String
var icons:ObjSportsIcon
}
struct ObjSportsIcon {
var green:String
var grey:String
var white:String
var black:String
}
像这样解码
let decoderdec = JSONDecoder()
decoderdec.keyDecodingStrategy = .convertFromSnakeCase
// 2. Create Data from Response
let jsonData = try JSONSerialization.data(withJSONObject: jsonResponse["data"] as! [[String:Any]])
// 3 Convert Data to Object (Array) if don't user array then only pass ObjCountry.self
self.arrSports.removeAll()
self.arrSports = try decoderdec.decode([ObjSportsList].self, from: jsonData)
解码行上的错误:无法将“[ObjSportsList]”类型的值分配给“[[String : Any]]”类型
更新
// 错误 2.从响应创建数据// 这是 [[String:Any]] 的数组 let jsonData = try JSONSerialization.data(withJSONObject: jsonResponse["data"] as! [[String:Any]])
您只是缺少 ObjSportsIcon 类的 Codable 实现。
struct ObjSportsList : Codable {
var id:Int
var name:String
var slug:String
var icons:ObjSportsIcon
}
struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String
}
或者您可以使用以下代码使其正确:
public struct ObjSportsList : Codable {
var id:Int
var name:String
var slug:String
var icons:ObjSportsIcon
public init(id: Int, name: String, slug: String, icons: ObjSportsIcon) {
self.id = id
self.name = name
self.slug = slug
self.icons = icons
}
public enum CodingKeys: String, CodingKey {
case id
case name
case slug
case icons
}
}
public struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String
public init(green: String, grey: String, white: String, black: String) {
self.green = green
self.grey = grey
self.white = white
self.black = black
}
public enum CodingKeys: String, CodingKey {
case green
case grey
case white
case black
}
}
更改以下代码行以解决您的第二个错误:
self.arrSports = try decoderdec.decode(Array<ObjSportsList>.self, from: jsonData)
我找到了我的错误和第二个错误的解决方案
旧代码var arrSports:[[String:Any]] = []
新代码var arrSports:[ObjSportsList] = []
您必须实现 init(fromdecoder: Decoder) 方法才能实现相同的目的。 注意:您必须为每个属性设置默认值
struct ObjSportsIcon : Codable {
var green:String
var grey:String
var white:String
var black:String
var pink:String
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.green = try container.decodeIfPresent(String.self, forKey: .green) ?? "green"
self.grey = try container.decodeIfPresent(String.self, forKey: .grey) ?? "grey"
self.white = try container.decodeIfPresent(String.self, forKey: .white) ?? "white"
self.black = try container.decodeIfPresent(String.self, forKey: .black) ?? "black"
self.pink = try container.decodeIfPresent(String.self, forKey: .pink) ?? "pink"
}
}
那么有两种选择:
let data = try JSONSerialization.data(withJSONObject: dictionary, options: [.fragmentsAllowed])
我不知道为什么会遇到这个问题,因为我已经尝试过复制粘贴您的代码。 一切正常。 请参考以下代码。
struct ObjSportsList : Decodable {
var id:String
var name:String
var slug:String
var icons:ObjSportsIcon
}
struct ObjSportsIcon : Decodable {
var green:String
var grey:String
var white:String
var black:String
}
let decoderdec = JSONDecoder()
decoderdec.keyDecodingStrategy = .convertFromSnakeCase
let aryTemp = [[
"id": "1",
"name": "Cricket",
"slug": "cricket",
"banner_image": "https://cricket.jpg",
"icons": [
"green": "http://localhost:8000/sport_icon_cricket_green.png",
"grey": "http://localhost:8000/sport_icon_cricket_gray.png",
"white": "http://localhost:8000/sport_icon_cricket_white.png",
"black": "http://localhost:8000/sport_icon_cricket_black.png"
]],[
"id": "2",
"name": "Baseball",
"slug": "baseball",
"banner_image": "https://baseball.jpg",
"icons": [
"green": "http://localhost:8000/sport_icon_baseball_green.png",
"grey": "http://localhost:8000/sport_icon_baseball_gray.png",
"white": "http://localhost:8000/sport_icon_baseball_white.png",
"black": "http://localhost:8000/sport_icon_baseball_black.png"
]
]]
do {
let jsonData = try JSONSerialization.data(withJSONObject: aryTemp)
let arrSports = try decoderdec.decode([ObjSportsList].self, from: jsonData)
print(arrSports)
} catch let error {
print(error)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.