Jekyll2022-03-23T05:20:06+00:00/Malin SundbergA blog about Swift and iOS Development
SwiftUI talks2022-03-16T00:00:00+00:002022-03-16T00:00:00+00:00/talks/2022/03/16/SwiftUI-videos<p>I’ve given a lot of talks about SwiftUI lately. Here’s a list with links to some of the most recent ones.</p>
<p><a href="https://www.youtube.com/watch?v=5HO6fsegDNk">Multi-platform Development, the SwiftUI Way</a> – 360iDev 2021<br />
<a href="https://www.youtube.com/watch?v=0MAc-hjvKqw">The Hitchhiker’s Guide to SwiftUI</a> – iOS Conf SG 2021<br />
<a href="https://vimeo.com/479786650">SwiftUI: We’re now Apple Platform Developers</a> – NSSpain 2020<br />
<a href="https://www.youtube.com/watch?v=mxTYOnkA0vo">Building an Indie app using SwiftUI</a> – MalagaMobile 2020</p>I’ve given a lot of talks about SwiftUI lately. Here’s a list with links to some of the most recent ones.How to implement the coordinator pattern in a new project2018-03-06T00:00:00+00:002018-03-06T00:00:00+00:00/architectures/implementations/how-tos/2018/03/06/Coordinator-Implementation<p>In this post, I will outline how to implement the coordinator pattern in a new project. The post will include code snippets from <strong><a href="https://github.com/malinsundberg/coordinator-pattern-sample-project">this sample project</a></strong> that I created. Although the post is mostly focused on the actual implementation of the coordinators, I will also talk a bit about some of the considerations that I take when implementing a coordinator and the coordinator pattern. If you are unfamiliar with what the coordinator pattern is, I wrote an earlier post about it <a href="/architectures/2017/08/29/Coordinators.html">here</a>. I also wrote <a href="/architectures/2017/12/17/A-Coordinators-Responsibilities.html">this post</a>, describing the coordinator components’ different responsibilities.</p>
<h3 id="the-sample-project">The sample project</h3>
<p>The focus of the sample app for this post is to demonstrate the structure of a project that uses the coordinator pattern, it’s simply an app which displays a view, containing two buttons, these buttons lead to their own sub flows, with their own navigation logic. The image below outlines how the app’s different views relate to one another.</p>
<p><img src="/assets/images/Sample-coordinator-app-structure.png" alt="Structure of sample coordinator app" /></p>
<p>From an implementation point of view, the <strong>AppDelegate</strong> is initializing an <strong>AppCoordinator</strong>, which is responsible for creating a coordinator for the app’s <strong>MainView</strong>, this <strong>MainViewCoordinator</strong> initializes the main view and handles the navigation between the main view and the two sub flows, containing views of their own. Since each of the <em>mainView</em>’s sub flows have their own navigational logic, I also gave them their own coordinators, which are initialized from the <strong>MainViewCoordinator</strong> when the two buttons in the main view have been tapped. <strong>SubFlow1Coordinator</strong> handles the presentation of <strong>SubView1TableViewController</strong> and the navigation to <strong>SubView1TableViewController</strong>’s <em>detailedView</em>. <strong>SubFlow2Coordinator</strong> handles the presentation of <strong>SubView2ViewController</strong> and the navigation to <strong>SubView2ViewController</strong>’s <em>detailTableViewController</em>.</p>
<p>Now, let’s have a closer look at how to implement this coordinator structure.</p>
<h3 id="the-coordinator-protocol">The Coordinator protocol</h3>
<p>As a start, I create a protocol which all of my app’s coordinators, parent as well as child coordinators, will conform to.</p>
<p>This protocol outlines the basic functionality for the app’s coordinators, including the basic variables that each coordinator should have, as well as the main functions that each of the coordinators should contain. These functions will either be implemented in an extension of the protocol or by the conforming child coordinators.</p>
<p><strong>Coordinator protocol:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Coordinator</span><span class="p">:</span> <span class="kd">class</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="k">var</span> <span class="nv">childCoordinators</span><span class="p">:</span> <span class="p">[</span><span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">:</span><span class="kt">Coordinator</span><span class="p">]</span> <span class="p">{</span> <span class="k">get</span> <span class="k">set</span> <span class="p">}</span>
<span class="kd">func</span> <span class="nf">start</span><span class="p">()</span>
<span class="kd">func</span> <span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="kt">Coordinator</span><span class="p">,</span> <span class="n">with</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">)</span>
<span class="kd">func</span> <span class="nf">removeChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="kt">Coordinator</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Let’s go through what the above code does;</p>
<p>The <em>navigationController</em> is simply a <strong><em>UINavigationController</em></strong>, which will be used by each coordinator to present or push the view controllers that we want to display to the user.</p>
<p>The <em>childCoordinators</em> is a dictionary which will store a parent coordinator’s child coordinators. If the coordinator doesn’t initialize any child coordinators, this will simply be an empty dictionary.</p>
<p>The <strong>start</strong> function is a basic function that each coordinator is required to implement. This function - as mentioned in my earlier <a href="/architectures/2017/12/17/A-Coordinators-Responsibilities.html">post</a>, will be responsible for initializing either a coordinator’s child coordinator or the <em>view</em> that the coordinator is responsible for displaying.</p>
<p><strong>addChild</strong> and <strong>removeChild</strong>, are functions responsible for adding and removing coordinators from the coordinator’s <em>childCoordinators</em> dictionary. Since the adding and removing of a child coordinator is a behavior which all coordinators will handle in the same way in this example project, I have added a default implementation of these functions in an extension of the coordinator protocol.</p>
<p><strong>Coordinator extension:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Coordinator</span> <span class="p">{</span>
<span class="kd">func</span> <span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="kt">Coordinator</span><span class="p">,</span> <span class="n">with</span>
<span class="nv">key</span><span class="p">:</span> <span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">)</span> <span class="p">{</span>
<span class="n">childCoordinators</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">coordinator</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">removeChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="kt">Coordinator</span><span class="p">)</span> <span class="p">{</span>
<span class="n">childCoordinators</span> <span class="o">=</span> <span class="n">childCoordinators</span><span class="o">.</span><span class="n">filter</span> <span class="p">{</span>
<span class="nv">$0</span><span class="o">.</span><span class="n">value</span> <span class="o">!==</span> <span class="n">coordinator</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The above implementation of <strong>addChild</strong> simply adds the <em>coordinator</em> parameter to the coordinator’s <em>childCoordinators</em> variable. The <em>key</em> parameter is used as the key when adding a value to the <em>childCoordinators</em> dictionary. Using a key here helps for potential later retrieval of the added child coordinator.</p>
<p>The <strong>removeChild</strong> function is filtering through the values of <strong>childCoordinators</strong> to update the <em>childCoordinators</em> variable to not include the passed in <em>coordinator</em>. This function is really important to prevent memory leaks, I will go through how to use this function in more detail later in this post.</p>
<h3 id="appcoordinator">AppCoordinator</h3>
<p>The next step for the project is to utilize the coordinator protocol in the first - and the root - coordinator.</p>
<!-- - AppCoordinator is initializing the other screens, child coordinators and setting the rootViewController -->
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">AppCoordinator</span><span class="p">:</span> <span class="kt">Coordinator</span> <span class="p">{</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">window</span><span class="p">:</span> <span class="kt">UIWindow</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">childCoordinators</span><span class="p">:</span> <span class="p">[</span><span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">:</span><span class="kt">Coordinator</span><span class="p">]</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nv">rootViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">navigationController</span>
<span class="p">}</span>
<span class="nf">init</span><span class="p">(</span><span class="k">in</span> <span class="nv">window</span><span class="p">:</span> <span class="kt">UIWindow</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">childCoordinators</span> <span class="o">=</span> <span class="p">[:]</span>
<span class="k">self</span><span class="o">.</span><span class="n">navigationController</span> <span class="o">=</span> <span class="kt">UINavigationController</span><span class="p">()</span>
<span class="k">self</span><span class="o">.</span><span class="n">window</span> <span class="o">=</span> <span class="n">window</span>
<span class="n">window</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">white</span>
<span class="k">self</span><span class="o">.</span><span class="n">window</span><span class="o">.</span><span class="n">rootViewController</span> <span class="o">=</span> <span class="n">rootViewController</span>
<span class="p">}</span>
<span class="kd">public</span> <span class="kd">func</span> <span class="nf">start</span><span class="p">()</span> <span class="p">{</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>In the above code, the <em>childCoordinators</em> and <em>navigationController</em> variables are declared, as outlined in the coordinator protocol. However, the <strong>AppCoordinator</strong> is also responsible for the app’s <em>window</em>, this is the app’s main window which will be used to display the app’s different views.</p>
<p>Because of this, the <strong>AppCoordinator</strong> stores a <strong>UIWindow</strong> variable and a <em>rootViewController</em> of type <strong>UIViewController</strong>. The app coordinator is responsible for setting this <strong>UIWindow</strong>’s <em>rootViewController</em>, this is done in the class’ initializer. Apart from initializing the <em>childCoordinators</em> and the <em>navigationController</em> variables, the <strong>AppCoordinator</strong>’s <strong>init</strong> therefore takes a <strong>UIWindow</strong> parameter and sets the window’s <em>rootViewController</em> to the <strong>AppCoordinator’s</strong> <em>rootViewController</em> variable. This <strong>UIWindow</strong> parameter is provided by the <strong>AppDelegate</strong> when the app first launches.</p>
<h4 id="initializing-the-appcoordinator-from-the-appdelegate">Initializing the <strong>AppCoordinator</strong> from the <strong>AppDelegate</strong></h4>
<p>The app coordinator is different from other coordinators since it functions as a root coordinator and handles the initialization of the app’s first view, the app coordinator is created and started directly from the <strong>AppDelegate</strong>.</p>
<p><strong>AppDelegate:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">AppDelegate</span><span class="p">:</span> <span class="kt">UIResponder</span><span class="p">,</span> <span class="kt">UIApplicationDelegate</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">window</span><span class="p">:</span> <span class="kt">UIWindow</span><span class="p">?</span>
<span class="kd">private</span> <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">appCoordinator</span><span class="p">:</span> <span class="kt">AppCoordinator</span> <span class="o">=</span> <span class="p">{</span>
<span class="k">return</span> <span class="kt">AppCoordinator</span><span class="p">(</span><span class="nv">in</span><span class="p">:</span> <span class="k">self</span><span class="o">.</span><span class="n">window</span><span class="o">!</span><span class="p">)</span>
<span class="p">}()</span>
<span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="n">_</span> <span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">didFinishLaunchingWithOptions</span>
<span class="nv">launchOptions</span><span class="p">:</span> <span class="p">[</span><span class="kt">UIApplicationLaunchOptionsKey</span><span class="p">:</span> <span class="kt">Any</span><span class="p">]?)</span>
<span class="o">-></span> <span class="kt">Bool</span> <span class="p">{</span>
<span class="n">window</span> <span class="o">=</span> <span class="kt">UIWindow</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">UIScreen</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="n">bounds</span><span class="p">)</span>
<span class="n">appCoordinator</span><span class="o">.</span><span class="nf">start</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">true</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>In the above class, the lazy variable <em>appCoordinator</em> is created by passing in the <strong>AppDelegate</strong>’s <strong>UIWindow</strong> as a parameter when initialising a variable of type <strong>AppCoordinator</strong>.</p>
<p>Once the app finishes launching, the <strong>UIWindow</strong> is available, which allows it to be accessed by the lazily loaded <em>appCoordinator</em> property, which is used in calling the app coordinator’s <strong>start</strong> function.
<!-- - Go through AppDelegate functionality step by step: -->
<!-- - window -->
<!-- - appCoordinator -->
<!-- - init of window -->
<!-- - Call appCoordinator's start method --></p>
<h4 id="the-appcoordinators-start-function">The <strong>AppCoordinator</strong>’s <strong>start</strong> function</h4>
<p>The app coordinator’s job is to initialize and present the app’s main view. Since the main view in the sample project will include its own sub flows and its own navigation logic, the app coordinator will initialize a child coordinator which, in its turn, is responsible for creating and presenting a view and for handling this view’s navigational logic. For this, the following code has been added to the <strong>AppCoordinator</strong>’s <strong>start</strong> function.</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">start</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">mainViewCoordinator</span> <span class="o">=</span> <span class="kt">MainViewCoordinator</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">navigationController</span><span class="p">)</span>
<span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="n">mainViewCoordinator</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="o">.</span><span class="n">mainViewCoordinator</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Here, the <strong>MainViewCoordinator</strong> is created by passing in the <strong>AppCoordinator</strong>’s local <em>navigationController</em> variable. Once this child coordinator is created, the coordinator’s <strong>addChild</strong> function will be called to add this child coordinator to the <strong>AppCoordinator</strong>’s <em>childCoordinators</em> dictionary.</p>
<p>Now let’s have a look at the <strong>MainViewCoordinator</strong> and the <strong>MainViewViewController</strong>.</p>
<h3 id="the-mainviewcoordinator">The <strong>MainViewCoordinator</strong></h3>
<p><strong>Basic structure of the app’s MainViewCoordinator:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MainViewCoordinator</span><span class="p">:</span> <span class="kt">Coordinator</span> <span class="p">{</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">childCoordinators</span><span class="p">:</span> <span class="p">[</span><span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">:</span><span class="kt">Coordinator</span><span class="p">]</span>
<span class="nf">init</span><span class="p">(</span><span class="n">with</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span><span class="p">)</span> <span class="p">{</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="kd">internal</span> <span class="kd">func</span> <span class="nf">start</span><span class="p">()</span> <span class="p">{</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>So far, <strong>MainViewCoordinator</strong> simply conforms to the <strong>Coordinator</strong> protocol, however, the <strong>MainViewCoordinator</strong>’s <strong>init</strong> is different from the <strong>AppCoordinator</strong>’s.</p>
<p><strong>MainViewCoordinator’s initializer:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="nf">init</span><span class="p">(</span><span class="n">with</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">navigationController</span> <span class="o">=</span> <span class="n">navigationController</span>
<span class="k">self</span><span class="o">.</span><span class="n">childCoordinators</span> <span class="o">=</span> <span class="p">[:]</span>
<span class="nf">start</span><span class="p">()</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The above initializer takes a <strong>UINavigationController</strong> parameter, which is assigned to its local <strong>UINavigationController</strong> variable. After this, the <em>childCoordinators</em> variable is initialized by setting it to an empty dictionary. Once the class variables have been initialized, the <strong>MainViewCoordinator</strong> calls its <strong>start</strong> function. Before looking at what the <strong>MainViewCoordinator</strong>’s <strong>start</strong> function does, I would like to go through what the actual <strong>MainViewViewController</strong> does.</p>
<h3 id="the-mainviewviewcontroller">The <strong>MainViewViewController</strong></h3>
<p><strong>MainViewViewController:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MainViewViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
<span class="kd">@IBOutlet</span> <span class="k">weak</span> <span class="k">var</span> <span class="nv">button1</span><span class="p">:</span> <span class="kt">UIButton</span><span class="o">!</span>
<span class="kd">@IBOutlet</span> <span class="k">weak</span> <span class="k">var</span> <span class="nv">button2</span><span class="p">:</span> <span class="kt">UIButton</span><span class="o">!</span>
<span class="k">let</span> <span class="nv">button1Tapped</span><span class="p">:</span> <span class="p">(()</span><span class="o">-></span><span class="p">())</span>
<span class="k">let</span> <span class="nv">button2Tapped</span><span class="p">:</span> <span class="p">(()</span><span class="o">-></span><span class="p">())</span>
<span class="kd">@IBAction</span> <span class="kd">func</span> <span class="nf">button1Action</span><span class="p">(</span><span class="n">_</span> <span class="nv">sender</span><span class="p">:</span> <span class="kt">UIButton</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">button1Tapped</span><span class="p">()</span>
<span class="p">}</span>
<span class="kd">@IBAction</span> <span class="kd">func</span> <span class="nf">button2Action</span><span class="p">(</span><span class="n">_</span> <span class="nv">sender</span><span class="p">:</span> <span class="kt">UIButton</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">button2Tapped</span><span class="p">()</span>
<span class="p">}</span>
<span class="nf">init</span><span class="p">(</span><span class="n">nibName</span> <span class="nv">nibNameOrNil</span><span class="p">:</span> <span class="kt">String</span><span class="p">?,</span> <span class="n">bundle</span> <span class="nv">nibBundleOrNil</span><span class="p">:</span> <span class="kt">Bundle</span><span class="p">?,</span>
<span class="nv">button1Action</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(()</span><span class="o">-></span><span class="p">()),</span>
<span class="nv">button2Action</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(()</span><span class="o">-></span><span class="p">()))</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">button1Tapped</span> <span class="o">=</span> <span class="n">button1Action</span>
<span class="k">self</span><span class="o">.</span><span class="n">button2Tapped</span> <span class="o">=</span> <span class="n">button2Action</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span> <span class="n">nibNameOrNil</span><span class="p">,</span> <span class="nv">bundle</span><span class="p">:</span> <span class="n">nibBundleOrNil</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">required</span> <span class="nf">init</span><span class="p">?(</span><span class="n">coder</span> <span class="nv">aDecoder</span><span class="p">:</span> <span class="kt">NSCoder</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">fatalError</span><span class="p">(</span><span class="s">"init(coder:) has not been implemented"</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The <em>button1</em> and <em>button2</em> <strong>IBOutlet</strong> are simply connected to the <strong>MainViewViewController</strong>’s corresponding <strong>UIView</strong>, which is laid out in the <code class="highlighter-rouge">MainViewViewController.xib</code> file.</p>
<p>Next, there is the <em>button1Tapped</em> and the <em>button2Tapped</em> variables of type <code class="highlighter-rouge">(()->())</code>.</p>
<p>Then there are two <strong>IBActions</strong>, <em>button1Action</em> and <em>button2Action</em>, which again are connected to the <code class="highlighter-rouge">MainViewViewController.xib</code>. These are the actions that will handle the taps of the two buttons. These outlets simply call the function stored in the <em>button1Tapped</em> and the <em>button2Tapped</em> variables.</p>
<p>The benefits of (and in some cases the reason for) using .xibs for the views, is that a <strong>UIViewController</strong> can be created by calling its initializer, which allows for use of dependency injection. When initializing the <strong>MainViewViewController</strong>, I simply pass in the dependencies for the <strong>MainViewViewController</strong> - the <em>button1Action</em> and <em>button2Action</em>, as well as the <em>nibName</em> and the <em>bundle</em> for the .xib file. In the <em>init</em>, I use the provided parameters to set the <strong>MainViewViewController</strong>’s class variables, followed by calling <code class="highlighter-rouge">super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)</code>.</p>
<p>Now when the <strong>MainViewViewController</strong> is outlined, the <strong>MainViewCoordinator</strong> can create an instance of the view controller in its <strong>start</strong> function.</p>
<p><strong>Start function:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">internal</span> <span class="kd">func</span> <span class="nf">start</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">mainViewViewController</span> <span class="o">=</span> <span class="kt">MainViewViewController</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span>
<span class="kt">Constants</span><span class="o">.</span><span class="kt">Nibs</span><span class="o">.</span><span class="n">mainViewViewController</span><span class="p">,</span>
<span class="nv">bundle</span><span class="p">:</span> <span class="kt">Bundle</span><span class="o">.</span><span class="n">main</span><span class="p">,</span> <span class="nv">button1Action</span><span class="p">:</span>
<span class="n">navigateToSubFlow1</span><span class="p">,</span> <span class="nv">button2Action</span><span class="p">:</span>
<span class="n">navigateToSubFlow2</span><span class="p">)</span>
<span class="nf">navigate</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">mainViewViewController</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="o">.</span><span class="n">push</span><span class="p">,</span> <span class="nv">animated</span><span class="p">:</span> <span class="kc">false</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>What the above code does, is simply initializing a <strong>MainViewViewController</strong>. Once the <em>mainViewViewController</em> is created, it’s being push onto the coordinator’s <em>navigationController</em> by calling <code class="highlighter-rouge">navigationController.pushViewController(viewController, animated: true)</code> within the helper function <code class="highlighter-rouge">navigate(to:with:animated:)</code> (which is declared in an extension of the Coordinator protocol). This will make the main view visible to the user of the sample app.</p>
<p>Note that the above <strong>start</strong> function provides the <strong>MainViewViewController</strong> with parameter <em>button1Action</em> and <em>butto2Action</em>. The values provided here are two functions <strong>navigateToSubFlow1</strong> and <strong>navigateToSubFlow2</strong>, these functions are class functions of <strong>MainViewCoordinator</strong>.</p>
<p><strong>navigateToSubFlow1 and navigateToSubFlow2:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigateToSubFlow1</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">coordinator</span> <span class="o">=</span> <span class="kt">SubFlow1Coordinator</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">navigationController</span><span class="p">,</span>
<span class="nv">using</span><span class="p">:</span> <span class="o">.</span><span class="n">push</span><span class="p">,</span>
<span class="nv">removeCoordinatorWith</span><span class="p">:</span> <span class="n">removeChild</span><span class="p">)</span>
<span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="n">coordinator</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="o">.</span><span class="kt">SubFlow1Coordinator</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigateToSubFlow2</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">coordinator</span> <span class="o">=</span> <span class="kt">SubFlow2Coordinator</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">navigationController</span><span class="p">,</span>
<span class="nv">using</span><span class="p">:</span> <span class="o">.</span><span class="n">push</span><span class="p">,</span>
<span class="nv">removeCoordinatorWith</span><span class="p">:</span> <span class="n">removeChild</span><span class="p">)</span>
<span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="n">coordinator</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="o">.</span><span class="kt">SubFlow2Coordinator</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The above <strong>navigateToSubFlow1</strong> and <strong>navigateToSubFlow2</strong> functions create their own child coordinators and add these child coordinators to the <em>mainViewCoordinator</em>’s <em>childCoordinators</em> dictionary by calling the default implementation of the coordinator protocols’ <strong>addChild</strong> function.</p>
<p>You may have noticed that both the <strong>SubFlow1Coordinator</strong> initializer a the <strong>SubFlow2Coordinator</strong> initializer take a parameter called <em>removeCoordinatorWith</em> this is related to the removal of these child coordinators from the <em>mainViewCoordinator</em>’s <em>childCoordinators</em> dictionary, I will go through this in more details when describing the coordinators’ relation with the system “back” button later in this post.</p>
<p>Let’s have a closer look at the child coordinators that are being created in the above functions.</p>
<h3 id="the-subflowcoordinators">The SubFlowCoordinators</h3>
<p><strong>SubFlow1Coordinator:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">SubFlow1Coordinator</span><span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">Coordinator</span> <span class="p">{</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span>
<span class="kd">internal</span> <span class="k">var</span> <span class="nv">childCoordinators</span><span class="p">:</span> <span class="p">[</span><span class="kt">Constants</span><span class="o">.</span><span class="kt">CoordinatorKeys</span><span class="p">:</span><span class="kt">Coordinator</span><span class="p">]</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">preferredNavigationStyle</span><span class="p">:</span> <span class="n">navigationStyle</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">removeCoordinatorWhenViewDismissed</span><span class="p">:</span> <span class="p">((</span><span class="kt">Coordinator</span><span class="p">)</span> <span class="o">-></span> <span class="p">())</span>
<span class="nf">init</span><span class="p">(</span><span class="n">with</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span><span class="p">,</span> <span class="n">using</span>
<span class="nv">preferredNavigationStyle</span><span class="p">:</span> <span class="n">navigationStyle</span><span class="p">,</span> <span class="n">removeCoordinatorWith</span>
<span class="nv">removeCoordinatorWhenViewDismissed</span><span class="p">:</span> <span class="kd">@escaping</span>
<span class="p">((</span><span class="kt">Coordinator</span><span class="p">)</span> <span class="o">-></span> <span class="p">()))</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">navigationController</span> <span class="o">=</span> <span class="n">navigationController</span>
<span class="k">self</span><span class="o">.</span><span class="n">childCoordinators</span> <span class="o">=</span> <span class="p">[:]</span>
<span class="k">self</span><span class="o">.</span><span class="n">preferredNavigationStyle</span> <span class="o">=</span> <span class="n">preferredNavigationStyle</span>
<span class="k">self</span><span class="o">.</span><span class="n">removeCoordinatorWhenViewDismissed</span> <span class="o">=</span>
<span class="n">removeCoordinatorWhenViewDismissed</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="nf">start</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The implementation of <strong>SubFlow1Coordinator</strong> above is very similar to the <strong>MainViewCoordinator</strong> which I presented earlier.</p>
<p>This child coordinator simply conforms to the <strong>Coordinator</strong> protocol by declaring the <em>navigationController</em> and <em>childCoordinators</em> values, which are being set in the class’ <strong>init</strong>. The <em>removeCoordinatorWhenViewDismissed</em> variable is going to be used to remove the <strong>SubFlow1Coordinator</strong> from the <strong>MainViewCoordinator</strong>, which I will go through later on.</p>
<p>Like the <strong>MainViewCoordinator</strong>’s initializer, <strong>SubFlow1Coordinator</strong> calls <strong>start</strong> directly after initializing all of the coordinator’s variables, let’s go through what this <strong>start</strong> method looks like.</p>
<p><strong>SubFlow1Coordinator’s start method:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">internal</span> <span class="kd">func</span> <span class="nf">start</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">subView1TableViewController</span> <span class="o">=</span> <span class="kt">SubView1TableViewController</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span>
<span class="kt">Constants</span><span class="o">.</span><span class="kt">Nibs</span><span class="o">.</span><span class="n">subView1TableViewController</span><span class="p">,</span> <span class="nv">bundle</span><span class="p">:</span> <span class="kt">Bundle</span><span class="o">.</span><span class="n">main</span><span class="p">,</span>
<span class="nv">withAction</span><span class="p">:</span> <span class="n">navigationWhenTapped</span><span class="p">)</span>
<span class="nf">navigate</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">subView1TableViewController</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">preferredNavigationStyle</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigationWhenTapped</span><span class="p">(</span><span class="n">cellWith</span> <span class="nv">title</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">detailViewController</span> <span class="o">=</span> <span class="kt">DetailViewController</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span>
<span class="kt">Constants</span><span class="o">.</span><span class="kt">Nibs</span><span class="o">.</span><span class="n">detailViewController</span><span class="p">,</span> <span class="nv">bundle</span><span class="p">:</span> <span class="kt">Bundle</span><span class="o">.</span><span class="n">main</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">title</span><span class="p">)</span>
<span class="nf">navigate</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">detailViewController</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">preferredNavigationStyle</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Again, similar to the <strong>MainViewCoordinator</strong>, the above <em>start</em> function creates a view controller, for which’s flow the coordinator will be responsible for. When creating an instance of the <strong>SubView1TableViewController</strong>, the action <strong>navigationWhenTapped</strong> is passed in as a parameter. What <strong>navigationWhenTapped</strong> does, is to create an additional view controller, an instance of <strong>DetailViewController</strong>, and then call the function <code class="highlighter-rouge">navigate(to:with:)</code> - which is simply a function responsible for presenting the newly created <em>detailViewController</em> to the user.</p>
<p>Let’s go through how <strong>navigationWhenTapped</strong> is being used by the <strong>SubView1TableViewController</strong>, during, and after, its initialization.</p>
<h3 id="subview1tableviewcontrollers-behavior"><strong>SubView1TableViewController</strong>’s behavior</h3>
<p><strong>SubView1TableViewController:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">SubView1TableViewController</span><span class="p">:</span> <span class="kt">UITableViewController</span> <span class="p">{</span>
<span class="kd">private</span> <span class="k">let</span> <span class="nv">tableViewTapped</span><span class="p">:</span> <span class="p">((</span><span class="kt">String</span><span class="p">)</span><span class="o">-></span><span class="p">())</span>
<span class="nf">init</span><span class="p">(</span><span class="n">nibName</span> <span class="nv">nibNameOrNil</span><span class="p">:</span> <span class="kt">String</span><span class="p">?,</span> <span class="n">bundle</span> <span class="nv">nibBundleOrNil</span><span class="p">:</span> <span class="kt">Bundle</span><span class="p">?,</span>
<span class="n">withAction</span> <span class="nv">tableViewTapped</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">((</span><span class="kt">String</span><span class="p">)</span> <span class="o">-></span> <span class="p">()))</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">tableViewTapped</span> <span class="o">=</span> <span class="n">tableViewTapped</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span> <span class="n">nibNameOrNil</span><span class="p">,</span> <span class="nv">bundle</span><span class="p">:</span> <span class="n">nibBundleOrNil</span><span class="p">)</span>
<span class="p">}</span>
<span class="o">...</span>
<span class="k">override</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="n">_</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="n">didSelectRowAt</span>
<span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="p">{</span>
<span class="k">guard</span> <span class="k">let</span> <span class="nv">cell</span> <span class="o">=</span> <span class="n">tableView</span><span class="o">.</span><span class="nf">cellForRow</span><span class="p">(</span><span class="nv">at</span><span class="p">:</span> <span class="n">indexPath</span><span class="p">),</span>
<span class="k">let</span> <span class="nv">cellTitle</span> <span class="o">=</span> <span class="n">cell</span><span class="o">.</span><span class="n">textLabel</span><span class="p">?</span><span class="o">.</span><span class="n">text</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
<span class="nf">tableViewTapped</span><span class="p">(</span><span class="n">cellTitle</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The above class’ <strong>init</strong> simply takes a parameter called <em>tableViewTapped</em> and then assigns it to the class’ <em>tableViewTapped</em> variable.</p>
<p>Further down, in the delegate function <code class="highlighter-rouge">tableView(_:didSelectRowAt:)</code>, the class variable <em>tableViewTapped</em> is called, and is provided with the function variable <em>cellTitle</em> - which is the text in the selected row. Since the functionality of <em>tableViewTapped</em> is provided by the view controller’s coordinator - the <strong>SubFlow1Coordinator</strong> - in function <strong>navigationWhenTapped</strong>, it means that once a row is selected in <strong>SubView1TableViewController</strong> it simply hands over the decisions for the flow logic to its coordinator. The view controller’s coordinator (the <strong>SubFlow1Coordinator</strong>), in its turn, presents a new view with the selected row’s text as a title. There is one more thing that’s worth pointing out in the <strong>SubFlow1Coordinator</strong>. Let’s look at its <strong>navigationWhenTapped</strong> function again.</p>
<h3 id="subflow1coordinators-navigationwhentapped-functionality---further-explained"><strong>SubFlow1Coordinator</strong>’s <strong>navigationWhenTapped</strong> functionality - further explained</h3>
<p><strong>SubFlow1Coordinator:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigationWhenTapped</span><span class="p">(</span><span class="n">cellWith</span> <span class="nv">title</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">detailViewController</span> <span class="o">=</span> <span class="kt">DetailViewController</span><span class="p">(</span><span class="nv">nibName</span><span class="p">:</span>
<span class="kt">Constants</span><span class="o">.</span><span class="kt">Nibs</span><span class="o">.</span><span class="n">detailViewController</span><span class="p">,</span> <span class="nv">bundle</span><span class="p">:</span> <span class="kt">Bundle</span><span class="o">.</span><span class="n">main</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">title</span><span class="p">)</span>
<span class="nf">navigate</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">detailViewController</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">preferredNavigationStyle</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>One main difference between the <strong>SubFlow1Coordinator</strong> and the <strong>MainViewCoordinator</strong> is that the <strong>SubFlow1Coordinator</strong> is only a child coordinator, and not a child/parent coordinator. This can be seen by the implementation of the <strong>navigationWhenTapped</strong> function above. This function is directly initializing an instance of <strong>DetailViewController</strong>, rather than initializing a child coordinator (which in its turn would be responsible for initializing the <strong>DetailViewController</strong> instance). This means that the <strong>SubFlow1Coordinator</strong> doesn’t add any child coordinators to its dictionary variable, and is therefore, not responsible for any child coordinators, and is therefore, not a parent coordinator.</p>
<p>Technically, the above function could initialize and add a child coordinator to its class’ <em>childCoordinators</em> dictionary, but in this scenario, an additional layer of coordinators is simply not necessary. That’s because the <strong>DetailViewController</strong> does not have any further navigational behavior, it’s simply just a view which is being presented to the user, where the only navigation comes from the system “Back” button, which is handled automatically by the system. In my opinion, it’s not necessary to add the complexity of creating another child coordinator from the <strong>SubFlow1Coordinator</strong>, so instead, the <strong>DetailViewController</strong> is initialized and presented directly from the <strong>SubFlow1Coordinator</strong>.</p>
<!-- Apart from this child coordinator's ***navigationWhenTapped*** function, the functionality of this coordinator and the ***MainViewCoordinator*** is very similar. However, since this
- **Note:** No ChildCoordinator is initialized here -->
<!-- #### **MainViewCoordinator**
- Introduce one screens coordinator and one of the app coordinators child coordinator works
- Have a look at the AppCoordinator's *start* function again
```swift
public func start() {
let beansCoordinator = BeansCoordinator(with: navigationController)
beansCoordinator.start()
}
```
- Introduce the mainViewCoorinator
```swift
class MainViewCoordinator: Coordinator {
internal var navigationController: UINavigationController
internal var childCoordinators: [Constants.CoordinatorKeys:Coordinator]
init(with navigationController: UINavigationController) {
self.navigationController = navigationController
self.childCoordinators = [:]
start()
}
internal func start() {
/*let mainViewViewController = MainViewViewController(nibName: Constants.Nibs.mainViewViewController, bundle: Bundle.main, button1Action: navigateToSubFlow1, button2Action: navigateToSubFlow2)
navigationController.addChildViewController(mainViewViewController)*/
}
}
``` -->
<!-- - MainViewCootrinator conforms to Coordinator
- Has it's own start function which initializes the actual ViewCotroller for the main view
- This calls the "init()" of the mainView
```swift
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, button1Action: @escaping (()->()), button2Action: @escaping (()->())) {
self.button1Tapped = button1Action
self.button2Tapped = button2Action
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
```
- mainView has two buttons, which have navigational actions, these actions can be passed in through dependency injection
- See below start function
```swift
internal func start() {
let mainViewViewController = MainViewViewController(nibName: Constants.Nibs.mainViewViewController, bundle: Bundle.main, button1Action: navigateToSubFlow1, button2Action: navigateToSubFlow2)
navigationController.addChildViewController(mainViewViewController)
}
```
- Start function provides functionality for the MainView's buttons, these are the functions:
```swift
private func navigateToSubFlow1() {
let coordinator = SubFlow1Coordinator(with: navigationController, using: .push, removeCoordinatorWith: removeChild)
addChild(coordinator: coordinator, with: .SubFlow1Coordinator)
}
private func navigateToSubFlow2() {
let coordinator = SubFlow2Coordinator(with: navigationController, using: .push, removeCoordinatorWith: removeChild)
addChild(coordinator: coordinator, with: .SubFlow2Coordinator)
}
``` -->
<!-- - These functions handle navigational logic for the two buttons -->
<!-- - Go through the details of the two functions -->
<!-- - What will these functions do from a navigational point? -->
<!-- - initialization of subViewCoordinators, which will handle the initialization and the navigation of the child views -->
<!-- - This makes the mainViewCoordinator a child coordinator of the appCoordinator, as well as a parent coordinator of the subViewCoordinators -->
<h3 id="the-back-button">The back button</h3>
<p>As mentioned above, the navigation functionality for a default “Back” button is something that the system provides to the view’s <em>navigationController</em>. When the user tapes the “Back” button, the presented <strong>View</strong> and its <strong>ViewController</strong> is removed from the navigation stack, as long as no references to these objects remain.</p>
<p><img src="/assets/images/back-button-view.png" alt="Back button from View" /></p>
<p>However, in the sample app for this project, and as seen in above diagram, the second view, the <strong>SubView1TableViewController</strong> instance, also has a “Back” button. This view, however, is initialized by the <strong>SubFlow1Coordinator</strong> instance, which sits in-between the main view and <strong>SubView1TableViewController</strong> instance and this coordiantor is not automatically going to remove be removed when the “Back” button is tapped. This means that the <strong>SubFlow1Coordinator</strong> has to be removed from the <strong>MainViewCoordinator</strong> once the “Back” button in <strong>SubView1TableViewController</strong> has been tapped in order to prevent this variable from causing memory leaks. This is where the <strong>Coordinator</strong> protocol’s <strong>removeChild</strong> function comes into place.</p>
<p><em>Note: I have based my handling of the back button tap on <strong><a href="http://khanlou.com/2017/05/back-buttons-and-coordinators/">this</a></strong> great post by Soroush Khanlou. If you want to read more in detail about the “Back” button in relation to coordinators, I really recommend you reading his’ post.</em></p>
<p>As you may recall, when the <strong>SubFlow1Coordinator</strong> instance is initialized from the <strong>MainViewCoordinator</strong>, the <strong>removeChild</strong> function is passed in as a parameter.</p>
<p><strong>navigateToSubFlow1:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigateToSubFlow1</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">coordinator</span> <span class="o">=</span> <span class="kt">SubFlow1Coordinator</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">navigationController</span><span class="p">,</span>
<span class="nv">using</span><span class="p">:</span> <span class="o">.</span><span class="n">push</span><span class="p">,</span>
<span class="nv">removeCoordinatorWith</span><span class="p">:</span> <span class="n">removeChild</span><span class="p">)</span>
<span class="nf">addChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="n">coordinator</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="o">.</span><span class="kt">SubFlow1Coordinator</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Let’s have a look how the <strong>SubFlow1Coordinator</strong>’s <strong>init</strong> uses this parameter again.</p>
<p><strong>SubFlow1Coordinator init:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="nf">init</span><span class="p">(</span><span class="n">with</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span><span class="p">,</span> <span class="n">using</span>
<span class="nv">preferredNavigationStyle</span><span class="p">:</span> <span class="n">navigationStyle</span><span class="p">,</span> <span class="n">removeCoordinatorWith</span>
<span class="nv">removeCoordinatorWhenViewDismissed</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">((</span><span class="kt">Coordinator</span><span class="p">)</span> <span class="o">-></span> <span class="p">()))</span> <span class="p">{</span>
<span class="o">...</span>
<span class="k">self</span><span class="o">.</span><span class="n">removeCoordinatorWhenViewDismissed</span> <span class="o">=</span>
<span class="n">removeCoordinatorWhenViewDismissed</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="nf">start</span><span class="p">()</span>
<span class="p">}</span>
</code></pre>
</div>
<p>In <strong>SubFlow1Coordinator</strong>’s <strong>init</strong>, the <em>removeCoordinatorWhenViewDismissed</em> parameter is set to the coordinator’s class variable <em>removeCoordinatorWhenViewDismissed</em>.</p>
<p>This means that when an instance of <strong>SubFlow1Coordinator</strong> should be de-initialized, the <strong>MainViewCoordinator</strong>’s <strong>removeChild</strong> function is available, which is the <strong>Coordinator</strong> protocol’s default implementation of the function, which - to recap - does the following:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">removeChild</span><span class="p">(</span><span class="nv">coordinator</span><span class="p">:</span> <span class="kt">Coordinator</span><span class="p">)</span> <span class="p">{</span>
<span class="n">childCoordinators</span> <span class="o">=</span> <span class="n">childCoordinators</span><span class="o">.</span><span class="n">filter</span> <span class="p">{</span> <span class="nv">$0</span><span class="o">.</span><span class="n">value</span> <span class="o">!==</span> <span class="n">coordinator</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>This means that now, when the <strong>SubFlow1Coordinator</strong> has access to the above function, the <strong>SubFlow1Coordinator</strong> can call this function once the back button of <strong>SubView1TableViewController</strong> is tapped. To do this, the sample app must recognize when the “Back” button for <strong>SubView1TableViewController</strong>* is tapped. One way to recognize this is by implementing the <strong>UINavigationControllerDelegate</strong> function <code class="highlighter-rouge">navigationController(_:didShow:animated:)</code>, which can be done by making the <strong>SubFlow1Coordinator</strong> conform to this delegate.</p>
<p><strong>SubFlow1Coordinator’s conformance to UINavigationControllerDelegate:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">SubFlow1Coordinator</span><span class="p">:</span> <span class="kt">UINavigationControllerDelegate</span> <span class="p">{</span>
<span class="kd">func</span> <span class="nf">navigationController</span><span class="p">(</span><span class="n">_</span> <span class="nv">navigationController</span><span class="p">:</span> <span class="kt">UINavigationController</span><span class="p">,</span>
<span class="n">didShow</span> <span class="nv">viewController</span><span class="p">:</span> <span class="kt">UIViewController</span><span class="p">,</span>
<span class="nv">animated</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">)</span> <span class="p">{</span>
<span class="k">guard</span> <span class="k">let</span> <span class="nv">viewController</span> <span class="o">=</span> <span class="n">navigationController</span><span class="o">.</span><span class="n">transitionCoordinator</span><span class="p">?</span><span class="o">.</span>
<span class="nf">viewController</span><span class="p">(</span><span class="nv">forKey</span><span class="p">:</span> <span class="o">.</span><span class="n">from</span><span class="p">),</span>
<span class="o">!</span><span class="n">navigationController</span><span class="o">.</span><span class="n">viewControllers</span><span class="o">.</span>
<span class="nf">contains</span><span class="p">(</span><span class="n">viewController</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
<span class="k">if</span> <span class="n">viewController</span> <span class="k">is</span> <span class="kt">SubView1TableViewController</span> <span class="p">{</span>
<span class="nf">removeCoordinatorWhenViewDismissed</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>In this implementation of <code class="highlighter-rouge">navigationController(_:didShow:animated:)</code>, the <code class="highlighter-rouge">guard let</code> statement gets the <strong>ViewController</strong> that is being navigated away from, followed by checking that this viewController is no longer contained in the <em>navigationController</em>’s <em>viewControllers</em> variable.</p>
<p>Once this viewController is retrieved, the function checks if the viewController is of type <strong>SubView1TableViewController</strong>, if so, <strong>removeCoordinatorWhenViewDismissed</strong> will be called with <code class="highlighter-rouge">self</code> as a parameter.</p>
<p>Now, the last thing that needs to be done for the <strong>SubFlow1Coordinator</strong> to be removed from the <strong>MainViewCoordinator</strong> when the back button is tapped, is to add the following line of code to the <strong>init</strong> of <strong>SubFlow1Coordinator</strong> right before calling the <strong>start</strong> function.</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="n">navigationController</span><span class="o">.</span><span class="n">delegate</span> <span class="o">=</span> <span class="k">self</span>
</code></pre>
</div>
<p>What this does, is to assign <strong>SubFlow1Coordinator</strong> as the delegate of its <em>navigationController</em> variable, which makes the custom implementation of <code class="highlighter-rouge">navigationController(_:didShow:animated:)</code> be called once the back button of the <strong>SubView1TableViewController</strong> instance that the <strong>SubFlow1Coordinator</strong> is presenting.</p>
<p><img src="/assets/images/back-button-viewAndCoordinator.png" alt="Structure of sample coordinator app" /></p>
<p>With this implementation, the <strong>SubFlow1Coordinator</strong> will be removed from the <strong>MainViewCoordinator</strong>’s dictionary of child coordinators once the <strong>SubView1TableViewController</strong> is dismissed.</p>
<h3 id="subflow2coordinator-and-subview2viewcontroller"><strong>SubFlow2Coordinator</strong> and <strong>SubView2ViewController</strong></h3>
<p>Throughout this article, I have been describing the <strong>SubFlow1Coordinator</strong>, its behavior and its initialization of the <strong>SubView1TableViewController</strong> in great detail. When looking through the sample project, you will notice that the implementation of the <strong>SubFlow2Coordinator</strong> class is very similar to the implementation of <strong>SubFlow1Coordinator</strong>. Therefore, I won’t go through the second sub-flow coordinator in detail in this post. I would, however, like to point out one difference, in <strong>SubFlow2Coordinator</strong>’s function <strong>navigationWhenTappedButton</strong>, a storyboard is initialized for the view that the app should present, instead of following the pattern of initializing a view controller through its <strong>init</strong> providing it with a <em>xib</em> and a <em>bundle</em> parameter. The reason why I implemented it this way, was to provide a sample implementation of how the coordinator pattern can be used together with <em>storyboards</em>.</p>
<!-- - SubFlow2Coordinator is very similar
- Except from that it's using a StoryBoard instead of xib file when initializing detailsView -->
<h2 id="using-coordinators-with-storyboards">Using coordinators with storyboards</h2>
<p>So, let’s have a look at <strong>SubFlow2Coordinator</strong>’s implementation of the <strong>navigationWhenTappedButton</strong> function.</p>
<p><strong>navigationWhenTappedButton:</strong></p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">navigationWhenTappedButton</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">storyboard</span> <span class="o">=</span> <span class="kt">UIStoryboard</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="kt">Constants</span><span class="o">.</span><span class="kt">Storyboards</span><span class="o">.</span><span class="n">detailTableView</span><span class="p">,</span>
<span class="nv">bundle</span><span class="p">:</span> <span class="kc">nil</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">detailTableViewController</span> <span class="o">=</span> <span class="n">storyboard</span><span class="o">.</span><span class="nf">instantiateViewController</span>
<span class="p">(</span><span class="nv">withIdentifier</span><span class="p">:</span> <span class="kt">Constants</span><span class="o">.</span><span class="kt">Storyboards</span><span class="o">.</span>
<span class="kt">StoryboardIdentifiers</span><span class="o">.</span><span class="n">detailTableView</span><span class="p">)</span>
<span class="k">as!</span> <span class="kt">DetailTableViewController</span>
<span class="nf">navigate</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">detailTableViewController</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">preferredNavigationStyle</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>This function starts out retrieving a <strong>UIStoryboard</strong> by its name - declared as a constant in the app’s <strong>Constants</strong> struct.</p>
<p>Once the <em>storyboard</em> variable is set, it’s used to instantiate a view controller, using a string (also declared in the <strong>Constants</strong> struct) as its identifier of type <strong><em>DetailTableViewController</em></strong>.</p>
<p>When <em>detailTableViewController</em> has been created, the view is presented using the helper function <code class="highlighter-rouge">navigate(to:with:)</code> which is declared and implemented in the <strong>Coordinator</strong> protocol.</p>
<h3 id="limitations-using-storyboards-with-coordinators">Limitations using storyboards with coordinators</h3>
<p>As you may have noticed, there are a few limitations with the above implementation.</p>
<p>First of all, the view controller gets force casted to a <strong>DetailTableViewController</strong>. If this class, later on, gets renamed or if the type of the view that is being retrieved from the storyboard is changed, it won’t be picked up by the compiler and will, therefore, cause a crash when the view is being initialized during runtime.
<!-- However, if the *detailTableViewController* would have been created through an **init** (like any of the other view controllers in this sample project), the app wouldn't build until the issues have been resolved. --></p>
<p>Second of all, since there is no <strong>init</strong> available when initializing the <em>detailTableViewController</em> through the storyboard, the implementation doesn’t allow for dependency injection on initialization. This means that any variables included in the <em>detailTableViewController</em> instance which the coordinator should set, will have to be either declared as <strong>public</strong> variables and then be set after the <em>detailTableViewController</em> has been created, or be set as part of a <strong>public</strong> function, which can be called at a later stage.</p>
<p>There are several downsides to setting these variables at a later stage. The fact that the variables for a view are required to be declared as public leaves the variable exposed and can be changed from any other class in the app. The variables are also required to be given a default value, or alternatively, be an optional value, which adds logic to the code with would otherwise not be necessary, alternatively, the variables can be implicitly unwrapped optional variables (Natasha The Robot writes about this approach using <strong>prepareForSegue</strong> <a href="https://www.natashatherobot.com/ios-view-controller-data-injection-with-storyboards-and-segues-in-swift/">here</a>).</p>
<p>In addition, not using dependency injection at initialization of a class, means that any functions or callbacks handling the view’s navigational flow have to be set after the instance of the class has been created. This means that the view controller can’t use these functions to determine if a behavior should be available through the view that it controls or not. <strong>For example</strong>, in the sample project’s <strong>MainViewViewController</strong> the functionality of the view’s two buttons is being passed in through dependency injection and stored as local variables in the <strong>MainViewViewController</strong> instance. If the functionality of these variables are made optional, the view controller can decide whether the buttons should be displayed in the view depending on whether the variables <em>button1Tapped</em> and <em>button2Tapped</em> are nil or not. This means that it’s up to the <strong>MainViewCoordinator</strong> to decide if a functionality for the buttons should be provided, and depending on this decision, the view controller handles the logic of whether or not the buttons should be displayed.</p>
<!-- - Need the function to be exposed with public
- Need to set a default value of these variables or make them optional
- In addition Can't use dependency injection to control a view's behavior -->
<!-- ### Things to note -->
<!-- - Differences in adding coordinators to an existing app -->
<!-- - Using xibs vs storyboards -->
<!-- - Loss of dependency injection -->
<h2 id="reflections">Reflections</h2>
<p>This has been a long post, I really wanted to capture how I implement a coordinator pattern in detail.</p>
<p>I intended to expressed in great detail how the coordinator pattern works by elaborating on some of my previous posts on the topic, I hope that this post was able to capture that. Hopefully, this can help you implement coordinators in your next project.</p>
<p>Using coordinators instead of storyboard segues can be a relatively large change, it requires some initial setup code and, to some extent, a change of mindset. I do however think that, once the <em>coordinator</em> protocol has been initialized and the first view is created from a <strong>MainViewCoordinator</strong>, the pattern is easy to follow and to keep on building the rest of the app’s flows upon. I think that adding coordinators to a code base really helps for the decoupling of the project’s flow, view controllers and views, which, in its turn, adds to the reusability of the code.</p>
<p>If you want to learn more about the coordinator pattern, make sure to download the sample project and to look through the links below for further reading.</p>
<!-- - Unsure about using xibs instead of storyboards for UI to get the dependency injection benefit. -->
<!-- - Some people argue about the amount of code
- Once you have started adding the Coordinators it's straight forward to follow the pattern -->
<!-- - Adds a lot of flexibility and reusability of the viewController -->
<!-- - Can switch navigation behavior from one use case to another
- Can change behavior and UI on/off depending on the navigation behavior is available -->
<!-- - Delegation vs dependecy injection -->
<!-- - Need to make child coordinators to NSObjects to conform to UINavigationControllerDelegate -->
<h2 id="resources">Resources</h2>
<h4 id="sample-project"><strong>Sample project:</strong></h4>
<p><a href="https://github.com/malinsundberg/coordinator-pattern-sample-project">coordinator-pattern-sample-project on GitHub</a></p>
<h4 id="useful-links"><strong>Useful links:</strong></h4>
<ul>
<li><a href="/architectures/2017/08/29/Coordinators.html">An introduction to coordinators</a></li>
<li><a href="/architectures/2017/12/17/A-Coordinators-Responsibilities.html">A coordinator’s responsibilities</a></li>
<li><a href="http://khanlou.com/2017/05/back-buttons-and-coordinators/">Back Buttons and Coordinators - by Soroush Khanlou</a></li>
<li><a href="https://www.natashatherobot.com/ios-view-controller-data-injection-with-storyboards-and-segues-in-swift/">iOS: View Controller Data Injection with Storyboards and Segues in Swift - by Natasha The Robot</a></li>
</ul>In this post, I will outline how to implement the coordinator pattern in a new project. The post will include code snippets from this sample project that I created. Although the post is mostly focused on the actual implementation of the coordinators, I will also talk a bit about some of the considerations that I take when implementing a coordinator and the coordinator pattern. If you are unfamiliar with what the coordinator pattern is, I wrote an earlier post about it here. I also wrote this post, describing the coordinator components’ different responsibilities.A coordinator’s responsibilities2017-12-17T00:00:00+00:002017-12-17T00:00:00+00:00/architectures/2017/12/17/A-Coordinators-Responsibilities<!-- **The focus of this blog post is to outline what I see fits into the coordinator pattern in terms of responsibility and the separation of responsibility among an *app coordinator* and its different *child coordinators*. In this post I don’t intend to go into details about how the coordinator pattern works, instead, I have written a separate blog post about that [here](/architectures/2017/08/29/Coordinators.html).** -->
<!-- ## The key of coordinators
The key concept -->
<h3 id="which-components-are-included-in-a-coordinator">Which components are included in a coordinator?</h3>
<p>I think that an architectural pattern should work more as a guideline rather than a strict blueprint. However, I also do think it is important to have a general outline of which components fit into the coordinator pattern, before discussing the topic further.</p>
<p>The core component of the coordinator pattern is often referred to as the <em>app coordinator</em>. The app coordinator can be seen as an overarching parent coordinator, responsible for initializing <em>child coordinators</em> for our app’s different main flows.</p>
<p>Each child coordinator initializes and holds a reference to a <em>View</em> and the View’s <em>ViewController</em>.</p>
<p>The focus of this blog post is to outline what I see fits into these different coordinator components, in terms of responsibility and in terms of the separation of a parent coordinator and a child coordinator. If you want to read more about the relationship between the different coordinators, read my earlier post about coordinators <a href="/architectures/2017/08/29/Coordinators.html">here</a>.</p>
<!-- What components exist in the coordinator pattern
- App coordinator
- Child coordinators -->
<h3 id="what-should-be-included-in-a-coordinator">What should be included in a coordinator?</h3>
<p>In general, a common pattern that can be seen in a coordinator is that it contains the following basic components and functions:</p>
<ul>
<li>A <em>UIViewController</em> often named <em>root</em>, which acts as a root view controller</li>
<li>A <em>UINavigationController</em></li>
<li>An array or a dictionary often named <em>childCoordinators</em> which contains the different child coordinators that a coordinator may hold</li>
<li>A <strong><em>start</em></strong> and a <strong><em>stop</em></strong> function (more on these two below)
<!-- What a coordinator should contain? -->
<!-- - An array/dictionary of potential child coordinators -->
<!-- - A root navigation view controller -->
<!-- A *start* function responsible for initialising and presenting a *View* which the coordinator is responsible for. -->
<!-- - A start method -->
<!-- - A stop method --></li>
</ul>
<!-- A *stop* function responsible for deinitialising the View that the coordinator holds and potentially deinitialise it self to prevent memory leaks. -->
<h3 id="an-app---and-a-parent---coordinators-responsibility">An app - and a parent - coordinator’s responsibility</h3>
<p>Apart from containing the variables and methods outlined above, the app coordinator also includes a <em>UIWindow</em> variable which is the main window for displaying the app’s content.</p>
<p>An app coordinator is usually initialized by the app’s <em>AppDelegate</em> and is responsible for initializing and setting the app’s root view controller (by setting the UIWindow’s <em>rootViewController</em> variable). It is also the app coordinators responsibility to set up the required child coordinators for the app’s different main screens and their flows.</p>
<p>In an app that has multiple screens, which have their own coordinators, the app coordinator functions as a parent coordinator, where its <strong>start</strong> function is responsible for initializing different child coordinators, each responsible for a specific screen and for this screen’s flows. When a parent coordinator initializes these child coordinators, it may provide it with a root ViewController by passing in its own root variable. Alternatively, when the parent coordinator is the app coordinator, it may assign one if the childCoordinators’ ViewController to be the app’s root ViewController. Once the child coordinator is initialized, the parent coordinator may be responsible for calling the child’s start function (see below section for more information about what the child coordinator’s start method does). A parent coordinator’s start functionality is visualised in this diagram:</p>
<p><img src="/assets/images/Parent-coordinator-start-function.png" alt="The parent coordinator's start function visualized" /></p>
<!-- When initializing these child coordinators, the app coordinator's root variable is often provided to the child coordinator to function as the child coordinators' root view controller. Once the child coordinator is initialized, the parent coordinator may be responsible for calling the child's start function (see below section for more information about what the child coordinator's start method does). -->
<p>A parent coordinator’s <strong>stop</strong> method is responsible for de-initializing a specific child coordinator in order to prevent memory leaks.</p>
<!-- An app coordinator’s responsibility: -->
<!-- - Initialised by the app delegate
- Responsible of initialising the main view’s child coordinators -->
<h3 id="a-child-coordinators-responsibility">A child coordinator’s responsibility</h3>
<p>Generally, a child coordinator contains a <em>UIViewController</em> which is being presented to the user. The child coordinator’s <strong>start</strong> function is responsible for initializing this ViewController, by providing its required resources through dependency injection. Once this ViewController is initialized, the child coordinator presents the ViewController. If the ViewController requires a <em>Model</em> object or a <em>ViewModel</em>, it’s the coordinator’s responsibility to provide these objects, or alternatively, provide the ViewController with a way to retrieve this data - for example by passing in a service function (which for example accesses our <em>Core Data</em> database or executes network requests) to the ViewController.</p>
<p><img src="/assets/images/Child-coordinator-start-function.png" alt="The child coordinator's start function visualized" /></p>
<p>One of the core responsibilities of a child coordinator is to provide its ViewController with navigational logic. For example, if we display a list of items in a <em>UITableView</em>, and each of the TableView cells are tappable, it’s the child coordinator’s responsibility to provide the TableViewController with the navigational logic of how to route from the TableView to the detail view. This can either be done by delegation or by passing the navigational functionality to one of the ViewController’s local values when initializing the ViewController.</p>
<p>A child coordinator’s <strong>stop</strong> function is responsible for de-initializing the ViewController it holds and potentially de-initialize itself.</p>
<!-- Each child coordinator
A coordinators responsibility:
- Provide a ViewController with necessary dependencies through dependency injection
- Potentially provide a model, a view model or a data layer method
A child coordinator’s responsibility:
- Initialise the ViewController that we want to present
- This ViewController may be contained on a class level -->
<h3 id="a-childparent-coordinator">A child/parent coordinator</h3>
<p>Note that the above description of a coordinator distinguishes between a parent and a child coordinator, where the app coordinator is a parent coordinator. I decided to outline the responsibility of the two coordinator types as two separate entities in order to make a clear distinction between the different coordinator types’ responsibilities. However, when I’ve used the coordinator pattern, the separation is seldom this clear. In many cases, a child coordinator may also be a parent coordinator. For example, if we initialize a child coordinator for our main view from our app coordinator, the main view may also have different sub-views with different navigation flows, these sub-views may be initialized and handled through two different child coordinators initialized and held by the main view coordinator. In this scenario, we would have three layers of coordinators, the app coordinator (a parent coordinator) the main view coordinator (a child coordinator, as well as a parent coordinator) and the main view’s two child coordinators.</p>
<p><img src="/assets/images/Parent-child-coordinator_diagram.png" alt="A child/parent coordinator visualized" /></p>
<p>When I have used the coordinator pattern, I haven’t found it necessary to determine a strict rule around whether a coordinator needs child coordinators or not. I found that it’s something to decide on case-by-case bases. If a coordinator’s view should navigate to a different view, which in its turn requires navigational logic, it may be worthwhile to include an additional layer of coordinator logic. If the navigational logic is as simple as just displaying an alert view, it might not be necessary to include a coordinator for this simple logic. What level of complexity we wish to apply to our coordinator pattern may be decided on by considering the navigational needs for a specific view in a pragmatic way.</p>
<p><!-- child coordinator is responsible for a ViewController, which can navigate to and display two different ViewsControllers, which in there terms have their independent navigation flow to different views, this may require each of the view flows to have their own coordinator, which makes our initial coordinator both a child coordinator as well as a parent coordinator. --></p>
<!-- ## What is not a coordinator's responsibility?
What is not in a coordinator?
- Direct network requests
- May initialise a tmp loading vc to handle network requests - see swift talks example -->
<!-- #### **Useful links with code samples:**
- [Flow Coordinators in iOS - by Dennis Walsh](https://medium.com/@dkw5877/flow-coordinators-333ed64f3dd)
- [The Coordinator Pattern - by I am Simme](https://www.iamsim.me/the-coordinator-pattern/) -->An introduction to coordinators2017-08-29T00:00:00+00:002017-08-29T00:00:00+00:00/architectures/2017/08/29/Coordinators<p><strong>This post will introduce the concept of <em>coordinators</em>, and how they can be used beneficially in an iOS application. This post is part of a series of posts about iOS architectures, if you are interested in reading more about additional architectural patterns, check out my articles about “<a href="/architectures/2017/06/28/VIPER.html">VIPER</a>” and about “<a href="/architectures/2017/08/26/MVVM.html">MVVM</a>”. The coordinator pattern works great in combination with the MVVM architecture.</strong></p>
<p><img src="/assets/images/Coordinator.png" alt="Coordinator" /></p>
<p>The coordinator pattern introduces a new component to an iOS project - the <em>coordinator</em>. The core responsibility of a <em>coordinator</em> is to handle the application’s <strong>view creation</strong> and the <strong>flow logic</strong> between the app’s different screens.</p>
<p>A common issue in an iOS project, using the <em>MVC</em> pattern, is that the <em>Controller</em> is both responsible for handling its own <em>View</em> - by implementing a <em>View</em>’s delegate and data source methods - as well as creating other <em>Views</em> and handle the routing logic between these different <em>Views</em> and <em>ViewControllers</em>. This makes it difficult to reuse a <em>ViewController</em> in a different flow. This also contributes to code entanglement - making it difficult to read the code, to test the app’s behavior and to follow the single responsibility principle. This is where the <em>coordinators</em> can be really helpful.</p>
<h3 id="how-do-the-coordinators-work">How do the Coordinators work?</h3>
<p>A <em>coordinator</em> is responsible for creating a <strong>specific</strong> screen in our app. To do this, the <em>coordinator</em> will first take the responsibility of retrieving all the dependencies that are required for the specific screen that we want to display - this includes retrieving the <em>Models</em> that we want to display in a screen. Secondly, the <em>coordinator</em> will initialize the <em>ViewController</em> that we need for the specific screen, when initializing the <em>ViewController</em>, the <em>coordinator</em> will use dependency injection to provide the <em>ViewController</em> with its dependencies. Once this <em>ViewController</em> has been initialized, the <em>coordinator</em> will present the newly created <em>ViewController</em>.</p>
<p>Above I just described how a <em>coordinator</em> is responsible for a specific screen in our application. There are also other benefits and use cases of <em>coordinators</em>; in an app, we can have a main <em>coordinator</em> often referred to as the <em>AppCoordinator</em>. This <em>AppCoordinator</em> is responsible for creating our initial screen and can be really useful for a more complex app which contains multiple screens, which each have different navigation flows. An example of where the <em>AppCoordinator</em> provides us with benefits is an app that contains a tab bar, with different screens for each tab, which all contain their own <strong>navigation flow logic</strong>. An <em>AppCoordinator</em> is our initial <em>coordinator</em>, which is often initialized by the app’s <em>AppDelegate</em> class. This <em>AppCoordinator</em> is responsible for creating <em>ChildCoordinators</em> - which are the <em>coordinators</em> that are responsible for the creation and the navigation for a <strong>specific</strong> screen, as described above.</p>
<p><img src="/assets/images/Coordinator_diagram.png" alt="Relationship Between The Coordinators Visualized" /></p>
<h4 id="using-coordinators-to-improve-the-structure-of-our-viewcontroller"><strong>Using coordinators to improve the structure of our <em>ViewController</em></strong></h4>
<p>In the section above I have described how a <em>coordinator</em> is used for initializing our main screens and <em>ViewControllers</em> in a tab bar. Using coordinators can also help us to move navigation logic out of our <em>ViewControllers</em>.</p>
<p>For example, if we have a <em>View</em> which contains a button which should trigger the navigation to a different view when it’s tapped, our <em>ViewController</em> will need to retrieve the dependencies for this new <em>View</em> and its <em>ViewController</em>, then it needs to create the <em>ViewController</em>, and then present the new <em>ViewController</em>. If we have a <em>coordinator</em> which is responsible for creating this initial <em>ViewController</em>, we can also control the <em>ViewController</em>’s navigation behavior for when the button is tapped from our <em>coordinator</em>. This is done by defining the navigation logic and the behavior of the button tap in our <em>coordinator</em>. Once this logic is defined, we can either assign the <em>coordinator</em> to be the delegate of the <em>ViewController</em>, or we can pass our button’s navigation functionality in as a parameter to the <em>ViewController</em> on its initialization, this passed in functionality can then be utilized by the <em>ViewController</em>.</p>
<!-- Mention that the AppCoordinator holds an array?
Mention the flow logic and which coordinators are created depending on the requirements? Login checking? -->
<!-- * Main coordinator - AppCoordinator
* Child coordinators -->
<!-- * Responsibility of a coordinator -->
<h3 id="the-benefits-of-the-coordinators">The benefits of the coordinators</h3>
<p>Introducing <em>coordinators</em> to our iOS architecture gives us several benefits.</p>
<p>First of all, since a <em>coordinator</em> takes on the responsibility of creating <em>ViewControllers</em>, creating their dependencies, and are responsible for presenting these <em>ViewControllers</em>, we are able to consolidate the dependency retrieval and the initialization of a new view in one place.</p>
<p>A <em>coordinator</em> which is responsible for the navigation logic to a specific <em>ViewController</em> in our app can also handle navigation from this <em>ViewController</em> to another view. This means that the logic of navigating from one <em>ViewController</em> to an other, which used to live in the <em>ViewController</em> is being handled by our <em>coordinator</em> instead. This is specifically beneficial when our navigation logic is more complex and if it depends on a state; for example, a user’s login state.</p>
<p>Separating the navigation logic away from the <em>ViewController</em> also makes our <em>ViewController</em> more reusable. We may want to reuse a <em>ViewController</em> which contains a button, but in one use case we want the button to lead to one view, and in a different use case, we may want to display a different view when the button is tapped. By separating out our navigation logic into the <em>coordinator</em> our <em>ViewController</em> does not have to contain any case validation to handle the button tap, instead, we can have two different <em>coordinators</em> for the two instances of the <em>ViewController</em>, each containing their own, separate navigation logic while reusing one <em>ViewController</em>.</p>
<p>Apart from moving code out of our <em>ViewControllers</em> and consolidating our navigation logic, the <em>coordinators</em> also contribute to a more light weight <em>AppDelegate</em>. Earlier in this post, I describe the responsibility of an overarching <em>AppCoordinator</em> and its initialization of its <em>ChildCoordinators</em> for an app with a tab bar. The logic of creating the different <em>ViewControllers</em> for a tab bar would usually be contained in the <em>AppDelegate</em>, when using the <em>coordinator pattern</em> we can instead consolidate the creation of our <em>ViewController</em>’s and the presentation of the <em>ViewController</em>’s within one dedicated class.</p>
<h4 id="useful-links"><strong>Useful links:</strong></h4>
<p>Soroush Khanlou has some great posts about the coordinator pattern, if you want to read more in-depth information about this pattern, I would recommend he’s “Coordinators Redux” post.</p>
<ul>
<li><a href="http://khanlou.com/2015/01/the-coordinator/">The Coordinator - by Soroush Khanlou</a></li>
<li><a href="http://khanlou.com/2015/10/coordinators-redux/">Coordinators Redux - by Soroush Khanlou</a></li>
</ul>
<!-- So far, we have given the responsibility of creating and navigating to a *ViewController*, we can also use the *coordinator* to navigate from one view to another view. This is useful to -->
<!-- * Benefit of coordinators -->This post will introduce the concept of coordinators, and how they can be used beneficially in an iOS application. This post is part of a series of posts about iOS architectures, if you are interested in reading more about additional architectural patterns, check out my articles about “VIPER” and about “MVVM”. The coordinator pattern works great in combination with the MVVM architecture.What is MVVM?2017-08-26T00:00:00+00:002017-08-26T00:00:00+00:00/architectures/2017/08/26/MVVM<p><strong><em>This is the second post in a series of posts about iOS project architecture. Check out my previous post “<a href="/architectures/2017/06/28/VIPER.html">What is VIPER?</a>” if you are interested in learning more about different iOS architectures.</em></strong></p>
<p>In this post, I will introduce the <em>MVVM</em> architectural pattern and how it can be used in an iOS project. I will start out with a short introduction of the core concepts of <em>MVVM</em>. After that, I will go through its different components in more detail. Once I have outlined the architecture’s different components and their functionalities, I will present a more detailed description of the relationship between the different components in <em>MVVM</em>.</p>
<h4 id="mvvm---a-short-introduction"><strong><em>MVVM</em> - A short introduction</strong></h4>
<p><em>MVVM</em> stands for three architectural components; the <em>Model</em>, the <em>View</em> and the <em>ViewModel</em>. The <em>ViewModel</em> is a key component in <em>MVVM</em> which differentiates it from the commonly used <em>MVC</em> pattern. The use of a <em>ViewModel</em> provides a clear separation between an application’s <strong>business logic</strong> and its <strong>application logic</strong> (its UI layout related logic).</p>
<p>In <em>MVC</em> the <em>Controller</em> can have a direct relationship with a <em>Model</em>, which means that the <em>Controller</em> is responsible for both the layout related logic, the data retrieval and model manipulation logic, as well as the application’s business logic that needs to be applied to the <em>Model</em> for the specific screen. The <em>ViewModel</em> in <em>MVVM</em> changes this relationship between the <em>Controller</em> and the <em>Model</em>.</p>
<p>A core principle of <em>MVVM</em> is that the <em>View</em> and the <em>Model</em> are not aware of one another. Instead, the <strong><em>ViewModel</em></strong> works as a mediator between the <em>View</em> and the <em>Model</em> to supply the <em>View</em> with the data it needs, correctly formatted for a specific use case, in accordance with the app’s business logic. The diagram below gives us a visual representation of the components’ relationship, which will be described in more details throughout this article.</p>
<p><img src="/assets/images/MVVM_diagram.png" alt="Relationship Between MVVM's Components Visualized" /></p>
<h4 id="how-mvvms-components-interact-with-one-another---a-simple-example"><strong>How <em>MVVM</em>’s components interact with one another - A simple example</strong></h4>
<p>Let’s say that we want to display a list of blog posts in an app, these blog posts have a publish date. According to our business logic, we should display the number of days that have passed since the blog post was published in a text label. In the app, we have a <em>Model</em>, which contains variables about a blog post including the <em>Date</em> variable representing the blog post’s publish date. This <em>Model</em> is accessed by a <em>ViewModel</em> which contains our business logic. The <em>ViewModel</em> contains a function that compares the stored publish date with today’s date and calculates how many days have passed since the post was published, from this calculation, the <em>ViewModel</em> creates a <em>String</em> which represents the number of days that have passed since the post was published - for example, <strong>“2 days”</strong> - this <em>String</em> is being returned by the function. To display the blog post we have a <em>View</em> which uses the timestamp value returned by the function in our <em>ViewModel</em> to display the number of days passed since the post was published inside of a text label. This example expresses the core relationship between the components in <em>MVVM</em>.</p>
<h4 id="a-few-benefits-of-mvvm"><strong>A few benefits of <em>MVVM</em></strong></h4>
<!-- Let's add the dependency injection and the testability info here!! -->
<p>Using the <em>MVVM</em> pattern in an application provides us with several benefits. By separating our app’s business logic and the application logic we enforce the single responsibility principle, where the app’s different classes are responsible for a specific, single behavior. The responsibility of the <em>ViewModel</em> in our example above is to apply logic which determines which <em>String</em> the function should return. While the <em>View</em> described above is responsible for determining which label should display our timestamp string.</p>
<p>By following the single responsibility principle, we also add testability to our application, since we can test a specific functionality related to our business logic, independently from UIKit and from our app’s view layout related functionality.</p>
<!-- ### Why use MVVM?
- Reusability, readability and testability
- MVVM is useful for making the ViewController more readable by separating out some logic that's not directly related to the viewController logic. Also useful to make the logic (presentation logic) in the ViewModel easily testable -->
<!-- #### **MVVM, a brief history lesson**
----
Basic MVVM description
Origin of MVVM
More modern version, applicable to iOS development in combination with the current MVC structure -->
<h3 id="mvvm-in-ios"><em>MVVM</em> in iOS</h3>
<!-- Add this!!!! -->
<!-- - A ViewModel is created and provided to a ViewController through dependency injection
- composition pattern
- A viewModel's different variables are added on initialization
- Can value for a view model also be retrieved from network calls/later model data retrieval? -->
<p>When talking about MVVM in an iOS project the commonly used <em>UIView</em> and <em>UIViewController</em> are usually coupled within <em>MVVM</em>’s <em>View</em> component and is simply referred to as the <em>View</em>. In order to provide a more concrete overview of how the different components in <em>MVVM</em> look like in an iOS project, I have decided to split the <em>View</em> section below up into a <em>UIView</em> and a <em>UIViewController</em> section.</p>
<h3 id="model"><em>Model</em></h3>
<p>Like in MVC, a <em>Model</em> is a representation of the application’s data. An app may have multiple <em>Models</em>. A <em>Model</em> may simply be a Struct or a Class which contains variables that represent values for a specific data object, a <em>Model</em> may also be a <em>Core Data</em> entity.</p>
<h3 id="view"><em>View</em></h3>
<p>As mentioned above, the <em>View</em> component’s responsibility in an iOS project is split between the <em>UIView</em> and the <em>UIViewController</em>. Its joint responsibility is to provide the application with a visual element, that a user can interact with.</p>
<h4 id="uiview"><strong><em>UIView</em></strong></h4>
<p>The <em>UIView</em> is the component that is visible to a user, which the user can interact with directly. It provides the user with an interface to obtain information from and to enter information to our application.</p>
<h4 id="uiviewcontroller"><strong><em>UIViewController</em></strong></h4>
<p>The <em>UIViewController</em> (or simple <em>ViewController</em>) goes hand in hand with the <em>UIView</em>. The <em>ViewController</em> is simply, as the name suggests, the controller of the <em>UIView</em>. Its job is to handle user input events and to determine how the <em>UIView</em> should behave to provide user feedback. The <em>ViewController</em> contains all the <em>UIKit</em> specific logic and all the logic related to which of the <em>UIView</em>’s different components should display what. The <em>ViewController</em> is responsible for the <em>UIView</em>’s <em>Delegate</em> and <em>Datasource</em> methods. For a <em>UITableView</em> for example, the associated <em>ViewController</em>’s responsibilities include things like determining the section and row count for the UIView, determining what should be displayed in the tableView’s different cell elements and the <em>UITableView</em>’s navigation bar buttons’ behaviors.</p>
<h3 id="viewmodel"><em>ViewModel</em></h3>
<p>Okay, so this is where <em>MVVM</em> differentiate from <em>MVC</em>, with the added <em>ViewModel</em> component. The <em>ViewModel</em> contains the presentation and the business logic required for our application. It’s the <em>ViewModel’s</em> responsibility to contain the <em>Models</em> that are required for a specific screen in the app, as well as handling formatting of these <em>Model</em>’s data in accordance with the app’s business logic. The <em>ViewModel</em> works as a mediator between the app’s <em>Model</em> and the app’s <em>View</em> component.</p>
<p>A key differentiator between a <em>ViewModel</em> and a <em>Controller</em> is that the <em>ViewModel</em> is independent of any UI logic. This means that we should not have to import UIKit to our <em>ViewModel</em> (except for in rare edge cases, for example; when the <em>ViewModel</em> requires access to UIColors which depend on UIKit).</p>
<p>What differentiates the <em>ViewModel</em> from a <em>Model</em> is that the <em>ViewModel</em> contain functions for data manipulation, formatting of data, presentation logic application, and the business logic that we need to apply before displaying data.
<!-- which may be required to be applied to the values contained in a *Model*, by a specific *View* before the information is being displayed. -->
<!-- - Provides the data in a format that is required for a view to display the data --></p>
<h4 id="back-to-our-previous-example"><strong>Back to our previous example</strong></h4>
<p>In the example earlier in this post we wanted to display a blog post and a label with the time that passed since a post’s publish date. In the example, I simply describe the functionality of the <em>View</em> as a single component of <em>MVVM</em>.</p>
<p>I would like to expand on this example in more detail. If we separate the example’s <em>View</em> into a <em>UIView</em> and a <em>UIViewController</em> the <em>UIViewController</em>’s responsibility is to utilize the value representing the timestamp provided by our <em>ViewModel</em>. It’s the <em>UIViewController</em>’s responsibility to determine which UI element that should display the value provided by the <em>ViewModel</em>. The <em>UIView</em>, on the other hand, is simply the visual component that contains different labels which are directly visible to the user. Since the <em>UIView</em> might contain multiple labels it’s the <em>UIViewController</em>’s responsibility to decide which of these labels that should display the value retrieved from the <em>ViewModel</em> and assign the value to the <em>UIView</em>’s specific text label.</p>
<h3 id="where-do-the-network-calls-go">Where do the network calls go?</h3>
<p>In <em>MVVM</em> there is not an independent component that is specifically dedicated to network requests and data parsing. For the sake of code reusability and to follow the single responsibility principle, we can separate the network related functionality out to one or several <em>helper classes</em>. These <em>helper classes</em> will be responsible for the direct network calls.</p>
<p>However, we will still need to determine which of the components in our <em>MVVM</em> application should interact with these <em>helper classes</em>. Our <em>ViewModel</em> is responsible for containing our app’s business logic, in order to enforce testability and single responsibility we should try to keep this business logic as independent as possible. We want the <em>ViewModel</em> to have a minimum amount of dependencies, and we want it to be responsible for accessing and handling data models that we already have retrieved. To fulfill these preferences, we will interact with our <em>network helpers</em> from our <em>ViewController</em>.</p>
<!-- A core principle of *MVVM* is to have a clean *ViewController*, which is responsible for the app's UI components. The *ViewModel*, on the other hand, is responsible for the business logic and for the data manipulation. Therefore, the more natural component to contain the network request initialization and data handling is the *ViewModel*. In this way, we continue to have a clear separation between the *ViewController's* UI layout and updating, and the business logic, the relevant data interaction, and data handling that are handled by the *ViewModel*. -->
<p><!-- - May be added to the ViewModel since it is the components that is directly communicating with a model. Therefore, if a network call is made to retrieve data and we want to store this data in a model, it makes sense to have the network calls in the viewModel to be able to directly add data to a Model -->
<!-- - It also makes since to add the network calls to the ViewModel to keep the ViewController's responsibility focused on UI Layouts and styling --></p>
<h3 id="the-different-components-relationship">The different components’ relationship</h3>
<p>Now when we know what the different components of MVVM are responsible for, let’s go through what the relationship between these components looks like.</p>
<p>An app often contains different screens which provide the user with different functionalities, the screens have different responsibilities with different looks and feels. The same thing applies to the app project’s MVVM components. A project usually contains multiple <em>Models</em>, <em>Views</em>, and <em>ViewModels</em> which have their own functionalities and responsibilities. We combine a specific UIView with a specific UIViewController to display information to a user in a specific <em>View</em>. The formatted information that is being displayed in the <em>View</em> is retrieved from a specific <em>ViewModel</em> and the data that the <em>ViewModel</em> is formatting is often sourced from one or several specific <em>Models</em>.</p>
<p><img src="/assets/images/MVVM_ProjectStructure.png" alt="MVVM Project Structure" /></p>
<p>The graph above demonstrates the relationship between the different components in <em>MVVM</em>.</p>
<p>In <em>MVVM</em>, the <em>View</em> contains a reference to a <em>ViewModel</em> and has access to the variables and functionalities that this <em>ViewModel</em> provides. The <em>ViewModel</em> however, is not aware of the <em>View</em> and does not communicate directly to the <em>View</em>. This means that the <em>View</em> and the <em>ViewModel</em>’s relationship is unidirectional.</p>
<p>Our <em>ViewModel</em> in <em>MVVM</em> has a direct relationship with a <em>Model</em> and can access the values held by the <em>Model</em>.</p>
<p>There is no direct relationship between the <em>View</em> and the <em>Model</em> components in <em>MVVM</em>. A <em>View</em> that requires data from a <em>Model</em>, contains a <em>ViewModel</em> which it can interact with to retain the <em>Model</em>’s data in the format that the specific <em>View</em> requires it in. This is where the <em>ViewModel</em> works as a mediator between the <em>View</em> and the <em>Model</em>.</p>
<!-- ### A more advanced MVVM use case
In some cases the data that should be displayed and accessed in a specific screen may be more complex than the structure outlined in the previous section. Let's say that we have an app which contains three different screens, one contains information related to a user, another screen contains information about an address, and a third screen displays information about the user as well as about the address. The first two screens are composed of their own *Model*, *View* and *ViewModel*. The third screen, however, only needs a specific *View* components, while as the *Models* and the *ViewModels* that the screen requires already exists from the previous two screens. In this scenario, we will have a ViewController, which contains the *UserViewModel* as well as the *AddressViewModel*. Even though the composition of components look slightly different in this scenario, the core relationship between the different components remain the same as in the simpler screens - The *View* contains the *ViewModels* while each of the *ViewModels'* have direct relationships with the relevant *Models*, and the variables stored by these *Models*.
The graph below demonstrates a more advanced project structure using MVVM.
![MVVM Advanced Project Structure](/assets/images/MVVM_AdvancedProjectStructure.png) -->
<!-- - A ViewController may have multiple viewModels if the data is represented through composition
- For example, if a view displays both user information and address information, and this data is independent from one another, a viewController may contain two different viewModel. The separate userViewModel and addressViewModel may be used by other view, separately -->
<!-- - A ViewModel may contain separate ViewModels and work like a wrapper -->
<!-- - The V includes both the View and the ViewController -->
<!-- - The view and the ViewController is often tightly coupled in MVC, therefore, the MVVM pattern sees this as one components, and adds an additional component - ViewModel -->
<!-- - The viewModel is independent from any view setup and layout logic -->
<!-- - ViewModel works as a mediator between the Model and the ViewController -->
<!-- - ViewModel is UIKit independent -->
<!-- - ViewModel handles business logic -->
<!-- - The View and the Model are not aware of one another -->
<!-- - A View communicates with the ViewModel, the ViewModel communicates with the Model -->
<!-- - A viewModel is not aware of the viewController that contains it -->
<!-- - A ViewController that requires data from a model, contains at least one ViewModel. This viewModel is responsible for retrieving and formatting the data that the ViewController uses from a Model -->
<!-- **Moving on from basic iOS MVVM to data binding with Reactive programming**
**Further use cases and benefits of MVVM with Reactive programming or via a delegate pattern** -->
<h4 id="useful-links"><strong>Useful links:</strong></h4>
<ul>
<li><a href="https://www.objc.io/issues/13-architecture/mvvm/">Introduction to MVVM - by objc.io</a></li>
<li><a href="http://samwize.com/2016/07/26/mvvm-for-ios-and-swift/">MVVM for iOS & Swift - by samwize</a></li>
</ul>
<!-- #### **Further reading:**
- [MVVM Tutorial with ReactiveCocoa: Part 1/2 - by raywenderlich.com](https://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1) -->This is the second post in a series of posts about iOS project architecture. Check out my previous post “What is VIPER?” if you are interested in learning more about different iOS architectures.What is VIPER?2017-06-28T00:00:00+00:002017-06-28T00:00:00+00:00/architectures/2017/06/28/VIPER<p><strong><em>This is the first post in a series of posts about iOS project architecture. In these posts I do not intend to go into details about the architectural patterns’ pros and cons, instead, the focus will be on outlining different architectural structures, which may be applied in an iOS project. I do however intend to write a more opinionated piece as a summary/conclusion for the different concepts introduced throughout this series later on.</em></strong></p>
<p>In this post, I will introduce the VIPER architectural pattern. VIPER may be used as a design pattern on a variety of platforms, in this post, I will be focusing on using VIPER in an iOS project.</p>
<p><strong><em>VIPER</em></strong> stands for the different components of the architectural pattern; <em>View</em>, <em>Interactor</em>, <em>Presenter</em>, <em>Entity</em> and <em>Routing</em>. The core principle of VIPER is to separate the app’s functionality into these different components, in order to achieve low coupling between the app’s different components and to follow the single responsibility principle.</p>
<p>Apart from the components included in VIPER that are mentioned above, the VIPER pattern also takes use of helpers, which manages the logic between external sources, such as a database, and the iOS application, these components can be referred to as <em>Network Managers</em>.</p>
<h3 id="vipers-different-components">VIPER’s different components</h3>
<p>To start off, I will go through the different components in VIPER and their responsibilities. While describing VIPER’s different components, I will provide examples of where to find the different components in a traditionally set up MVC iOS project (where applicable).</p>
<p>Once the components have been introduced, I will focus on how the different components come together in a project and how the components relate to one another.</p>
<p><img src="/assets/images/VIPER_ProjectStructure.png" alt="VIPER Project Structure" /></p>
<h3 id="view"><em>View</em></h3>
<p>The view is responsible for displaying information to the user of the app. Since the view is what the user sees, this is an important component which provides the user with a direct interface to the application - in a traditional iOS project, this may be a view in a storyboard or in a .xib file. The view is therefore also responsible for providing the app with a way for a user to input information.</p>
<!-- Displayed information to a user
Open for user input
The user's direct path to an application -->
<h3 id="interactor"><em>Interactor</em></h3>
<p>The interactor contains the app’s business logic of how to handle data. The interactor is not directly responsible for retrieving data from a server, this is often allocated to one or several <em>Network Managers</em>. However, the interactor is responsible for interacting with these <em>Network Managers</em>. Since a specific app may require data to be retrieved from multiple, different data sources, the interactor may initialize network requests through multiple, different network managers. It’s up to the interactor to retrieve the required data for the app’s specific use case, from the different data points, according to the app’s business logic. Once data has been retrieved from all external servers via the network managers, the interactor handles any data manipulation that may be necessary.</p>
<p><strong>Note:</strong> If you are familiar with a modern MVVM architecture, the responsibility of an interactor may be compared to the responsibility of MVVM’s ViewModel.</p>
<!-- - Contains business logic of what to do with data
- Data manipulation
- Interacts with fetchers and managers to retrieve data from a server -->
<h3 id="presenter"><em>Presenter</em></h3>
<p>The presenter’s responsibility is to apply the logic of how content should be displayed. The presenter uses the data provided by the interactor and then applies the necessary logic of how this data should be presented in a view. The presenter is also responsible for the logic of how the application should respond to user inputs and user interactions. This responsibility is often given to a <em>ViewController</em> in the context of an iOS project.</p>
<!-- - View logic how content should be displayed
- Response to user input
- Calls interactor methods -->
<h3 id="entity"><em>Entity</em></h3>
<p>An entity is a data storage model. This can either be a persistent storage model - such as a <em>Core Data</em> object - or it can be a more temporary storage model - such as a <em>Struct</em>, <em>Class</em> or an <em>Enum</em>. The entity is not supposed to contain any logic related to formatting of data before displaying it, neither should it contain logic about how to retrieve the data (e.g. network request). An entity simply contains variables that are specific to the model it represents. The responsibility of how to display the data of an entity is instead given to the presenter, and a network manager is responsible for how to retrieve data.</p>
<!-- - Basic data models
- Could be a CoreData model
- Doesn't contain any data manipulation logic -->
<h3 id="routing"><em>Routing</em></h3>
<p>At last, the routing component is responsible for the logic required for, and the navigation between the app’s different views. This component describes what is required to display each of the app’s views. Once all the dependencies required for a specific view is provided/created, routing initializes the view, providing these dependencies (this is called dependency injection) and then presents the view.</p>
<!-- - Responsible for the navigation logic between different views
- Describes what is required for each of the views to be displayed -->
<p><strong>Note:</strong> The routing component takes the responsibility of navigating between different views, this is a responsibility that is traditionally split between a storyboard segue and a ViewController (in a prepareForSegue function). An app that’s using the VIPER architecture therefore usually doesn’t contain any segues between a storyboard’s different views.</p>
<!-- ### Using VIPER in an iOS app:
A ViewController is used for controlling a view
An Interactor can be used to initialize a network request
The networking code itself may be in a different part of the app, like a network manager.
Once the interactor has retrieve required data, the Presenter decides how this data should be presented and may format it to these requirements.
An Interactor also retrieves data objects from a data store, which it applies business logic to before it's provided to a Presenter, this also works the other way around, it gets data from a data store, and applies business logic to it, before placing it in a new/back into a data store. The persistence of data is not directly done by the Interactor, it's handled by a type of data manager helper.
- This helper is responsible both for fetching data from internal, persistent storage, as well as formulating network requests and retrieve data from external storage.
Storyboards may still be used for the view layer, but these storyboards do not contain segues (this is the routers' responsibility). -->
<h3 id="notable">Notable</h3>
<p><em>According to the VIPER architecture, no classes other than a data manager should have any awareness of Core Data, or of Core Data objects. Instead, a data manager class converts the Core Data object to a PONSO (Plain Old NSObject) before passing it to any other class, like an interactor class.</em></p>
<h3 id="using-modules-with-viper">Using Modules with VIPER</h3>
<p>A screen or a set of screens may be added to a <em>Module</em>. A module can simply be a folder in the project that contains the functionality required for a specific screen. The module pattern may be useful for replacing or reusing specific behavior for different platforms. For instance, if a specific functionality only exists for an iPad app, it is easily replaceable by a different module for an iPhone application.</p>
<h3 id="what-will-this-structure-look-like-in-an-ios-project">What will this structure look like in an iOS project?</h3>
<p>So far through this article, I have identified the different components of VIPER, as well as these components’ different responsibilities. Let’s go through how these components interact with one another and how they fit together in a project in more detail.</p>
<p><img src="/assets/images/VIPER_diagram.png" alt="VIPER Components Visualized" /></p>
<p>The fact that each of the components in the VIPER model are dedicated to a specific task, makes it easy for us to combine the components to fulfill a task required for the app to function, as well as re-using the components in different parts of the app. As the diagram above demonstrates, the different components interact with one another, to reach a specific goal.</p>
<p>While the <em>View</em> provides a user with a specific screen of the app, the <em>Presenter</em> is playing an important role in handling decision making of how data should be displayed in a view and what to do with data that a user enters to a view. The presenter gets data that should be displayed in a specific view from the <em>Interactor</em> and formats the data before it’s being displayed in the view. When the user of our app interacts with the view, it’s the presenter’s responsibility to decide how the view should change, to provide the user with necessary feedback.</p>
<p>If the user input should require being stored for later retrieval, the presenter forwards the data to an interactor. The interactor decides how the data should be formatted by applying relevant business logic, before either handing it over to a network manager (for external storage of the information) or to an <em>Entity</em>.</p>
<p>An app often contains multiple screens, with different functionalities, dedicated to fulfilling a specific use case. Each of these screens (or a set of related screens) are each made up of a <em>View</em>, an <em>Interactor</em>, a <em>Presenter</em>, an <em>Entity</em> and a <em>Routing</em> component, which combined can be referred to as a <em>Module</em>. Since some screens may require the same entities or the same interactor as a different screen, a VIPER component may be reused across different modules.</p>
<p><em>Routing</em> can exist on different levels within the application. There can be a router specific for a module, providing the navigation between a collection of screens. A router may also exist on higher, more overarching app level, providing the navigational functionality between the apps higher level, main views (for instance, the creation of views and the routing to these views, from a tab bar).</p>
<!-- ***This article has outlined the main components of the VIPER architecture and their responsibilities. The article has also described how these different components interact with each other in greater detail, to form a set of modules.*** -->
<!-- VIPER as an architecture may be seen to be relatively complex in comparison to a traditional MVC structure. However, I think that it's valuable to be aware of the concept -->
<!-- Multiple sets of VIPER components forms an app -->
<!-- An app often contains multiple screens, with different functionality. Each of these screens' functionalities is provided to the user through a dedicated View -->
<h4 id="useful-links"><strong>Useful links:</strong></h4>
<ul>
<li><a href="https://www.objc.io/issues/13-architecture/viper/">Architecting iOS Apps with VIPER - by objc.io</a></li>
<li><a href="https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52">iOS Architecture Patterns - by Bohdan Orlov</a></li>
<li><a href="https://blog.mindorks.com/building-ios-app-with-viper-architecture-8109acc72227">Building iOS App With VIPER Architecture - by Amit Shekhar</a></li>
</ul>This is the first post in a series of posts about iOS project architecture. In these posts I do not intend to go into details about the architectural patterns’ pros and cons, instead, the focus will be on outlining different architectural structures, which may be applied in an iOS project. I do however intend to write a more opinionated piece as a summary/conclusion for the different concepts introduced throughout this series later on.