0

In the following example I am saving a String with @AppStorage:

struct ContentView: View {
    @AppStorage("text") private var text = ""

    var body: some View {
        Button("Append text: \(text)") {
            text.append("APPEND")
        }
    }
}

But I want to save a unique String array, something like this:

@AppStorage("text") @State private var customer = [CustomerId]()

//

struct CustomerId: Identifiable {
let id = UUID()
var number: String
init(_ number: String) {
    self.number = number
}

//

Button {
    customer
        .append(CustomerId("New Id"))
}
Nikolass
  • 103
  • 1
  • 8
  • 1
    What is the difference to your (accepted!) [previous question](https://stackoverflow.com/questions/70303055/save-string-array-with-appstorage) except it's not a string array, it's an array of a custom object? – vadian Dec 11 '21 at 15:28
  • I am working with `@State` and `[CustomerId]()`, previous one is not working for me :/ – Nikolass Dec 11 '21 at 15:29

1 Answers1

0

It's highly recommended to move the entire code to modify the model into an extra class called view model.

  • The @AppStorage property wrapper reads and writes a JSON string.
  • The @Published property wrapper updates the view.
  • In the init method the saved JSON string is decoded to [CustomerId].
  • The method appendCustomer appends the items, encodes the array to JSON and writes it to disk.

class ViewModel : ObservableObject {
    @AppStorage("text") var text = ""
    
    @Published var customer = [CustomerId]()
    
    init() {
        customer = (try? JSONDecoder().decode([CustomerId].self, from: Data(text.utf8))) ?? []
    }
    
    func appendCustomer(_ sustomerId : CustomerId) {
        customer.append(sustomerId)
        guard let data = try? JSONEncoder().encode(customer),
        let string = String(data: data, encoding: .utf8) else { return }
        text = string
    }
}

struct ContentView : View {
    @StateObject private var model = ViewModel()
    @State private var counter = 0
    
    var body: some View {
        VStack{
            ForEach(model.customer) { item in
                Text(item.number)
            }
            Button("Append text: New Id \(counter)") {
                model.appendCustomer(CustomerId(number: "New Id \(counter)"))
                counter += 1
            }
        }
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361