Generating Forms in SwiftUI - Part 1
One thing I came up with in the days of ObjectiveC, XIBs, and storyboards (remember those?) was a way to dynamically generate and handle forms. This method has evolved and streamlined, through all the Apple releases and I’ve finally come upon a simple way of doing it in Swift and SwiftUI.
Why would you want to generate a form? In my writing app, Auteureist, I have a ton of user-managed metadata. This is split across many forms. For example: a project metadata form, a form for character, locations, preferences, notes, research, statistics, etc. I didn’t want to lay out each form by hand in SwiftUI. Yes, it’s a lot easier than it used to be in the days of ObjectiveC, but it’s still repetitive. And what happens if I need to change a data structure that’s tied to a form? I’d have to change the SwiftUI code for the form. Again, not onerous, but tedious. For one, I’d have to dig through all the files in Xcode. And what about backwards compatibility?
I came up with what I feel is a cleaner and better solution. Here are the broad strokes. I store all of my project data in a directory FileWrapper. Along with the actual data, I store metadata for each of the forms in the FileWrapper in JSON. Why? I’m not locked in to using Xcode should I wish to, for example, write a version of my writing app in Python.
Why store it in the package and not in the app bundle? The metadata flows with the project data. If I change them, the app will still be able to decode and use the data and metadata through versioning. If I change the data, all I have to do is change the JSON metadata file.
So how does it work?
In practice, I:
1) load the data into my model. Then, when I display a form, I
2) pull the JSON for that form from the FileWrapper,
3) decode JSON into a Swift dictionary,
4) map the data from my model to the dictionary, and
5) display the form using a custom binding
I don’t enjoy getting fancy, so there are no generics or code that requires an advanced degree.
Using this method, I can create any SwiftUI form I need.
In the next few posts, I’ll show the code and walk through the process.