I’m trying to practice using Supabase with SwiftUI as an alternative to Firebase. I have a table set up in my Supabase database and my code is identifying this and retrieving the data, but I’m having issues displaying it in a list once it’s been retrieved.
I can print the data to the console window to show it has in fact been retrieved but the List doesn’t seem to display anything on the simulator screen.
My view model contains this code:
let client = SupabaseClient(supabaseUrl: SupabaseURL, supabaseKey: SupabaseKey)
@Published var todos: [Todo] = []
// Retrieve all todo's
func getAllTodos() {
print("Retrieving all todo's from database")
let query = client.database.from("todos")
.select()
query.execute { results in
switch results {
case let .success(response):
let todos = try? response.decoded(to: [Todo].self)
self.todos = todos!
print("Todos: \(todos)")
case let .failure(error):
print(error.localizedDescription)
}
}
}
And my ContentView contains this code:
@State private var model = ContentViewModel()
@State var title = ""
@State var description = ""
var body: some View {
VStack {
TextField("Title", text: $title)
.padding(5)
.border(Color.black)
TextField("Description", text: $description)
.padding(5)
.border(Color.black)
Button("Create Todo") {
model.createTodo(title: title, description: description)
}
.padding(10)
Button("List todo's") {
model.getAllTodos()
}
.padding(10)
List(model.todos) { todo in
Text("\(todo.title): \(todo.description)")
Text("Done: \(String(describing: todo.isDone))")
}
.refreshable {
model.getAllTodos()
}
}
.padding(20)
.onAppear {
model.getAllTodos()
}
}
If I run the simulator, and click ‘List todo’s’ once, the console shows this output:
Retrieving all todo's from database
2022-01-30 17:59:19.077191+0000 Supabase API 2[36461:1087300] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics
Todos: [Supabase_API_2.Todo(id: "56e81c25-2fbe-45da-ac57-5e0d92fdd9b4", title: "First Todo", description: "basic description", isDone: false), Supabase_API_2.Todo(id: "06b8e7bf-f990-4553-9c92-5a12a38d8e78", title: "Second todo", description: "another basic description", isDone: false)]
Retrieving all todo's from database
Todos: [Supabase_API_2.Todo(id: "56e81c25-2fbe-45da-ac57-5e0d92fdd9b4", title: "First Todo", description: "basic description", isDone: false), Supabase_API_2.Todo(id: "06b8e7bf-f990-4553-9c92-5a12a38d8e78", title: "Second todo", description: "another basic description", isDone: false)]
You can see it retrieves the todo’s when the view loads, then again when I click the ‘List todo’s’ button. So I can see it is correctly retrieving the data and storing in the ‘todos’ var, but for some reason won’t display it in the list.
Any help with this would be really appreciated!
>Solution :
Assuming ContentViewModel is an ObservableObject (which it should be), it should be annotated with @StateObject (which is the property wrapper that allows the View to hook up to the objects publisher), not @State.