My challenge is that once I edit a template, the UI in BeginWorkoutView doesn’t replace appropriately. I consider I’m by some means misusing @ObservableObject/@Printed/@Mainactor, however can’t for the lifetime of me work out how. Each tutorial appears to make use of the sample I’m presently utilizing, and it really works for them.
I’ve a important web page, BeginWorkoutView. From right here, you’ll be able to create new exercise or create exercise templates. You can even see all created templates, and click on to edit them.
here’s a simplified model of that:
struct BeginWorkoutView: View {
@ObservedObject var templateManager = TemplateManager.shared
var physique: some View {
NavigationView{
ScrollView{
Part("Begin from scratch"){
HStack{
NavigationLink("New Exercise"){
//new exercise web page
}
NavigationLink("New Template"){
CreateTemplateView( viewModel: CreateTemplateViewModel(), editMode: true)
}
}
}
Part("Begin from template") {
ForEach(templateManager.templates, id: .id.self) { template in
TemplateRowView(template: template)
}
}
}
}
}
}
I handle my information in a template supervisor. Im ready so as to add new exercises and so they present up on my BeginWorkoutView web page no challenge. As I mentioned, once I edit the title, it doesn’t replace in BeginWorkoutView. From what I can inform, the templateManager record of templates IS being up to date, but it surely doesnt appear to set off the UI. I’m presently utilizing the @mainactor/@Observable object construction as a result of i need to help pre-IOS 17.
@MainActor
closing class TemplateManager: ObservableObject {
@Printed personal(set) var templates: [WorkoutTemplate] = []
static let shared = TemplateManager()
init(){
getTemplates()
}
func getTemplates() {
//will get templates from firebase
}
func updateTemplates(template: WorkoutTemplate) {
Job{
do {
//updates templates in firebase
//HERE is the place the UI ought to be getting the sign to replace. Clearly spot changing the template didnt work, however changing the whole factor wont work both.
var up to date = templates
if let index = up to date.firstIndex(the place: { $0.id == template.id }) {
up to date[index] = template
} else {
up to date.append(template)
}
self.templates = up to date
} catch {
print("unable to replace templates")
}
}
}
}
whether or not i’m creating a brand new template or enhancing one, i take advantage of createtemplateview/createtemplateviewmodel. listed here are simplified variations with largely simply the perform calls. I dont consider the problem is right here however im including them in case they’re useful.
@MainActor
closing class CreateTemplateViewModel: ObservableObject {
@Printed var template: WorkoutTemplate
var templateManager = TemplateManager.shared
init(template: WorkoutTemplate) {
self.template = template
}
init(){
self.template = WorkoutTemplate(identify: "Exercise Template", workoutModules: [])
}
func addTemplateList() {
templateManager.updateTemplates(template: template)
}
func removeTemplateList() {
templateManager.removeTemplateList(templateId: template.id)
}
}
struct CreateTemplateView: View {
@StateObject var viewModel: CreateTemplateViewModel
var physique: some View {
ScrollView{
StringTextField(preview: "Template Title", $viewModel.template.identify )
.padding()
//reveals editable modules for the template
Button("save"){
viewModel.addTemplateList()
}
}
}
}
there are "hacks" on the market like utilizing notifications or mix to inform the UI to replace, however I consider this could work if carried out appropriately. I’m largely penning this to be taught these information constructions and i am having a troublesome time greedy this one so I would positively prefer to unravel it relatively than slap a bandaid repair on it.