[英]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.