Just make your name property optional, create a custom initializer to your structure that takes a dictionary and use its first key to initialise your name property:
enum ParseError: Error {
case noKeyFound
}
struct Strain: Codable {
let name: String!
let id: Int
let race: String
let flavors: [String]
let effects: [String: [String]]
init(dictionary: [String: Strain]) throws {
guard
let key = dictionary.keys.first,
let strain = dictionary[key] else { throw ParseError.noKeyFound }
name = key
id = strain.id
race = strain.race
flavors = strain.flavors
effects = strain.effects
}
}
do {
let strain = try Strain(dictionary: JSONDecoder().decode([String:Strain].self, from: data))
print(strain) // Strain(name: Afpak, id: 1, race: "hybrid", flavors: ["Earthy", "Chemical", "Pine"], effects: ["positive": ["Relaxed", "Hungry", "Happy", "Sleepy"], "negative": ["Dizzy"], "medical": ["Depression", "Insomnia", "Pain", "Stress", "Lack of Appetite"]])
} catch {
print(error)
}