MVC without C: What will change SwiftUI in application architecture?

MVC has been a long-standing standard in design patterns used to write iOS applications. The structure of iOS applications that were created earlier was based on one basic component, which is present everywhere, and it is called Controller . SwiftUI was introduced at WWDC19 , which does not have such a component.



The problem with the so-called massive view-controllers should be resolved in SwiftUI. So, you need to find a new way to correctly decompose the code. Let's look at the current state of the platform and think about what paradigms we can use when developing for iOS13 and later.



image



Unidirectional and bidirectional architectures



Most of the architectural solutions that large corporations use are bidirectional. This means that you can think of them as layers above each other and they can communicate with each other transferring data both up and down. Patterns such as MVC, Model-View-ViewModel, and even many implementations of the MVVM pattern with coordinators are also bi-directional architectures.



An example of the currently widely used unidirectional data stream on the iOS platform is the VIP (Presentation-Interactive-Presenter) loop in the Clean Swift or Viper architectures. These architectures are not purely unidirectional. Router and executables communicate with the VIP loop in both directions.



Another thing that we can observe is that the MVC pattern and other patterns that are built on its basis are more based and located on one screen. Usually there is no clear structure for writing services, modules, etc., that interact with various parts of the application.



Data flow in SwiftUI



According to the WWDC presentation, the element connecting view and model / state in SwiftUI was a certain Store class, corresponding to the BindableObject protocol. We can only hope that we will not have applications with a massive store containing all the application logic with all states without any clear structure. I believe that the iOS community is quite advanced and can do better in this direction.



If we put MVC and SwiftUI with view and store next to each other, we can see almost the same template, which can lead to similar problems that we had with the view controller, but without any standard code that VC has in nature.



image

If you put MVC and store in a chart, they might look something like this.



At first glance, it might seem that Combine may be the architectural pattern used in SwiftUI. But Combine is just a tool for processing values ​​over time. Likewise, MVVM using RxSwift is still MVVM, just a link between layers, which is implemented in different ways.



Declarative architecture for declarative user interfaces



SwiftUI can be summarized in a few words, such as a declarative user interface . I believe that more can be achieved if you think outside the box and focus on the word β€œ declarative ”. The most advanced declarative architectural examples can be found when developing front-end applications. Concepts like ELM, Redux, and Flux can be easily used with SwiftUI and Combine infrastructure. Swift already had several re-implementations such as ReSwift , but it would still be necessary to combine these implementations in Combine .



image

Slightly modified Data Flow in SwiftUI from WWDC19



I would like to play with SwiftUI from the very beginning without any dependencies, and I'm currently experimenting in Swift with a simple implementation of the ELM architecture. This architecture better matches the diagrams Apple showed at WWDC.



We can describe the application through these architectural patterns:





All three of these elements are declarative, and each of them represents one small testable and reusable part of the puzzle, which together makes up the whole application. The state is stored in the Store, and a view can be computed from it.



image

State, Actions and update for a simple Swift application.



For asynchronous operations, we could introduce something like a middleware object in Redux or Commands in ELM.



Conclusion



We can either use any architectures known to us, and when we gradually add SwiftUI to currently existing applications, this will be a reliable and safe approach. In case a new application is implemented using only SwiftUI, you can use a more open approach and try something else.



If you think about developing an application using SwiftUI in the near future, I would recommend paying attention to some points:





My experiments can be found in playground Swift (for comparison, it presents the implementation and use of UIKit and SwiftUI, the same application).



Next steps



There are many ways we can take advantage, but I am strongly inclined to finally try a much more functional approach to application development. So, you can see some interesting solutions from the community, and we still have a lot of time when we can use SwiftUI in everyday work, so there is still time for experimentation and there is no pressure on us.



I plan to write more about this implementation of a unidirectional and functional architecture. I hope that soon I can use this in some small real project, so I can tell you more about how this approach is viable and has performance problems in large-scale projects.



All Articles