I need to setup an information controller that’s shared between 2 or extra View Fashions in my SwiftUI utility. I’ve discovered about establishing the information controller as a singleton in order that occasion is shared between the 2 however I even have discovered singletons are an anti sample. What are my choices?
That is my present try that doesn’t work as a result of I consider every VM finally ends up instantiating its personal occasion of the consumer controller. Updating the username in a single view doesn’t replace within the different view.
UserController
@Observable ultimate class UserController {
personal(set) var userProfile: UserProfile?
func getUserProfile() async -> () {
do {
...
} catch {
...
}
}
func updateUsername(newUsername: String) -> () {
userProfile?.updateUsername(newUsername: newUsername)
}
}
HomeViewModel
@Observable ultimate class HomeViewModel {
var controller: UserController
init(controller: UserController) {
self.controller = controller
}
func getData() async {
await controller.getUserProfile()
}
func updateUsername(newUsername: String) -> () {
controller.updateUsername(newUsername: newUsername)
}
}
SettingsViewModel
@Observable ultimate class SettingsViewModel {
var controller: UserController
init(controller: UserController) {
self.controller = controller
}
func getData() async {
await controller.getUserProfile()
}
func updateUsername(newUsername: String) -> () {
controller.updateUsername(newUsername: newUsername)
}
}
Within the views, I am testing this by attempting to replace the username so it displays in each views.
HomeView
struct HomeView: View {
@State personal var vm = HomeViewModel(controller: UserController())
var physique: some View {
VStack {
if let userProfile = vm.controller.userProfile {
Textual content("(userProfile.username)")
}
Button("Get knowledge") {
Activity {
await vm.getData()
}
}
Button("Replace username") {
vm.updateUsername(newUsername: "HomeViewUsername")
}
}
}
}
SettingsView
struct SettingsView: View {
@State personal var vm = SettingsViewModel(controller: UserController())
var physique: some View {
VStack {
if let userProfile = vm.controller.userProfile {
Textual content("(userProfile.username)")
}
Button("Replace username") {
vm.updateUsername(newUsername: "Settings username")
}
}
}
}
My purpose with this setup is to have an information controller/file that holds all of the API requests which might be wanted and their responses. After I setup a View Mannequin for a display screen I can set it up in a manner that makes use of knowledge from a controller that syncs the entire utility on updates.