'SwiftUI macOS - Commands menu list is not updating to observable object changes
I'm trying to list all recent used files (form observable object) in a menu bar list item but somehow the list only loads the values form the app model once the app launches and then never updates again.
To fix this I tried using a @Published variable, that gets updated as soon as the list changes, and a computed variable, that itself runs the update function, but in both cases the list stayed the same until the app is relaunched.
Somehow the variables are only read during the launch process and then never again.
My code:
@main
struct MyAPP: App {
var model = appModell()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(appModell())
}.commands { AppCommands(model: model) }
}
}
struct AppCommands: Commands {
@ObservedObject var model : appModell
var body: some Commands {
CommandGroup(after: .newItem) {
// list all recent used files
Menu("Open Recent") {
ForEach(model.getAllRecentUsedFiles, id: \.self) { file in
Button(action: { NSWorkspace.shared.open(file.location!) }, label: {
MenuButtonRecentUsedFile(type: file.type!, name: file.name!, icon: file.icon!)
})
}
}
}
}
}
class appModell: ObservableObject {
// @Published var getAllRecentUsedFiles : [fileInfo] = [fileInfo(), fileInfo()]
var getAllRecentUsedFiles : [fileInfo] { getFileInfo() }
...
func getFileInfo() -> [fileInfo] {...}
}
Is there a way to dynamically update the list using an app model?
Solution 1:[1]
import SwiftUI
@main
struct xxxApp: App {
let appModel = AppModel.shared
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(appModel)
}
.commands {
AppCommands()
}
}
}
class AppModel: ObservableObject {
// singleton
static let shared = AppModel()
@Published var getAllRecentUsedFiles: [String] = []
init() {
self.getAllRecentUsedFiles = getFileInfo()
}
func getFileInfo() -> [String] {
return ["File-01", "File-02"]
}
}
struct AppCommands: Commands {
var body: some Commands {
CommandGroup(after: .newItem) {
Menu("Open Recent") {
ForEach(AppModel.shared.getAllRecentUsedFiles, id: \.self) { file in
Button(action: { }, label: {
Text(file)
})
}
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | sugimoto |
