我不知道如何解释......但有一种感觉,API知道如何在名称中设置字符串,但它不知道如何输入具有结构类型的属性并已设置其他值
有我的API的网址=“https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/all.json”
所以我创建了正确的模型,它采用了我需要的值。但出于某种原因,当我打印我的常量时,它会告诉我除了名称之外缺少属性。
这是我的模型:
struct SuperHero: Decodable {
let name: String?
let powerstats: PowerStats?
let appearance: Appearance?
let biography: Biography?
let work: Work?
let images: Images?
}
struct PowerStats: Decodable {
let intelligence: Int
let strength: Int
let speed: Int
let durability: Int
let power: Int
let combat: Int
}
struct Appearance: Codable {
let gender: Gender
let race: String?
let height, weight: [String]
}
enum Gender: String, Codable {
case empty = "-"
case female = "Female"
case male = "Male"
}
struct Biography: Codable {
let fullName, alterEgos: String
let aliases: [String]
let firstAppearance: String
let publisher: String?
let alignment: Alignment
}
enum Alignment: String, Codable {
case bad = "bad"
case empty = "-"
case good = "good"
case neutral = "neutral"
}
struct Work: Codable {
let occupation, base: String
}
struct Images: Decodable {
let xs: String
let sm: String
let md: String
let lg: String
}
我尝试通过我的函数获取数据:
func fetchData() {
guard let url = URL(string: url) else { return }
request(url).validate().responseJSON { (dataResponse) in
switch dataResponse.result {
case .success(let value):
guard let arrayOfItems = value as? Array<[String : Any]> else { return }
for dict in arrayOfItems {
let superHero = SuperHero(name: dict["name"] as? String,
powerstats: dict["powerstats"] as? PowerStats,
appearance: dict["appearance"] as? Appearance,
biography: dict["biography"] as? Biography,
work: dict["work"] as? Work,
images: dict["images"] as? Images)
self.superHeroes.append(superHero)
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
case.failure(let error):
print(error)
}
}
}
}
发生此错误是因为您无法将反序列化的JSON字典值强制转换为自定义结构。你必须通过调用init
这样的SuperHero
方法来创建其他结构。
因为你的结构符合Decodable
无论如何使用JSONDecoder
,只需用responseJSON
替换responseData
即可获得原始数据。
您可以将根结构中的所有成员声明为非可选
struct SuperHero: Decodable {
let name: String
let powerstats: PowerStats
let appearance: Appearance
let biography: Biography
let work: Work
let images: Images
}
并且Images
中的所有成员都可以直接解码为URL
struct Images: Decodable {
let xs: URL
let sm: URL
let md: URL
let lg: URL
}
func fetchData() {
guard let url = URL(string: url) else { return }
request(url).validate().responseData { (dataResponse) in
switch dataResponse.result {
case .success(let data):
do {
self.superHeroes = try JSONDecoder().decode([SuperHero].self, from: data)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
} catch { print(error) }
case.failure(let error):
print(error)
}
}
}
要在代码中创建子结构,您必须创建每个单个实例。这是PowerStats
的一个例子
for dict in arrayOfItems {
let pwstats = dict["powerstats"] as! [String:Int]
let powerStat = PowerStats(intelligence: pwstats["intelligence"]!,
strength: pwstats["strength"]!,
speed: pwstats["speed"]!,
durability: pwstats["durability"]!,
power: pwstats["power"]!,
combat: pwstats["combat"]!)
let superHero = SuperHero(name: dict["name"] as? String,
powerstats: powerStat, ...
请注意,大多数词典都是[String:Any]
,需要为每个值添加额外的类型。