Document-Based App with MVVM

Dear all,

I made an app for computing Finite Element Analysis of electric motors. I (think I) managed to follow the MVVM principle by not exposing the model to the views. Now, my goal is to be able to use documents, each representing a different motor. I want to have my files saved on iCloud, and I want to be able to read plain text from it, so some other code (i.e. python) can create new configurations, even though this app is made for building, graphically.

Before trying to work with FileDocument, my class ViewModel: ObservableObject had properties with Published, like @Published var staOD = 80.0, and I would have views with TextFields to change these values.

Now, I’m trying to blend in FileDocument, and I’m lost. I don’t know how I should work with my data. Under the “Separation of Concerns”, I guessed that:

  • ViewModel: Should handle computations, updates, and application logic.
  • Document: Should focus on data persistence and encapsulate data to be saved/loaded as a document.

My ViewModel looks a bit strange to me, and I’m not sure I’m updating it the right way. I have around 100 parameters, I’m afraid I’m updating these parameters too often and unnecessarily every parameter at the same time, even when only one value is changed in the document.

What I’m asking:

  • Clarifications on how to work with FileDocument in my case of MVVM (I’m open to change the entire workflow, my main knowledge is on the Model built in Swift, but not SwiftUI)
  • Why isn’t the computed area on the DocumentView at the right value when I open a document? I would like to open documents and have it in the “right” state. In reality, I’m computing an image of the electric motor, and it would be nice to open the document and see the “real” image, and not a dummy image before I can validate the geometry.
  • I have these warnings popping every time I open a document and that scares me, especially because I want ideally to use swift 6 in the coming future, with concurrency the right way.
    • Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.

Thanks a lot for your help,

Guillaume


I made an example/simplified code that has all the logic. I can't show the entire code in this prompt due to space limitation. Therefore, I put everything (184 lines) in a single Swift file for you to download. You can just create a Multiplatform Document App. Remove all files except the ...App file, in which you can paste the content of the shared swift file. Run on iPhone simulator.

Development environment: Xcode 16, macOS 15

Run-time configuration: iOS 18, macOS 15

  • Open the app, click on "New motor"
  • You will see "Computed area: 3'063..."
  • Click on "Geometry", change "Stator OD" to 60 instead of 80.
  • Click on "Save" button, now Computed area is 863...
  • Click on "Cancel" button, and reopen the same document
  • Problem: area is again 3'063 while when you open Geometry, you see that "Stator OD" is rightfully 60.
Document-Based App with MVVM
 
 
Q