繁体   English   中英

SwiftUI - 如何使用动态密钥访问 API 响应数据?

[英]SwiftUI - How can I access API response data with a dynamic key?

我在这里先向您的帮助表示感谢。
我第一次在 SwiftUI 中处理 API 调用。 我通过使用 structs/decodable 取回了一部分数据。 我使用枚举来访问每一层。 但是,我正在使用的 API 使用当前日期作为键,并且我正在努力在不使用字符串文字的情况下访问该层数据。 有任何想法吗?
这就是我所拥有的。

struct NEObjects: Decodable {
    let fromToday: [NEObject]
    
    enum CodingKeys: String, CodingKey {
        case  fromToday = "2021-02-16"
    }
}

我将当前日期存储在用户默认值中。 但是如果我做类似的事情

let date = UserDefaults.standard.string(forKey: "current_date")
case fromToday = date

然后我收到一条错误消息“枚举大小写的原始值必须是文字”
我不确定我还能如何访问这一层,因为我是 swiftUI 的新手。
以下是完整数据 model 供参考:

import Foundation

let date = UserDefaults.standard.string(forKey: "current_date")

struct NEOData: Decodable  {
    let elementCount: Int
    let neObjects: NEObjects
    
    enum CodingKeys: String, CodingKey {
        case elementCount = "element_count"
        case neObjects = "near_earth_objects"
    }
}

struct NEObjects: Decodable {
    let fromToday: [NEObject]
    
    enum CodingKeys: String, CodingKey {
        case  fromToday = "2021-02-15"
    }
}

struct NEObject: Decodable {
    let name: String
    let absoluteMagnitude: Double
    let diameter: Diameter
    let isHazardous: Bool
    let closeApproachData: [CloseApproachData]
    let isSentry: Bool
    
    enum CodingKeys: String, CodingKey {
        case name = "name"
        case absoluteMagnitude = "absolute_magnitude_h"
        case diameter = "estimated_diameter"
        case isHazardous = "is_potentially_hazardous_asteroid"
        case closeApproachData = "close_approach_data"
        case isSentry = "is_sentry_object"
    }
}

struct Diameter: Decodable {
    let kilometers: Kilometers
    let meters: Meters
    let miles: Miles
    let feet: Feet
}

struct CloseApproachData: Decodable {
    let velocity: Velocity
    let missDistance: MissDistance
    let date: String
    
    enum CodingKeys: String, CodingKey {
        case velocity = "relative_velocity"
        case missDistance = "miss_distance"
        case date = "close_approach_date"
    }
}

struct Velocity: Decodable {
    let mph: String
    let kph: String
    
    enum CodingKeys: String, CodingKey {
        case mph = "miles_per_hour"
        case kph = "kilometers_per_hour"
    }
}

struct MissDistance: Decodable {
    let kilometers: String
    let miles: String
}

struct Kilometers: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Meters: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Miles: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Feet: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

没有看到 JSON,我只是猜测你希望你的NEObjects结构看起来像这样:

struct NEObjects: Decodable {
    let objectsByDay : [String : NEObject]    
}

这将解码 JSON,如下所示:

{
   "2021-02-16" : [
       { ... a bunch of your custom objects ... }
   ]
}

最终结果:我有一个不必要的额外层。 在执行约翰的建议后。

Model

import Foundation

struct NEOData: Decodable  {
    let elementCount: Int
    let neObjects: [String : [NEObject]]
    
    enum CodingKeys: String, CodingKey {
        case elementCount = "element_count"
        case neObjects = "near_earth_objects"
    }
}

struct NEObject: Decodable {
    let name: String
    let absoluteMagnitude: Double
    let diameter: Diameter
    let isHazardous: Bool
    let closeApproachData: [CloseApproachData]
    let isSentry: Bool
    
    enum CodingKeys: String, CodingKey {
        case name = "name"
        case absoluteMagnitude = "absolute_magnitude_h"
        case diameter = "estimated_diameter"
        case isHazardous = "is_potentially_hazardous_asteroid"
        case closeApproachData = "close_approach_data"
        case isSentry = "is_sentry_object"
    }
}

struct Diameter: Decodable {
    let kilometers: Kilometers
    let meters: Meters
    let miles: Miles
    let feet: Feet
}

struct CloseApproachData: Decodable {
    let velocity: Velocity
    let missDistance: MissDistance
    let date: String
    
    enum CodingKeys: String, CodingKey {
        case velocity = "relative_velocity"
        case missDistance = "miss_distance"
        case date = "close_approach_date"
    }
}

struct Velocity: Decodable {
    let mph: String
    let kph: String
    
    enum CodingKeys: String, CodingKey {
        case mph = "miles_per_hour"
        case kph = "kilometers_per_hour"
    }
}

struct MissDistance: Decodable {
    let kilometers: String
    let miles: String
}

struct Kilometers: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Meters: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Miles: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

struct Feet: Decodable {
    let min: Double
    let max: Double
    
    enum CodingKeys: String, CodingKey {
        case min = "estimated_diameter_min"
        case max = "estimated_diameter_max"
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM