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 的新手。
完整的数据模型供参考:
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 ... }
]
}
最终结果:我有一个不必要的额外层。执行约翰的建议后。
型号
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"
}
}
提前感谢您的帮助。
我第一次在 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 的新手。
完整的数据模型供参考:
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 ... }
]
}
最终结果:我有一个不必要的额外层。执行约翰的建议后。
型号
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"
}
}