Protocols have their uses, but MVC works really well and scales really well in making apps for Apple platforms.
Protocols have their uses, but MVC works really well and scales really well in making apps for Apple platforms.
Multi-paradigm isn’t a cop-out, it’s a pretty specific goal of the language. Being overly “faithful” to particular patterns will conflict with this, as you’ve likely experienced. I appreciate the ability to break out and use different styles where appropriate. That pesky “last 10%” is now far less painful. It also allows for varying styles per module based on functionality required and libraries in use.
If you replace protocol by trait, class, function, macro (basically anything that was invented to allow abstraction), the statement remains true, So I don’t think that’s a good argument against protocol-oriented programming.
I don’t even want to bother with answering that question, though. Even Apple didn’t have a clear definition for it, so debating this point seems moot to me, I’m afraid.
https://blog.metaobject.com/2015/06/protocol-oriented-progra...
Yes, OO as defined by Alan Kay was about the interface, protocol or what ever we call it in a given language. It's a tool for abstraction, so you think about communicating instead of structure and state.
Now, most modern (~10y/o) general purpose languages I know have moved away from ADTs or simply inheritance. Inheritance was just a means to an end and never the point.
MVC is famous for scaling terribly on iOS and resulting in view controllers with thousands of lines. MVC is great for small apps. No need to overcomplicate things. But if you're building something bigger, you should look into using the right tool for the job. Don't blindly follow a popular pattern, but choose the right pattern to make the code easy to read, easy to test, and easy to modify.
Over time I realized that I can just create dedicated controllers or handlers or managers or services with more specific and limited functionality, and then my VCs simply dispatch to those. It’s called composition.
To give some context, I remember reading an article about massive view controllers and one example was Firefox for iOS, so I've dug up a snapshot of its main view controller, which exhibits all the things people hate about Apple's MVC:
https://github.com/mozilla-mobile/firefox-ios/blob/21e9d2943...
I have met Swift teams who would have proudly refactored this outdated MVC code into a "modern" MVVM pattern, replacing the 2000 LOC controller with one 2000 LOC ViewModel and a 500 LOC controller (because you still need UIViewControllers in the Apple world).
But in my opinion the bigger issue is the insistence of only having one controller, or view model, or whatever per screen. As soon as you find a way to divide all the interconnected concerns of this screen, the layers and their names are not really that interesting.
As for structuring your code, someone (I don't remember who) offered the suggestion that out of all the parts that the framework gives you, your application logic doesn't belong in any of them.
Everything else is outside MVC. Apparently some people don't understand this and stuff their application logic into MVC controllers.
I actually agree with what you said in some way. Projects should start with whatever is the most boring, straightforward architecture possible, and then evolve it organically.
But for UIKit projects, that boring foundation is to vaguely follow Apple's idea of MVC, at least so that JSON parsing and font size adjustments don't happen directly in an IBAction.
First, MVC isn’t flat. The (V)iew of an MVC triad can itself be an MVC.
Second, MVC is a UI pattern. Decouple your business logic from your UI. Put it in a utility or “service” layer (which itself can adopt patterns to manage complexity, as needed).
I have seen many versions for it in iOS, MMVC, MVVC, or whatever, but really they are iterations of separation of business logic and view/display logic.
You can disperse the view logic, without having traditional centralized controllers, but your business logic will end up centralized in one place. So, in practice you end up with a Model-Business-Logic / View paradigm, where traditional controllers end up just being a thin layer.
Protocol driven development, reminds me the old Java style of having a class (eg. MyFunctionalityClass), which was either abstract, or had only protocols declared, then have another MyFunctionalityClassImpl to actually implement it.
I didn't think it was pretty, and it seemed it was done by C++ developers to simulate the lack for header .h files in Java.
Ps. Before you reply on a ad-hominen way, I probably have much more iOS experience than you, since I both have worked on it since day one, and have worked on some the currently largest apps in the world.
The fundamental challenge of iOS architecture is picking the right level of abstraction for the complexity of your application.
The trouble that comes in with MVC, as I see it, is how easy it is to shoot yourself in the foot. It’s too easy to do it “wrong”, which is why so many have tried to come up with something different. Of course you can’t escape the MVC-ness of the platform, it’s all about how you manage it.
You have to distinguish between MVC, which scales really well, and what Apple calls "MVC", which does not.
https://blog.metaobject.com/2015/04/model-widget-controller-...
And yes, the fact that they overloaded the term is a problem.
https://blog.metaobject.com/2017/03/concept-shadowing-and-ca...
One particular challenge is lack of modular components and component nesting. For example, if you have a list view, it's very natural to have one component define the list, and child components define each entry in the list. Something like React makes this trivial.
On iOS on the other hand, you are encouraged to use a UITableViewController with UIViews for each cell. This immediately pushes you towards one mega-controller which mixes the responsibilities of the list with those of the individual cells. To overcome this, you could try to have a UIViewController for each cell (uncommon), or have the UIView of each cell start taking on more responsibilities of a UIViewController (breaking MVC).
In general though, iOS's MVC is a perfect storm of being both bare bones as well as opinionated at the same time. For these reasons many large corporations have moved away from MVC to their own custom in-house architectures to handle scale.
Facebook - https://www.youtube.com/watch?v=mLSeEoC6GjU. * Uber - https://github.com/uber/RIBs * Square - https://github.com/square/workflow
Let’s just say that I can build a view controller for a large, multi-sectioned list where each section calls a different APIs and shows items with different layouts, and still end up with less than 500 lines of VC code even with generous line breaking. Oh, and I can make custom UICollectionView layouts with self-sizing headers and cells.
That said, your comment is just ad hominem and you should be downvoted to oblivion.
Now imagine that your table view has 20 cells, and each cell is managed by a team of 5 people and needs 1,000 lines of code to fulfill its business logic. How would this approach hold up? Would you have all 100 people working on the same `cellForRowAtIndexPath` method, piping every event for those 20,000 lines of code through there?
When people talk about scale on iOS, they are talking about potentially 100s of people working on the same screen. With something like React, this is trivial by having each team work independently on its own components. With iOS, its much harder out of the box.
That’s pretty much the technique. :) Also, composition by child view controllers.
That being said, would love to learn more about how you structure code. What does a project structure look like for you? I usually conceptually try to separate the view and data starting with the simplest file structure and dividing as needed.
https://medium.com/flawless-app-stories/the-only-viable-ios-...
Obviously most significant production apps are using variant architectures such as at the bare minimum having view models, and the introduction of SwiftUI and popular earlier frameworks such as RxSwift also complicates things. Most apps aren't using pure MVC, sure, but it doesn't mean that the architecture isn't scalable. The alternatives might also be pretty gnarly:
https://developer.squareup.com/blog/ziggurat-ios-app-archite...
To me that article proposes a more disciplined MVC than what I've seen in real codebases. I think a lot of the architectures people come up with (like the second one you linked) try to build that discipline in. I try not to be dogmatic and instead go to core principles. Do I know what this class is supposed to be doing? Are my data and view layers reasonably separated with minimal glue code? Can a new dev easily navigate this project?
It's an endless discussion with no right answer. Thanks for sharing!
> It's an endless discussion with no right answer.
These don't seem like the hallmarks of a well-designed, mature platform.