json - API 可以不理解我的属性类型吗?

标签 json swift xcode api alamofire

我不知道怎么解释......但是感觉API知道如何设置名称中的字符串,但它不知道如何输入结构类型的属性并设置其他值

我的 API 有一个 url = "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],这需要为每个值进行额外的类型转换。

关于json - API 可以不理解我的属性类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55647550/

相关文章:

java - 如何使用 Jackson 反序列化动态 JSON 字段?

ios - 如何使用 Swift 在 Firebase 中查询最近的用户?

ios - 专门针对纵向 3.5 英寸 (iPhone 4S) Xcode 6 的尺寸等级?

xcode - CABasic 动画翻译不工作

ios - swift 中的按钮旋转动画制作类似的动画

JSON 解析错误 : Can not construct instance of java. time.LocalDate: 没有从字符串值反序列化的字符串参数构造函数/工厂方法

html - Json 服务以 HTML 形式返回

javascript - 数数没有。 json 对象中的条目数在多个键中具有特定值

ios - 将 CURL 转换为 Swift

ios - 动画自定义按钮 iOS Swift