Home > other >  Creating an array from stuct data SwiftUI
Creating an array from stuct data SwiftUI

Time:12-15

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
}
  • Related