The controller is always where the trouble arises because it glosses over a lot of details [1], and there's way too much stuff you can put in there if you're not careful. Before you know it you have thousands of lines of highly coupled code. This has been especially true for me in mobile applications (though much of this is relevant on other platforms too).
Over the years I've extracted many components from my controllers to the point where they're finally getting pretty slim. At first I let the controller fetch the model - e.g. update a model from the network, but later extracted this into a manager/provider object so multiple controllers and views can easily share this. Then I removed anything resembling business logic from the controller as I realised that was part of the model too, and moved this into service objects or utility functions (and not on the model-objects themselves, as I try to keep these focused just on data storage and serialization/deserialization). This might also include some form of dispatch if the business logic is triggered by a command. Similarly I moved all kinds of formatting code into presenter objects. Then I added viewmodels as an adapter layer on top of the actual model - both to insulate the controller from the actual model (didn't seem that important at first, but I finally 'got it' later) and to have a place to store local state such as current selection, scroll position, etc. And finally, I recently went all the way with the viewmodel after I extracted the logic of which view leads to which view out of the controller and into a flow coordinator object. This way, a given controller doesn't know what view is shown when you click the 'Next' button - instead it asks its viewmodel. That way the controller doesn't know anything about what needs to happen next or how the next view is shown. And that way all the logic about which view leads to which view resides in the flow coordinator which injects this into the controllers via the viewmodel. That way a view-controller pair becomes a completely reusable component that can be shown in multiple ways from multiple locations as part of different flows, and even using different models.
I don't always bother with all of the above, but it goes to show just how many separate concerns can actually end up in a controller, or instead be extracted to its own object: Fetching the model (provider), formatting the data (presenters), mutating the model (service/dispatch objects), wrapping the model (viewmodel), local ui state (viewmodel) and navigation between views (flow coordinator). It really goes to show that MVC isn't so much an architecture as it's the foundation for one; You've separated your view and model - great, now what about the rest of the application?
Over the years I've extracted many components from my controllers to the point where they're finally getting pretty slim. At first I let the controller fetch the model - e.g. update a model from the network, but later extracted this into a manager/provider object so multiple controllers and views can easily share this. Then I removed anything resembling business logic from the controller as I realised that was part of the model too, and moved this into service objects or utility functions (and not on the model-objects themselves, as I try to keep these focused just on data storage and serialization/deserialization). This might also include some form of dispatch if the business logic is triggered by a command. Similarly I moved all kinds of formatting code into presenter objects. Then I added viewmodels as an adapter layer on top of the actual model - both to insulate the controller from the actual model (didn't seem that important at first, but I finally 'got it' later) and to have a place to store local state such as current selection, scroll position, etc. And finally, I recently went all the way with the viewmodel after I extracted the logic of which view leads to which view out of the controller and into a flow coordinator object. This way, a given controller doesn't know what view is shown when you click the 'Next' button - instead it asks its viewmodel. That way the controller doesn't know anything about what needs to happen next or how the next view is shown. And that way all the logic about which view leads to which view resides in the flow coordinator which injects this into the controllers via the viewmodel. That way a view-controller pair becomes a completely reusable component that can be shown in multiple ways from multiple locations as part of different flows, and even using different models.
I don't always bother with all of the above, but it goes to show just how many separate concerns can actually end up in a controller, or instead be extracted to its own object: Fetching the model (provider), formatting the data (presenters), mutating the model (service/dispatch objects), wrapping the model (viewmodel), local ui state (viewmodel) and navigation between views (flow coordinator). It really goes to show that MVC isn't so much an architecture as it's the foundation for one; You've separated your view and model - great, now what about the rest of the application?
[1] http://i.imgur.com/rCr9A.png