First of all, i am very sorry for the noob question, but i just cant seem to figure this out.
I am very new to coding and just started to get my feet wet with SwiftUI, following a few courses and started to dabble in trying to create some basic apps.
I am currently working on an app that does an API call and displays the data.
My issue is, im trying to put the decoded data into an array, it sounds so simple and I think i am missing something very easy, but for the life of me I cant seem to figure it out.
Below is the codable struct I have
struct Drinks: Codable, Identifiable {
let id = UUID()
let strDrink : String
let strInstructions: String
let strDrinkThumb: String?
let strIngredient1: String?
let strIngredient2: String?
let strIngredient3: String?
let strIngredient4: String?
let strIngredient5: String?
}
I want to put the ingredients into an Array so I can go through them in lists etc
import SwiftUI
struct IngredientView: View {
let drink : Drinks
let ingredientArray : [String] = [] // I want to append the ingredients here
var body: some View {
GroupBox() {
DisclosureGroup("Drink Ingredience") {
ForEach(0..<3) { item in
Divider().padding(.vertical, 2)
HStack {
Group {
// To use the array here
}
.font(Font.system(.body).bold())
Spacer(minLength: 25)
}
}
}
}
}
}
Again, sorry for the noob question that probably has a simple answer, but worth a shot asking :D
Thanks!
CodePudding user response:
change you struct to
struct Drink: Codable, Identifiable {
let id = UUID()
let strDrink : String
let strInstructions: String
let strDrinkThumb: String?
let strIngredients: [String] = []
}
wherever you want to loop through ingredients you can use drink.strIngredients
array
CodePudding user response:
you could use this approach to get all your ingredients into an array and use it in Lists.
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var drinkList = [Drink]()
var body: some View {
List {
ForEach(drinkList) { drink in
VStack {
Text(drink.strDrink).foregroundColor(.blue)
Text(drink.strInstructions)
ForEach(drink.allIngredients()) { ingr in
HStack {
Text(ingr.name).foregroundColor(.red)
Text(ingr.amount).foregroundColor(.black)
}
}
}
}
}
.task {
let theResponse: ApiResponse? = await getData(from: "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita")
if let response = theResponse {
drinkList = response.drinks
}
}
}
func getData<T: Decodable>(from urlString: String) async -> T? {
guard let url = URL(string: urlString) else {
print(URLError(.badURL))
return nil // <-- todo, deal with errors
}
do {
let (data, response) = try await URLSession.shared.data(for: URLRequest(url: url))
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
print(URLError(.badServerResponse))
return nil // <-- todo, deal with errors
}
return try JSONDecoder().decode(T.self, from: data)
}
catch {
print("---> error: \(error)")
return nil // <-- todo, deal with errors
}
}
}
struct ApiResponse: Decodable {
var drinks: [Drink]
}
struct Drink: Decodable, Identifiable {
let id = UUID()
let idDrink: String
let strDrink: String
let strDrinkThumb: String
let strAlcoholic: String
let strGlass: String
let strInstructions: String
let strIngredient1: String?
let strIngredient2: String?
let strIngredient3: String?
let strIngredient4: String?
let strIngredient5: String?
let strIngredient6: String?
let strIngredient7: String?
let strIngredient8: String?
let strIngredient9: String?
let strIngredient10: String?
var strMeasure1: String?
var strMeasure2: String?
var strMeasure3: String?
var strMeasure4: String?
var strMeasure5: String?
var strMeasure6: String?
var strMeasure7: String?
var strMeasure8: String?
var strMeasure9: String?
var strMeasure10: String?
// --- here adjust to your needs
func allIngredients() -> [Ingredient] {
var ingrediends = [Ingredient]()
if let ingr = strIngredient1 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure1 ?? "")) }
if let ingr = strIngredient2 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure2 ?? "")) }
if let ingr = strIngredient3 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure3 ?? "")) }
if let ingr = strIngredient4 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure4 ?? "")) }
if let ingr = strIngredient5 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure5 ?? "")) }
if let ingr = strIngredient6 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure6 ?? "")) }
if let ingr = strIngredient7 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure7 ?? "")) }
if let ingr = strIngredient8 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure8 ?? "")) }
if let ingr = strIngredient9 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure9 ?? "")) }
if let ingr = strIngredient10 { ingrediends.append(Ingredient(name: ingr, amount: strMeasure10 ?? "")) }
return ingrediends
}
}
struct Ingredient: Identifiable {
let id = UUID()
var name: String
var amount: String
}