3 ms·
I also do iOS apps, and I think the reason for bugs and low maintainability in our domain (i.e. programs that have to power a GUI and all its states) is convolu
by manmal 10y ago
I also do iOS apps, and I think the reason for bugs and low maintainability in our domain (i.e. programs that have to power a GUI and all its states) is convoluted state. You stack feature upon feature, and once the system gets big enough, it's getting hard to get a proper grip of what is actually happening. So you start monkey patching, and you start to regret not having written any integration tests that would tell you when you introduce regressions.
State has to be managed rigidly. If you cannot deduce what semantic state your app is in while you debug, then chances are things will go wrong.
I have found two approaches that work for me: Reactive programming, and good old state machines. The former is needed when there is so much state that the latter would be too complex (too many possible permutations > too many states to grasp).
Every property that your screen has (element A is hidden, element B has this text, animation C is in flight...) should be derived from the current screen's state machine or stream of values. Meaning, state 1 will set A to hidden, B has no text, and C is stopped; state 2 will set A to not-hidden, B has text "xyz" and C is still stopped, etc. It's kind of like React, but on a lower level - properties are overridden or methods are called when transitioning between states. One could call this state machine "ViewModel" :)
Swift brought us Enums with attached values, so they are perfect for modeling a state machine. IMO Optionals also prevent some state sloppiness we had with Obj-C's nil behavior.
I'm not saying state machines or Reactive programming are a panacea, but they have solved the problem for me. I'm confident in my code now, and have the feeling that I do solid work (which is good as I'm huge on feeling like an imposter). As long as I use Swift and RAC or state machines, the very most bugs I cause are of semantic nature - e.g. a button text is wrong in such and such state. But crashes or unreproducible behavior are really rare now.