iOS Foundations (SwiftUI) M2L12

Hello!

Does it work if I don’t change the Recipe struct to class, but make a method which can modify the id property of the Recipe struct?

m2l12

Hi @takipeti90

Welcome to the community.

As you have discovered the current code that populates the UUID does not work when you change the class to a struct.

A struct is a “Value” type and a class is a “Reference” type. So you need to change the way the for loop operates to generate an index so that you can index the array and assign the UUID()

For example you would use something like:

for index in 0...<recipeData.count {
    recipeDate[index].id = UUID()
}

Note that in order to change the contents of recipeData it will need to be a var rather than a let since a let is a constant and cannot be changed.

Hope that helps.

Thank you for the answer!

I found this page about classes and structures:
https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes

If I understand correctly, it is better to use struct for the Recipe model since it is always “risky” if the model is reference type.

I also read about mutating func, it can be used to set the id of a struct too.

struct PizzaJSON: Identifiable, Decodable {
    
    var id:UUID?
    var name:String
    var toppings:[String]
    
    mutating func setID(uuid: UUID) {
        id = uuid
    }
}


// MARK: Solution with mutating func
var pizzaData = try decoder.decode([PizzaJSON].self, from: data)

for index in 0..<pizzaData.count {
// Set a unique ID for each pizza in the pizzaData array
    pizzaData[index].setID(uuid: UUID())
 }

What I don’t understand is that why I couldn’t use for loop like this:

for p in pizzaData {
    // Set a unique ID for each pizza in the pizzaData array
    p.setID(uuid: UUID())
}

I got this error message:
Cannot use mutating member on immutable value: ‘p’ is a ‘let’ constant

Because the control variable in for loop is by default a let. You can declare it as a var instead:

for var p in pizzaData {
...
}

But you can also just assign the id when the struct is created:

struct PizzaJSON: Identifiable, Decodable {
    let id = UUID()
    //...other properties
}