Swift UI update


#1

Добрый день!

Никак не могу разобраться с обновлением UI, прошу помощи. В реальном проекте данные приходят по вебсокету (и там устанавливаю переменные через DispatchQueue.main.async {}). Для понимания накидал примерный код, как все устроено. При нажатии кнопки, ничего не обновляется, в чем проблема?

ps. Реальный проект немного сложнее, не могу использовать struct вместо class.

import SwiftUI

class DataBase: ObservableObject {
    
    @Published var data: [MyData]
    @Published var users: [User]
    
    init(data: [MyData], users: [User]) {
        self.data = data
        self.users = users
    }
}

class MyData: ObservableObject, Identifiable {
    
    @Published var type: String
    @Published var array: [Double]
    
    init(type: String, array: [Double]) {
        self.type = type
        self.array = array
    }
}

class User: ObservableObject, Identifiable {
    
    @Published var id: UUID = UUID()
    @Published var name: String
    @Published var data: MyData
    
    init(name: String, data: MyData) {
        self.name = name
        self.data = data
    }
}

let data: [MyData] = [
    MyData(type: "type1", array: [1, 2, 3]),
    MyData(type: "type2", array: [4, 5, 6, 7]),
]

let users: [User] = [
    User(name: "Tim", data: data[0]),
    User(name: "Steve", data: data[1]),
]

struct ContentView: View {
    
    let db = DataBase(data: data, users: users)
    
    var body: some View {
        ShowView(db: db)
    }
}

struct ShowView: View {
    
    @ObservedObject var db: DataBase
    
    var body: some View {
        
        HStack {
            
            List(db.users) { user in
                Text("\(user.id) \(user.name) \(user.data.type)")
                Text("\(user.data.array.count)")
                Divider()
            }
            
            List(db.data) { data in
                Text("\(data.type)")
                Text("\(data.array.count)")
                Divider()
            }
        }
        
        HStack {
            Button("add data to data[0]") {
                db.data[0].array.append(db.data[0].array.last! + 10)
                print(db.data[0].array)
            }
            
            Button("add data to data[1]") {
                db.data[1].array.append(db.data[1].array.last! + 20)
                print(db.data[1].array)
            }
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

#2

попробуй поменять на @StateObject private var db = DataBase(data: data, users: users)


#3

Да, заработало! Спасибо. Либо еще нашел такой вариант

db.objectWillChange.send()