需要从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]]的数组 让jsonData =尝试JSONSerialization.data(withJSONObject:jsonResponse [“ data”] as![[String:Any]])
答案 0 :(得分:2)
您只是缺少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(来自解码器: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"
}
}
答案 1 :(得分:1)
有两种选择:
let data = try JSONSerialization.data(withJSONObject: dictionary, options: [.fragmentsAllowed])
答案 2 :(得分:0)
我不知道为什么要面对这个问题,因为我已经尝试过复制粘贴您的代码。一切正常。请参考下面的代码。
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)
}