Coordinators with Storyboards (You won't believe what happened next!)
After trying to shoehorn coordinators into storyboards I freely admit there were a number of unanswered questions.
My plan wasn't to make a completely perfect coordinator pattern, it was to try to see if the architectural simplicity of coordinators could use the highly coupled storyboard paradigm. I think I succeeded in what I wanted to do, but the constraints of the challenge meant there are some obvious holes.
So, in the spirit of honesty, here's my own attempt at trashing my own work.
- Order is important. Knowing when performSegueWithIdentifier(_:sender:) is triggered is vital. For example, if you have a table view whose cells trigger a segue directly in the storyboard, that segue will get triggered before the table view will call tableView(_:didSelectRowAtIndexPath). This means any updates to your model or view model must be done in tableView(_:willSelectRowAtIndexPath) instead.
- coordinateTransitionFrom(_:toDestination:) could become huge.
- The coordinators are now coupled to the storyboard. Which means if the storyboard can't do it, the coordinator can't do it!
- How are storyboard references handled? If there is a separate coordinator per storyboard, and there probably should considering point 2, then how do we know which coordinator to set in the view controller?
- Segues aren't just for transitions from one scene to another, they are also used when loading child view controllers. So be careful.
- Isn't testing still a pain in the elbows?
- What about unwind segues and shouldPerformSegueWithIdentifier(_:sender:)
- Am I being free and easy with the definition of a coordinator in order to achieve my goals?
Let's have a look at some of those points.
2. Yes, coordinateTransitionFrom(_:toDestination:) could become huge. It's effectively all of the code from prepareForSegue(_:sender:) from every view controller in the storyboard grouped into one place. But it's up to the developer to reduce the load on this coordinator by not relying on a singe coordinator in their app. I would say in general there's potential for any Coordinator to become huge, so this isn't just a storyboard problem.
3. Coordinators don't need to be storyboard coordinators. The example in the post used an AppCoordinator to kick everything off, and that wasn't tied to any storyboard. But yes, a storyboard coordinator is tied to the storyboard, but that's the point!
Having said that, I would love to get rid of the need for the AppCoordinator being the initialiser for the root view controller. That's the next challenge.
4. It would be nice to have a single coordinator per storyboard and for the storyboard reference to automagically create the right coordinator, but I haven't found a way yet. View controllers have a reference to their storyboard, but the name of the storyboard is a private API, so using that would get any app using that as a workaround rejected.
6. I had a closer look at testing, and it turns out it's really simple as long as you stick to a few rules. You cannot create your own view controllers in the unit test, you have to instantiate them via the storyboard, otherwise calls to perform the segue won't be understood.
7. Nuts. I forgot about those.
8. Hell yes. It's how we learn, isn't it?