May 9, 2017
Really interesting read highlighting the pitfalls of a lot of common approaches to iOS App Architecture.
In my experience I’ve found that testing is the hardest thing to keep up with in a typical Cocoa architecture. I do sometimes tend to fall back to a Massive View Controller, but try to keep everything organized with
#pragma mark (or
// MARK:) and well documented marking groups so it’s easier to keep track of a growing ViewController, so navigating my code isn’t usually the biggest problem I have. But it is difficult to write specific tests when you have a lot of logic grouped into
UIViewController classes or even
AppDelegate, which is another class I use for more than I know I should. Keeping things modularized in small chunks allows for much more robust test coverage and usefulness (one thing I’ve learned in previous jobs is that
coverage != usefulCoverage).
UITests can do a lot to bridge this gap, allowing you to test core controller logic without hacking your existing code base to bite-sized pieces, but with the obvious caveat that the test becomes more of a function test of how the view and controller units work as a pair rather than individual tests of each piece. Again,
coverage != usefulCoverage.
These days I think it’s very important to remember that a good application doesn’t just mean a rectangle that takes up the full screen and displays information and transitions well. There’s a lot more to the Apple platforms than just UIKit, so platform agnostic modules are something I’m trying to keep in mind. This is something Orlov highlights really well, that a well abstracted controller should treat a
UIViewController like a generic
View class, and allow you to plug in a
UIViewController, or a
WKInterfaceController, or whatever container is appropriate for the context.
The final thing I want to address is
RXSwift. I really like a lot of the simplicity that you can get from reactive programming architectures, but the screenshot of a callstack when working with
RactiveCocoa is a key example of why I don’t think this is ready to use yet. Debugging is a pain, and tools matter in an IDE. Until Xcode and Cocoa adds native support for these patterns I think this is something I’m going to be avoiding like the plague in my own personal projects. There’s also my general feelings about third party layers of abstraction, which is a matter for a whole other post.