Home > database >  @AppStorage not updating view
@AppStorage not updating view

Time:04-27

I have the following reproduced example in Swift/SwiftUI.

Intended Functionality: List of numbers, where upon deletion of any number, the numbers update and reorganize so that they are in consecutive order.

Example: Suppose we have numbers 1, 2, 3, 4 in a list. When we delete number 2, the list should become 1, 2, 3 instead of staying like 1, 3, 4.

Problem: When @State is used to hold the array of numbers, the code works as expected. However, when an array in @AppStorage is used to hold the array, the view does not seem to update/change the numbers.

So, why can't I use the @AppStorage approach, and how can I fix this?

I know the code looks like a lot, but you can mostly ignore it if you just read the comments. It's just a body with a couple of functions, nothing crazy.

class MyObj: Codable, Identifiable {      //SIMPLE OBJECT TO HOLD A NUMBER
    init(num: Int) {
        self.num = num
    }
    
    var id: UUID = UUID()
    var num: Int
}

struct test2: View {
    
    @State var array: [MyObj] = []                             //USING THIS (@State) WORKS
    //AppStorage("array") var array: [MyObj] = []              //USING THIS (@AppStorage) DOESN’T UPDATE NUMBERS
    
    func minimizeNums() {
        for i in 0..<array.count {         //MAKES NUMBERS IN ORDER/CONSECUTIVE
            array[i].num = i
        }
    }
    
    var body: some View {
        VStack {
            Button("add number object") {
                array.append(MyObj(num: array.count))
            }
            
            List {
                ForEach(array) { obj in
                    Text(String(obj.num))
                }
                .onDelete(perform: { index in         
                    array.remove(atOffsets: index)      //REMOVES NUMBER OBJECT FROM LIST
                    minimizeNums()                //MAKES THE REMAINING OBJECT'S NUMBERS CONSECUTIVE
                })
            }
        }
    }
}

Important: I used the extension from this accepted answer in order to store arrays in @AppStorage. I assume this extension may be contributing to the problem, but I'm not sure how!

CodePudding user response:

This is failing, because you are using a class for your model MyObj. There are multiple reasons for using structs with SwiftUI. Please read Blog entry or any other tutorial or documentation.

[TLDR]: Don´t use classes use structs.

Changing MyObj to:

struct MyObj: Codable, Identifiable {     
    init(num: Int) {
        self.num = num
    }
    
    var id: UUID = UUID()
    var num: Int
}

should work.

  • Related