<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.6.2">Jekyll</generator><link href="https://mateuszkoslacz.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mateuszkoslacz.com/" rel="alternate" type="text/html" /><updated>2018-01-24T15:24:44+00:00</updated><id>https://mateuszkoslacz.com/</id><title type="html">Mateusz Koślacz Homepage</title><subtitle>My page and blog about mobile development and programming, both for Android and iOS, especially in VIPER architecture using Moviper.</subtitle><author><name>Mateusz Koślacz</name><email>contact@mateuszkoslacz.com</email></author><entry><title type="html">Moviper - the Android VIPER Library</title><link href="https://mateuszkoslacz.com/moviper-the-android-viper-library/" rel="alternate" type="text/html" title="Moviper - the Android VIPER Library" /><published>2017-02-08T07:38:09+00:00</published><updated>2017-02-08T07:38:09+00:00</updated><id>https://mateuszkoslacz.com/moviper--the-android-viper-library</id><content type="html" xml:base="https://mateuszkoslacz.com/moviper-the-android-viper-library/">&lt;p class=&quot;notice--warning&quot;&gt;&lt;strong&gt;iOS dev note:&lt;/strong&gt; There is also an iOS version of Moviper library that we successfully use in production environment, but it’s not yet open-sourced. Stay tuned to not to miss the iOS Moviper!&lt;/p&gt;

&lt;aside class=&quot;sidebar__right&quot;&gt;
&lt;nav class=&quot;toc&quot;&gt;
    &lt;header&gt;&lt;h4 class=&quot;nav__title&quot;&gt;&lt;i class=&quot;fas fa-file-alt&quot;&gt;&lt;/i&gt; On This Page&lt;/h4&gt;&lt;/header&gt;
&lt;ul class=&quot;toc__menu&quot; id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#tldr&quot; id=&quot;markdown-toc-tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#introduction&quot; id=&quot;markdown-toc-introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#project-setup&quot; id=&quot;markdown-toc-project-setup&quot;&gt;Project setup&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#library--generator&quot; id=&quot;markdown-toc-library--generator&quot;&gt;Library &amp;amp; generator&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#first-module-barebones&quot; id=&quot;markdown-toc-first-module-barebones&quot;&gt;First module barebones&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#login-screen-module&quot; id=&quot;markdown-toc-login-screen-module&quot;&gt;Login screen module&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#responsibilities-split&quot; id=&quot;markdown-toc-responsibilities-split&quot;&gt;Responsibilities split&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#contract&quot; id=&quot;markdown-toc-contract&quot;&gt;Contract&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#presenter&quot; id=&quot;markdown-toc-presenter&quot;&gt;Presenter&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#routing&quot; id=&quot;markdown-toc-routing&quot;&gt;Routing&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#interactor&quot; id=&quot;markdown-toc-interactor&quot;&gt;Interactor&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#view&quot; id=&quot;markdown-toc-view&quot;&gt;View&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#following-views-modules&quot; id=&quot;markdown-toc-following-views-modules&quot;&gt;Following Views Modules&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#implementation-finish&quot; id=&quot;markdown-toc-implementation-finish&quot;&gt;Implementation finish&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#implementation--behavior-details&quot; id=&quot;markdown-toc-implementation--behavior-details&quot;&gt;Implementation &amp;amp; behavior details&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#retrysubscribe-operator&quot; id=&quot;markdown-toc-retrysubscribe-operator&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;retrySubscribe&lt;/code&gt; operator&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#addsubscription-operator&quot; id=&quot;markdown-toc-addsubscription-operator&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;addSubscription&lt;/code&gt; operator&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#presenter-lifecycle--retaining&quot; id=&quot;markdown-toc-presenter-lifecycle--retaining&quot;&gt;Presenter lifecycle &amp;amp; retaining&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#presenter-view-communication-thread&quot; id=&quot;markdown-toc-presenter-view-communication-thread&quot;&gt;Presenter-View communication thread&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#independent-implementation&quot; id=&quot;markdown-toc-independent-implementation&quot;&gt;Independent implementation&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#flavor-design&quot; id=&quot;markdown-toc-flavor-design&quot;&gt;Flavor design&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#possibilities&quot; id=&quot;markdown-toc-possibilities&quot;&gt;Possibilities&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sum-up&quot; id=&quot;markdown-toc-sum-up&quot;&gt;Sum up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

  &lt;/nav&gt;
&lt;/aside&gt;

&lt;h1 id=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;In this blog post I showcase my Android VIPER library usage. The library is called Moviper. To do so I implement the sample Kotlin Android app using Moviper and RxJava step by step and explain the library specific implementation details. The result of this work is available &lt;a href=&quot;https://github.com/mkoslacz/MoviperShowcase&quot;&gt;here&lt;/a&gt;. The way I did the app here is only one of available for Moviper uses as it comes with many flavors, applicable in example if you don’t like RxJava or Kotlin. For more - see the &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper readme&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;In the previous post I have covered pros and cons and a general idea of the Viper architecture. For now let’s focus on &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper - the Android Viper library&lt;/a&gt;. Moviper comes in many different flavors, there are more and less advanced ones - you can just pick one that fits you the most. In this post I’ll show you the flavor I use in the daily basis on the example of a simple Github login screen. I use Rx flavor with &lt;em&gt;Passive Autoinject Views&lt;/em&gt; and I wrap it up using Kotlin language with Android Kotlin Extensions. Sounds scary? Actually, it’s pretty straightforward. Fear not and read on!&lt;/p&gt;

&lt;p&gt;We are going to create a very simple app, that will allow the user to log in to Github and go to the profile page, and provide info about the app.&lt;/p&gt;

&lt;p&gt;It will consist of:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;login screen:
    &lt;ul&gt;
      &lt;li&gt;allows user to go to the help screen,&lt;/li&gt;
      &lt;li&gt;allows user to login and then leads to profile page.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;fake profile page:
    &lt;ul&gt;
      &lt;li&gt;displays logged in user username.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;fake help page:
    &lt;ul&gt;
      &lt;li&gt;displays “help” text.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;third &quot;&gt;
  
    
      &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/LoginActivityLayout.png&quot; title=&quot;Login screen&quot;&gt;
        &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/LoginActivityLayout.png&quot; alt=&quot;Login screen screenshot from app created in this post.&quot; /&gt;
      &lt;/a&gt;
    
  
    
      &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/ProfileActivityLayout.png&quot; title=&quot;Fake profile screen&quot;&gt;
        &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/ProfileActivityLayout.png&quot; alt=&quot;Fake profile screen screenshot from app created in this post.&quot; /&gt;
      &lt;/a&gt;
    
  
    
      &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/HelpActivityLayout.png&quot; title=&quot;Fake help screen&quot;&gt;
        &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/HelpActivityLayout.png&quot; alt=&quot;Fake help screen screenshot from app created in this post.&quot; /&gt;
      &lt;/a&gt;
    
  
  
    &lt;figcaption&gt;This is our sample app mockup. As you can see it’s not a UI tutorial ;)
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;Ok, enough talking, let’s get our feet wet!&lt;/p&gt;

&lt;h1 id=&quot;project-setup&quot;&gt;Project setup&lt;/h1&gt;

&lt;h2 id=&quot;library--generator&quot;&gt;Library &amp;amp; generator&lt;/h2&gt;

&lt;p&gt;First of all, install the &lt;a href=&quot;https://github.com/mkoslacz/MoviperTemplateGenerator&quot;&gt;Moviper Templates Generator&lt;/a&gt; using instructions provided in the repository readme. Just click the link. Remember to restart Android Studio after the installation!&lt;/p&gt;

&lt;p&gt;After that, start up with a brand new Android project with no Activity. If you’re new to Android you can follow a official Google tutorial &lt;a href=&quot;https://developer.android.com/studio/projects/create-project.html&quot;&gt;here&lt;/a&gt; to learn more about stuff we will discuss here.&lt;/p&gt;

&lt;p&gt;The next step is pretty obvious, go to &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper Github page&lt;/a&gt; and find the latest Moviper version and import its Rx-dependency adding the following line to app module gradle dependencies and sync the project.&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;compile&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'com.mateuszkoslacz.moviper:moviper-rx:2.0.3'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;first-module-barebones&quot;&gt;First module barebones&lt;/h2&gt;

&lt;p&gt;Now things get interesting. Let’s create our first Viper Activity! Right-click the app package and select &lt;code class=&quot;highlighter-rouge&quot;&gt;New -&amp;gt; Moviper -&amp;gt; RxActivity&lt;/code&gt; to start the generator.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/chosingViperRxActivity.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/chosingViperRxActivity.png&quot; alt=&quot;Location of RxActivity generator screenshot&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;This is where lies RxActivity generator.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p class=&quot;notice--info&quot;&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; you can even assign a shortcut to create any of the Moviper modules using &lt;code class=&quot;highlighter-rouge&quot;&gt;Manage shortcuts&lt;/code&gt; menu (easy to find using our standard &lt;code class=&quot;highlighter-rouge&quot;&gt;cmd/ctrl + shift + A&lt;/code&gt; magic), searching for “moviper” actions and right clicking them to add a shortcut. That will be even more smooth using the great &lt;a href=&quot;https://plugins.jetbrains.com/plugin/4455-key-promoter&quot;&gt;Key Promoter&lt;/a&gt; plugin, it will suggest  a shortcut assignment to the most used actions. You should definitely check it out!&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/assignMoviperShortcuts.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/assignMoviperShortcuts.png&quot; alt=&quot;Assigning shortcuts to Moviper actions screenshot&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;Assigning shortcuts for Moviper actions will definitely come in handy.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;Fill up the form like I did on the screenshot below: name the screen &lt;code class=&quot;highlighter-rouge&quot;&gt;LoginActivity&lt;/code&gt;, mark it as a &lt;code class=&quot;highlighter-rouge&quot;&gt;Launcher Activity&lt;/code&gt; and select a &lt;code class=&quot;highlighter-rouge&quot;&gt;Passive Autoinject&lt;/code&gt; type. There are more options there and I hope that they’re pretty self-explanatory. If not - just trust me for now - I’ll cover them later anyway.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/ViperActivityCreation.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/ViperActivityCreation.png&quot; alt=&quot;Filled up RxActivity generator screenshot&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;That’s how I have created the LoginActivity.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p class=&quot;notice--warning&quot;&gt;&lt;strong&gt;Important!&lt;/strong&gt; Moviper allows you to handle orientation changes in a very easy way and publish results from background thread after recreating view, but for simplicity, please mark our activity to be in a blocked portrait orientation by adding the &lt;code class=&quot;highlighter-rouge&quot;&gt;android:screenOrientation=&quot;portrait&quot;&lt;/code&gt; line to its entry in the &lt;code class=&quot;highlighter-rouge&quot;&gt;AndroidManifest.xml&lt;/code&gt; file as seen below. Handling orientation changes in Moviper will be covered in the later posts.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;activity&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;android:name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.viper.login.LoginActivity&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;android:screenOrientation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;portrait&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;action&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;android:name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;android.intent.action.MAIN&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;category&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;android:name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;android.intent.category.LAUNCHER&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After confirming our choice, we land in the &lt;code class=&quot;highlighter-rouge&quot;&gt;Contract&lt;/code&gt; interface. On your left hand side, in the project overview, you can see rest of the classes generated by plugin in &lt;code class=&quot;highlighter-rouge&quot;&gt;*.viper.login&lt;/code&gt; package. Viper is a general package for viper modules and the &lt;code class=&quot;highlighter-rouge&quot;&gt;login&lt;/code&gt; part was inferred from the name we gave the generated Activity.&lt;/p&gt;

&lt;p&gt;But hold on - I told you that we will make a Kotlin app and these files feel somewhat suspicious. Yep, MoviperTemplateGenerator creates only Java file sets and for now there is no plan to migrate them to Kotlin. This way we can use it to generate Java code, and for Kotlin apps, we can convert it to Kotlin easily, so let’s do it right now using magic &lt;code class=&quot;highlighter-rouge&quot;&gt;alt + cmd/ctrl + shift + K&lt;/code&gt; shortcut on the entire &lt;code class=&quot;highlighter-rouge&quot;&gt;login&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;If you’re not comfortable with Kotlin, I recommend you to follow &lt;a href=&quot;https://kotlinlang.org/docs/tutorials/kotlin-android.html&quot;&gt;the official tutorial&lt;/a&gt;. It’s not a big deal, I can guarantee you will get a grasp of it in just few hours :wink:.&lt;/p&gt;

&lt;h1 id=&quot;login-screen-module&quot;&gt;Login screen module&lt;/h1&gt;

&lt;h2 id=&quot;responsibilities-split&quot;&gt;Responsibilities split&lt;/h2&gt;

&lt;p&gt;Looking at our module, now we have a set of 5 Kotlin files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LoginActivity&lt;/code&gt; class (the View)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LoginContract&lt;/code&gt; interface&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LoginInteractor&lt;/code&gt; class&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LoginPresenter&lt;/code&gt; class&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LoginRouting&lt;/code&gt; class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a good time to stop now and discuss the responsibility distribution over these components. In classical objc-viper we have a following division:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The main parts of VIPER are:&lt;/p&gt;

  &lt;p&gt;View: displays what it is told to by the Presenter and relays user input back to the Presenter.
Interactor: contains the business logic as specified by a use case.
Presenter: contains view logic for preparing content for display (as received from the Interactor) and for reacting to user inputs (by requesting new data from the Interactor).
Entity: contains basic model objects used by the Interactor.
Routing: contains navigation logic for describing which screens are shown in which order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em style=&quot;text-align: center; display: block; font-size: 80%;&quot;&gt;Source: https://www.objc.io/issues/13-architecture/viper/&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Moviper I have worked out the following, slightly shifted, responsibility fragmentation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;View: displays what the Presenter wants and relays user input back to the Presenter. (exactly the same as above)&lt;/li&gt;
  &lt;li&gt;Interactor: contains the data read/write and preprocessing logic - all of the api and db calls go here.&lt;/li&gt;
  &lt;li&gt;Presenter: contains the business logic - reacts to user input, translating it to the Interactor and Routing calls, decides what to display in the View, validates the data in the business use cases sense (ie username can’t be empty).&lt;/li&gt;
  &lt;li&gt;Entity: these are data objects that are used in the app business logic, independent from the data handling and view implementation.&lt;/li&gt;
  &lt;li&gt;Routing: contains all system-related logic. You can alternatively call it “System”. It manages navigation, screen transitions, notifications scheduling, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mentioned division allows us to create a modular, testable, clean and neat code. Now we know where to put our stuff, so let’s begin to code!&lt;/p&gt;

&lt;h2 id=&quot;contract&quot;&gt;Contract&lt;/h2&gt;

&lt;p&gt;The starting point of every screen is a contract. It generally has one purpose - it defines all Viper modules interfaces and entire control and data flow in the given screen. Let’s define methods needed to implement the entire login screen:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginContract&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MvpView&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;loginClicks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;helpClicks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showLoading&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Interactor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ViperRxInteractor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performLogin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Single&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Routing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ViperRxRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToHelpScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToProfileScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I defined here some data classes to describe content we will use in the created methods. &lt;code class=&quot;highlighter-rouge&quot;&gt;LoginBundle&lt;/code&gt; data class is used as the Observable event type that will, well, bundle the user login data from View:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;data class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And there is also a &lt;code class=&quot;highlighter-rouge&quot;&gt;UserModel&lt;/code&gt; class that will represent our user retrieved from the remote. It is an equivalent of a Github api JSON returned from the endpoint we will use:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;data class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                     &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let’s put them into the &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; package:&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/DataClassesLocation.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/DataClassesLocation.png&quot; alt=&quot;data package screenshot&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;Let’s put our nice data classes to the separate package.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;Going back to our contract - as you can see, Presenter has no interface here. Welcome to the passive word from the chosen Moviper flavor. Passive means that View has no idea about Presenter being attached to it. Actually, you can access Presenter from the View using &lt;code class=&quot;highlighter-rouge&quot;&gt;presenter&lt;/code&gt; property or &lt;code class=&quot;highlighter-rouge&quot;&gt;getPresenter()&lt;/code&gt; method, but in a passive flavor, you will get just plain ViperPresenter, so you won’t have an access to your actual presenter methods. View communicates with Presenter using event streams exposed through View interface to which Presenter subscribes when attaching to it.&lt;/p&gt;

&lt;p&gt;Interactor and Routing are, let’s say, Presenters “tools”. Presenter delegates work to them and receives calls results using Observables. That said, there is no component that calls Presenters methods, so there is no need to implement any interface. This allows us to create multiple Presenters (where each has its own Routing and Interactor) for one View and switch between them seamlessly! We’ll go back to this feature later.&lt;/p&gt;

&lt;h2 id=&quot;presenter&quot;&gt;Presenter&lt;/h2&gt;

&lt;p&gt;Ok, so let’s begin implementing the Presenter. Let’s check out what we already have in there.&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginPresenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BaseRxPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Interactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ViperPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createInteractor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginInteractor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, there are declarations of Routing and Interactor generated by Generator already. You probably noticed that class declaration is pretty complicated, because of some crazy generic stuff. Don’t worry, after implementing some Viper modules, you will get what happens here, but for now, just trust the force (the Generator, to be more specific).&lt;/p&gt;

&lt;p&gt;We’re going to start with defining what should happen in the very beginning of the Presenter lifecycle in Viper module - on a presenter to a view attach. To achieve that, let’s override the &lt;code class=&quot;highlighter-rouge&quot;&gt;attachView(attachingView: LoginContract.View?)&lt;/code&gt; method. Don’t forget to call setup to allow Moviper do its setup work. Don’t forget to use &lt;code class=&quot;highlighter-rouge&quot;&gt;view&lt;/code&gt; property, not the &lt;code class=&quot;highlighter-rouge&quot;&gt;attachingView&lt;/code&gt; argument as a rule of thumb! (the latter is necessary for correct orientation changes handling, we will cover it later, as many other details mentioned here :wink: ).&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginPresenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BaseRxPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Interactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ViperPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;attachView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attachingView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attachView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attachingView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;addSubscription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginClicks&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doOnNext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;showLoading&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Schedulers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMapSingle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;performLogin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AndroidSchedulers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mainThread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retrySubscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goToProfileScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                    &lt;span class=&quot;n&quot;&gt;routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;


        &lt;span class=&quot;n&quot;&gt;addSubscription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;helpClicks&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retrySubscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goToHelpScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createInteractor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginInteractor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you probably noticed, Presenter has an access to View, Routing and Interactor in an entire class scope. Moreover, it automagically casts them to appropriate interfaces defined in contract.&lt;/p&gt;

&lt;p&gt;Note that I always use the optional view call - it’s just easier to do in a no-brainer way. As we often use thread switching in our streams, View can sometimes get detached from the Presenter. Don’t let Android Studio fool you using “unnecessary safe call” message! On the other hand, Interactor and Routing are tightly coupled with Presenter, so there is no need to use safe calls on them in any situation.&lt;/p&gt;

&lt;p&gt;Now let’s focus on our app logic. Don’t worry if you spot some methods that are new for you, they’re described later in this post. Here’s the code of our first stream:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;addSubscription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginClicks&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doOnNext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;showLoading&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Schedulers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMapSingle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;performLogin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AndroidSchedulers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mainThread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retrySubscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goToProfileScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;routing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let’s see what happens here, line by line:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;addSubscription&lt;/code&gt; is a call that wraps our stream to make sure that there won’t be any memory leak.&lt;/li&gt;
  &lt;li&gt;We take the stream from &lt;code class=&quot;highlighter-rouge&quot;&gt;view&lt;/code&gt; - see the following line.&lt;/li&gt;
  &lt;li&gt;It’s a call on the &lt;code class=&quot;highlighter-rouge&quot;&gt;loginClicks&lt;/code&gt; stream provided by our view that is defined in our contract.&lt;/li&gt;
  &lt;li&gt;We show the loading on the view to notify the user about the processing of the request.&lt;/li&gt;
  &lt;li&gt;Here the work shifts to the IO scheduler background thread as a next call will be network based.&lt;/li&gt;
  &lt;li&gt;It’s a delegation of the data work to the Interactor using a method that is defined in our contract.&lt;/li&gt;
  &lt;li&gt;We switch the thread back to the mainThread as we will touch the UI in the methods below.&lt;/li&gt;
  &lt;li&gt;We call our special &lt;code class=&quot;highlighter-rouge&quot;&gt;retrySubscribe&lt;/code&gt; operator that will allow us to retry the calls in case of failure.&lt;/li&gt;
  &lt;li&gt;It’s a start of ReactiveX &lt;code class=&quot;highlighter-rouge&quot;&gt;onNext&lt;/code&gt; lambda method.&lt;/li&gt;
  &lt;li&gt;If the Interactor performed our request succesfully we delegate the screen switch action to the routing using a method that is defined in our contract.&lt;/li&gt;
  &lt;li&gt;Same as above - we finish login activity after login.&lt;/li&gt;
  &lt;li&gt;There is the end of ReactiveX &lt;code class=&quot;highlighter-rouge&quot;&gt;onNext&lt;/code&gt; lambda method.&lt;/li&gt;
  &lt;li&gt;Here is ReactiveX &lt;code class=&quot;highlighter-rouge&quot;&gt;onError&lt;/code&gt; lambda definition - if the request has failed we show an error to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second stream based on &lt;code class=&quot;highlighter-rouge&quot;&gt;view?.helpClicks&lt;/code&gt; has the similar philosophy, so I won’t cover it step by step as it’s pretty straightforward in the context of the previous stream.&lt;/p&gt;

&lt;h2 id=&quot;routing&quot;&gt;Routing&lt;/h2&gt;

&lt;p&gt;OK, so our Presenter is ready, now let’s implement the Routing. Let’s start with using Android Studio auto-fix to implement stubbed methods from the contract:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginRouting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BaseRxRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Routing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToHelpScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TODO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;not implemented&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToProfileScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TODO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;not implemented&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To start these screens, I will use starters here. Starter is a simple class that is used to, well, start the screens. But why use them instead of just starting the activity here? There are two main reasons for it:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;From the login screen a user is able to move to help screen and profile screen (after login). That’s two screens. As we create Viper modules in our app, if we wanted to create whole modules right now, we would need to add six files (contract, Presenter, Interactor, View, Routing, layout) for each screen and insert appropriate Activity declaration lines to AndroidManifest. Adding 12 files not related with screen we work at won’t be a really good practice.&lt;/li&gt;
  &lt;li&gt;If we want to TDD our screen (and we do, I will cover it on the next blog post), it’s much easier to mock the context and check if appropriate starters were called than test if appropriate activities were started. Moreover, it’s much quicker to do it using mocked context than to use Robolectric to test that activities were started.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s create starters for the aforementioned screens and place them in correct packages:&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/StartersLocation.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/StartersLocation.png&quot; alt=&quot;starters location screenshot&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;I put the starters for the separate packages in the same way I did with a whole Login Viper module.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;Now let’s use our starters in Routing:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginRouting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BaseRxRouting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Activity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Routing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;helpStarter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HelpStarter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;profileStarter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProfileStarter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToHelpScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;relatedContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;helpStarter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goToProfileScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;relatedContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;profileStarter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And a quick look at how the starters look like:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelpStarter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// it won't work for now as we don't have HelpActivity yet, so for now let's leave this method empty.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// fun start(context: Context) = context.startActivity(Intent(context, HelpActivity::class.java))
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, I have made them fields of our Routing. You will gain the huge benefit from it in the next post, while we’ll redo the whole process using TDD. For now just trust me please :wink:. Take note of a &lt;code class=&quot;highlighter-rouge&quot;&gt;relatedContext&lt;/code&gt; nullcheck using cool Kotlin &lt;a href=&quot;https://kotlinlang.org/docs/reference/null-safety.html#safe-calls&quot;&gt;safe call&lt;/a&gt; and &lt;a href=&quot;https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html&quot;&gt;let function&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In Routing, it’s important to always check if the context is attached, because if Presenter calls a routing on the non-main thread, it’s possible that related context provider, ie. Activity, already got destroyed, so it could lead to a crash.&lt;/p&gt;

&lt;p&gt;Ok, so now we have implemented the Routing despite that we don’t have any other Viper screen module yet. Nice!&lt;/p&gt;

&lt;h2 id=&quot;interactor&quot;&gt;Interactor&lt;/h2&gt;

&lt;p&gt;Let’s implement the Interactor now, I did it this way:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginInteractor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BaseRxInteractor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Interactor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;loginRepository&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performLogin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;performLogin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With repository implementation delegated as a quasi &lt;a href=&quot;https://medium.com/@krzychukosobudzki/repository-design-pattern-bc490b256006&quot;&gt;Repository design pattern&lt;/a&gt; :wink: :&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class LoginRepository {

    private val retrofit = Retrofit.Builder()
            .baseUrl(&quot;https://api.github.com/&quot;)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()!! // inferred

    fun performLogin(loginBundle: LoginBundle): Single&amp;lt;UserModel&amp;gt; {
        return retrofit
                .create(LoginAndGetUser::class.java)
                .getUser(loginBundle.authorization)
    }

    private interface LoginAndGetUser {
        @GET(&quot;/user&quot;)
        fun getUser(@Header(&quot;Authorization&quot;) authorization: String): Single&amp;lt;UserModel&amp;gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where I have extended LoginBundleClass like this:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;data class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;authorization&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Basic &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encodeToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$login:$password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toByteArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NO_WRAP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p class=&quot;notice--info&quot;&gt;&lt;strong&gt;Pro reader note:&lt;/strong&gt; yep, I know how it looks like, but dude, it’s for presentation purposes.&lt;/p&gt;

&lt;p&gt;Well, I don’t want to focus on networking implementation here, it’s over-simplified moreover. I put it to delegate to don’t let it distract you. Just trust me, this code takes the login and password and translates it to the format readable for server authorization. In the regular case we would need to keep the header for the whole session using Interceptors and I personally would abstract-out the network layer implementation from the Interactor using &lt;a href=&quot;https://medium.com/@krzychukosobudzki/repository-design-pattern-bc490b256006&quot;&gt;Repository Design Pattern&lt;/a&gt;, but it’s the material for another article anyway. The important thing here is that we have our data handling delegated to Interactor.&lt;/p&gt;

&lt;h2 id=&quot;view&quot;&gt;View&lt;/h2&gt;

&lt;p&gt;Now let’s dive strictly to my ready view implementation:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginActivity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ViperAiPassiveActivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;loginClicks&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;RxView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clicks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginBtn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;LoginBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;passwordField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!!&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;helpClicks&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RxView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clicks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;helpBtn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showLoading&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;progressBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loginBtn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;progressBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loginBtn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Toast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makeText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;localizedMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Toast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoginPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getLayoutId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;activity_login&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, there is defined Presenter and layout, which was done for us by MoviperTemplatesGenerator. Here you just define the view logic and layout, so you don’t have to worry about any kind of binding to Presenter, handling lifecycle etc. Moviper does it for you.&lt;/p&gt;

&lt;p&gt;In this file I have used some cool Kotlin features to reduce boilerplate and make the code more readable. Firstly, there are &lt;a href=&quot;https://kotlinlang.org/docs/tutorials/android-plugin.html&quot;&gt;Kotlin Android Extensions&lt;/a&gt; that allows us refer views using their ids directly in the code without declaring them using &lt;code class=&quot;highlighter-rouge&quot;&gt;findViewById()&lt;/code&gt; method. You can see that I reference &lt;code class=&quot;highlighter-rouge&quot;&gt;progressBar&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;loginBtn&lt;/code&gt; etc. directly, without any lookup and it works.&lt;/p&gt;

&lt;p&gt;The second thing is the use of &lt;a href=&quot;https://kotlinlang.org/docs/reference/extensions.html#extension-functions&quot;&gt;Extension Functions&lt;/a&gt; that I use to neatly change the visibility of the views, ie &lt;code class=&quot;highlighter-rouge&quot;&gt;progresBar.visible()&lt;/code&gt;. I put view extensions to the separate file in the &lt;code class=&quot;highlighter-rouge&quot;&gt;*.utils&lt;/code&gt; package:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;com.mateuszkoslacz.movipershowcase.util.ViewExtensions.kt&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visibility&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VISIBLE&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visibility&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GONE&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The third thing is a usage of &lt;a href=&quot;https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/lazy.html&quot;&gt;Kotlin lazy function&lt;/a&gt; that allows us to initialize values that uses Android Views inside the class body, before views initialization, instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;onCreate&lt;/code&gt; method. Kotlin is sweet!&lt;/p&gt;

&lt;p&gt;I’ve also used &lt;a href=&quot;https://github.com/JakeWharton/RxBinding&quot;&gt;Jake Wharton’s RxBinding&lt;/a&gt; to easily create Rx streams from buttons.&lt;/p&gt;

&lt;p&gt;Don’t forget about the corresponding layout file. I won’t include it here, but you can check it out &lt;a href=&quot;https://github.com/mkoslacz/MoviperShowcase/blob/master/app/src/main/res/layout/activity_login.xml&quot;&gt;in the  repo&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/MainActivityLayout.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/MainActivityLayout.png&quot; alt=&quot;this is a placeholder image&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;This is how our view looks like.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;As you can see, our view implementation is pretty straightforward. We show and hide appropriate views, show an error in the toast, and provide click streams - in case of login clicks, we map it to the &lt;code class=&quot;highlighter-rouge&quot;&gt;LoginBundle&lt;/code&gt; using texts from inputs.&lt;/p&gt;

&lt;h1 id=&quot;following-views-modules&quot;&gt;Following Views Modules&lt;/h1&gt;

&lt;p&gt;Our login screen is fully functional right now, but before launching it, let’s pretend that our sprint has just finished and we have to implement the next screens. Let’s check out how it will influence our previous module (hint: it won’t).&lt;/p&gt;

&lt;p&gt;Let’s create (and of course declare in &lt;code class=&quot;highlighter-rouge&quot;&gt;AndroidManifest.xml&lt;/code&gt;) our HelpActivity that we’re prepared to launch as we have created a starter for it before. It’s not created as a Moviper Activity for simplicity, but it should be :wink::&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelpActivity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AppCompatActivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setContentView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;activity_help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now we can uncomment the code we wrote before in our starter:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelpStarter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startActivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HelpActivity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What are the changes in the Login Viper code? None. The only difference is that our help button just started to work. In Login Viper, what will be the overhead of an existence of a help screen in our code if we decide to disable the help button using some remote config? Almost none (a one-liner HelpStarter class object created in Routing).&lt;/p&gt;

&lt;p&gt;Moreover, we could remotely swap the starter to another one existing in our code to remotely modify the behavior of the app. Viper allows a very high modularity of apps in the level that allows to reconfigure the app on the fly. It’s very helpful in handling special events (ie. special Christmas modules that can be activated and deactivated without an app update) or some fatal scenarios in which some module malfunctions - we can always disable it remotely to avoid further crashes during the hotfixing. More detailed article about this feature coming soon.&lt;/p&gt;

&lt;p&gt;Now let’s focus on the ProfileActivity, and once again, we’re prepared to launch it as we have created a starter for it before. And once again, it’s not created as a Moviper Activity for simplicity, but it should be :wink::&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;EXTRA_USERNAME_STRING&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;EXTRA_USERNAME_STRING&quot;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProfileStarter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;starter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProfileActivity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;starter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;putExtra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXTRA_USERNAME_STRING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startActivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;starter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProfileActivity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AppCompatActivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savedInstanceState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setContentView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;activity_profile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usernameText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getStringExtra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXTRA_USERNAME_STRING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// display the username
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And once more, no changes in Login Viper code. The only difference is that we proceed to the ProfileScreen after a successful login.&lt;/p&gt;

&lt;h1 id=&quot;implementation-finish&quot;&gt;Implementation finish&lt;/h1&gt;

&lt;p&gt;Now our app is complete. We can put the wrong credentials to our inputs and see the error and then retry with correct ones and succeed. We can try to login with network disabled and then retry after enabling. We can see that our progress bar shows while loading and disappears after the error and our LoginActivity finishes after successful login. The help view is also functional. It’s alive!&lt;/p&gt;

&lt;p&gt;It looks like we have finished our base example of Moviper-rx with Passive Autoinject Views flavor in Kotlin. Of course, if you prefer Java you can use it as well, even better using some Moviper flavor that will replace Kotlin Android Extensions for you, ie. &lt;a href=&quot;https://jakewharton.github.io/butterknife/&quot;&gt;Butterknife&lt;/a&gt; or &lt;a href=&quot;https://developer.android.com/topic/libraries/data-binding/index.html&quot;&gt;Databinding&lt;/a&gt; one. Just check out the samples of their usage in a &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Moreover, if you don’t like the passive view concept you can choose the flavor in which view is not passive and it calls presenters methods or you can even pick the non-rx Moviper version. Feel free to choose your favorite! (but take note that I consider the flavor described in this post as a most boilerplate-reducing, readable, scalable and featureful) Just check out &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;the repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But it’s not the end yet. As you probably noticed, in this example I used some methods probably unknown to you and you may be wondering how our app will behave in edge cases. Don’t worry, just read on!&lt;/p&gt;

&lt;h1 id=&quot;implementation--behavior-details&quot;&gt;Implementation &amp;amp; behavior details&lt;/h1&gt;

&lt;p&gt;For simplicity, I have skipped some more detailed descriptions of utils I used, behavior of our app and rules to follow when using Moviper. Let’s go back there and be more meticulous about them.&lt;/p&gt;

&lt;h2 id=&quot;retrysubscribe-operator&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;retrySubscribe&lt;/code&gt; operator&lt;/h2&gt;

&lt;p&gt;I defined our special &lt;code class=&quot;highlighter-rouge&quot;&gt;retrySubscribe&lt;/code&gt; operator in &lt;code class=&quot;highlighter-rouge&quot;&gt;ObservableExtensions.kt&lt;/code&gt; file in &lt;code class=&quot;highlighter-rouge&quot;&gt;*.util&lt;/code&gt; package:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retrySubscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                     &lt;span class=&quot;n&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doOnNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doOnError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This operator allows our streams to signal an error and not to unsubscribe after that - if user wants to log in and he’s out of the Internet, he will get some error about it and we want to allow him to retry this action. That’s why we use the &lt;code class=&quot;highlighter-rouge&quot;&gt;retrySubscribe&lt;/code&gt; operator. I’ll describe implementation details in another post.&lt;/p&gt;

&lt;h2 id=&quot;addsubscription-operator&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;addSubscription&lt;/code&gt; operator&lt;/h2&gt;

&lt;p&gt;In the example you can see that each stream is wrapped in a &lt;code class=&quot;highlighter-rouge&quot;&gt;addSubscription&lt;/code&gt; call. It’s one of the built-in Moviper methods that allows you to forget about the need of unsubscribing your streams to avoid memory leaks. Just wrap all of your never completing streams using &lt;code class=&quot;highlighter-rouge&quot;&gt;addSubscription&lt;/code&gt; and that’s all! Your streams will be unsubscribed at Presenter detach from View. If you have some objects in your Presenter that need some special finishing, do it overriding &lt;code class=&quot;highlighter-rouge&quot;&gt;onDetach(Boolean retainInstance)&lt;/code&gt; method (and once again, don’t forget to call super!).&lt;/p&gt;

&lt;h2 id=&quot;presenter-lifecycle--retaining&quot;&gt;Presenter lifecycle &amp;amp; retaining&lt;/h2&gt;

&lt;p&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;onDetach&lt;/code&gt; is pretty simple, but remember, not every call to it means that Presenter will be destroyed - if a &lt;code class=&quot;highlighter-rouge&quot;&gt;retainInstance&lt;/code&gt; argument is &lt;code class=&quot;highlighter-rouge&quot;&gt;true&lt;/code&gt;, it means that attached view is destroyed, because of the Android orientation change and Presenter will be retained and reattached to the new view, so you don’t have to nuke your delegates (at least those which don’t use the view reference).&lt;/p&gt;

&lt;p&gt;The thing worth emphasizing here is that your Presenter won’t be parceled and recreated or something like that. After rotating the screen, it will be the same exact presenter that have been attached to the view before orientation change. Moreover, all of the background work that the presenter performs (and all of its children, with Routing and Interactor as a most notable examples of them) will be delivered to the eventual view, when the orientation change happens in the meantime, if you follow only one rule of thumb - &lt;em&gt;always communicate with the view using the main thread&lt;/em&gt; (&lt;a href=&quot;http://hannesdorfmann.com/mosby/summary/&quot;&gt;as it is in Mosby library&lt;/a&gt; - &lt;em&gt;Can the Presenter and its view be out of sync during a screen orientation change?&lt;/em&gt; paragraph. Moviper bases on Mosby so the linked rule refers to Moviper also).&lt;/p&gt;

&lt;h2 id=&quot;presenter-view-communication-thread&quot;&gt;Presenter-View communication thread&lt;/h2&gt;

&lt;p&gt;As I said above: &lt;em&gt;always communicate with the view using the main thread&lt;/em&gt;. Even if view will need to perform some hard work on the background thread, using the diffUtil for example - always call the view on the main thread and delegate the work to another thread in the view itself. It will allow your sub-modules to always be synchronized. For more info about the Presenter and view lifecycle and behavior I recommend you reading the &lt;a href=&quot;https://kotlinlang.org/docs/tutorials/kotlin-android.html&quot;&gt;Mosby docs and blog&lt;/a&gt; as the Moviper is built on top of this library, so it inherits the behavior of view-presenter relations.&lt;/p&gt;

&lt;h2 id=&quot;independent-implementation&quot;&gt;Independent implementation&lt;/h2&gt;

&lt;p&gt;The other fancy thing, even though we haven’t even touched another components, is that we could safely implement entire presenter! (and then Routing etc.) Using Moviper you can parallelize the work on the single module among entire team. Making work more focused on a single screen makes you send new builds to QA faster, so there is no bottlenecking on the very end of the scrum sprint!&lt;/p&gt;

&lt;h2 id=&quot;flavor-design&quot;&gt;Flavor design&lt;/h2&gt;

&lt;p&gt;It’s worth noting that in our app View is 100% passive - it means that View is not aware of any kind of Presenter attached to it nor methods it has. View doesn’t call Presenter in any way - it just provides the interface to which a Presenter can attach itself to. It’s the Presenter that decides what to do, what to use and what not to use - View has no app logic inside. That’s why the views flavor I use in this post has &lt;strong&gt;Passive&lt;/strong&gt; in its name.&lt;/p&gt;

&lt;p&gt;View is passive, but it provides the Rx streams to which Presenter can attach itself to. That’s why the Moviper flavor here has &lt;strong&gt;Rx&lt;/strong&gt; in its name.&lt;/p&gt;

&lt;p&gt;If we had some special views that would need additional setup we could do it overriding &lt;code class=&quot;highlighter-rouge&quot;&gt;injectViews(android.view.View)&lt;/code&gt;. There’s no need to plug in to android lifecycle methods like &lt;code class=&quot;highlighter-rouge&quot;&gt;onCreate&lt;/code&gt; etc., Moviper does the job for us. That’s why the views flavor I use in this post has &lt;strong&gt;Autoinject&lt;/strong&gt; in its name.&lt;/p&gt;

&lt;p&gt;I guess that now you get the naming of this Moviper-rx with Autoinject Passive Views flavor :wink:.&lt;/p&gt;

&lt;h1 id=&quot;possibilities&quot;&gt;Possibilities&lt;/h1&gt;

&lt;p&gt;As you can see, our app is really neat and clean. The clean design makes our apps maintainable, but it also comes in handy in our production environment where we attach multiple Presenters to our Views using Moviper &lt;a href=&quot;https://github.com/mkoslacz/Moviper#attaching-multiple-presenters-to-the-view&quot;&gt;ViperPresentersList&lt;/a&gt;. In &lt;a href=&quot;https://movibe.it/&quot;&gt;Movibe&lt;/a&gt;/&lt;a href=&quot;https://onas.wp.pl/&quot;&gt;Wirtualna Polska&lt;/a&gt; we have a separate business logic presenter, analytics presenter, advertising presenter, etc., where every presenter has its own routing and interactor crafted appropriately to the role of a given presenter. The fact that there are many presenters is transparent for the view. It allows us to dynamically attach or detach presenters to, for example, turn off ads for premium users.&lt;/p&gt;

&lt;p&gt;Moreover, if your presenter has grown too much and for some reason you can’t split your view to smaller chunks that corresponds with separate use-cases, you can create the presenter for each use-case and attach the whole bunch of them to the single view. It allows us to keep our classes small, and in most cases, smaller means more readable, more maintainable, more testable and more awesome. And still - with no changes in the View!&lt;/p&gt;

&lt;p&gt;It also works for defining multiple behaviors for one view. We use it to create one login screen and reuse it in the various login methods as we allow authorization using some external account credentials in our apps. Moviper provides a ready-to-use tool for it called &lt;a href=&quot;https://github.com/mkoslacz/Moviper#choosing-presenter-on-runtime&quot;&gt;PresentersDispatcher&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The idea works in both ways - we also swap the views using the same presenter and whole app logic. For example, we do so when we implement the Android TV version of our apps using the goodies from Leanback Library.&lt;/p&gt;

&lt;p&gt;For more general overview of VIPER features I recommend you reading my previous article.&lt;/p&gt;

&lt;h1 id=&quot;sum-up&quot;&gt;Sum up&lt;/h1&gt;

&lt;p&gt;To sum up let’s look at our code.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It’s highly modular in a way that allows us to remotely enable, disable and swap modules and develop multiple screens and modules at once without conflicts.&lt;/li&gt;
  &lt;li&gt;The contract allows a dev to take a quick overview how the entire module works while each submodule is so simple and beautiful that it’s understandable at a glance.&lt;/li&gt;
  &lt;li&gt;The view is passive, so we can swap the presenters, split the presenter to multiple ones if it grows too much or attach additional presenters for optional features.&lt;/li&gt;
  &lt;li&gt;We wrapped all our logic in Rx streams, which allows us to track the app execution path easily and making it almost completely crash-safe (not to be confused with being error-safe).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And there is a &lt;a href=&quot;https://github.com/mkoslacz/MoviperTemplateGenerator&quot;&gt;MoviperTemplatesGenerator&lt;/a&gt; that did all the relations binding, class creating and inheritance defining for us! That’s a pretty nice bunch of features!&lt;/p&gt;

&lt;p&gt;In this post series I have skipped some less important code, but you can check out and run &lt;a href=&quot;https://github.com/mkoslacz/MoviperShowcase&quot;&gt;the whole sample here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I encourage you to let me know what you think about the architecture and the library itself. Feel free to contribute and report the issues.&lt;/p&gt;

&lt;p&gt;Last but not least, stay tuned as I’ll be posting more about the Moviper goodies:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;handling orientation changes with retaining background jobs state,&lt;/li&gt;
  &lt;li&gt;Inter-Presenter-Communication,&lt;/li&gt;
  &lt;li&gt;dispatching presenters on runtime (using the same view with different presenters),&lt;/li&gt;
  &lt;li&gt;using multiple presenters with one view,&lt;/li&gt;
  &lt;li&gt;creating the viper modules for RecyclerView cells,&lt;/li&gt;
  &lt;li&gt;creating Android Service based viper modules and standalone viper modules,&lt;/li&gt;
  &lt;li&gt;passing Intent extras to presenters,&lt;/li&gt;
  &lt;li&gt;TDDing Viper modules,&lt;/li&gt;
  &lt;li&gt;using Moviper Test utils,&lt;/li&gt;
  &lt;li&gt;using iOS Moviper Version,&lt;/li&gt;
  &lt;li&gt;sharing code between Android and iOS thanks to Moviper.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And much more, stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great thanks to &lt;a href=&quot;http://damianchodorek.com/&quot;&gt;Damian Chodorek&lt;/a&gt; and Paweł Gawenda for reviewing this post.&lt;/em&gt;&lt;/p&gt;</content><author><name>Mateusz Koślacz</name><email>contact@mateuszkoslacz.com</email></author><category term="Android" /><category term="Architecture" /><category term="Moviper" /><category term="VIPER" /><category term="Kotlin" /><category term="ReactiveX" /><category term="RxJava" /><summary type="html">A walkthrough that will let you start using Moviper.</summary></entry><entry><title type="html">Why shall I choose VIPER architecture?</title><link href="https://mateuszkoslacz.com/why-shall-i-choose-viper-architecture/" rel="alternate" type="text/html" title="Why shall I choose VIPER architecture?" /><published>2017-01-31T13:12:20+00:00</published><updated>2017-01-31T13:12:20+00:00</updated><id>https://mateuszkoslacz.com/why-shall-i-choose-viper-architecture</id><content type="html" xml:base="https://mateuszkoslacz.com/why-shall-i-choose-viper-architecture/">&lt;aside class=&quot;sidebar__right&quot;&gt;
&lt;nav class=&quot;toc&quot;&gt;
    &lt;header&gt;&lt;h4 class=&quot;nav__title&quot;&gt;&lt;i class=&quot;fas fa-file-alt&quot;&gt;&lt;/i&gt; On This Page&lt;/h4&gt;&lt;/header&gt;
&lt;ul class=&quot;toc__menu&quot; id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#tldr&quot; id=&quot;markdown-toc-tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#introduction&quot; id=&quot;markdown-toc-introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#junior-dev-retrospection-horror&quot; id=&quot;markdown-toc-junior-dev-retrospection-horror&quot;&gt;Junior Dev Retrospection (Horror)&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#how-to-split&quot; id=&quot;markdown-toc-how-to-split&quot;&gt;How to split?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#how-to-test&quot; id=&quot;markdown-toc-how-to-test&quot;&gt;How to test?&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#relief---viper-architecture&quot; id=&quot;markdown-toc-relief---viper-architecture&quot;&gt;Relief - VIPER architecture&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#main-viper-features&quot; id=&quot;markdown-toc-main-viper-features&quot;&gt;Main VIPER features&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#modularity--interchangeability&quot; id=&quot;markdown-toc-modularity--interchangeability&quot;&gt;Modularity &amp;amp; interchangeability&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#clean-code--easy-testing&quot; id=&quot;markdown-toc-clean-code--easy-testing&quot;&gt;Clean code &amp;amp; easy testing&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#enhanced-agility&quot; id=&quot;markdown-toc-enhanced-agility&quot;&gt;Enhanced agility&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#enterprise-acceleration&quot; id=&quot;markdown-toc-enterprise-acceleration&quot;&gt;Enterprise acceleration&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#faster-multi-platform-development&quot; id=&quot;markdown-toc-faster-multi-platform-development&quot;&gt;Faster multi-platform development&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#doubt&quot; id=&quot;markdown-toc-doubt&quot;&gt;Doubt&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sum-up&quot; id=&quot;markdown-toc-sum-up&quot;&gt;Sum up&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#but-wait&quot; id=&quot;markdown-toc-but-wait&quot;&gt;But wait…&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

  &lt;/nav&gt;
&lt;/aside&gt;

&lt;h2 id=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;VIPER architecture allows you to easily TDD your app, keep the code clean, share modules and distribute the work. It enhances a general development process by increasing frequency of sending the new functionalities to QA and Product Owner. It speeds up a multi-platform development as Android and iOS can share the general logic. It also makes you more agile allowing to change only specific parts of an app at any moment. For each screen, it introduces five or six modules, but don’t worry - there are tools to generate these for you. It has some entry threshold, but it can be overcame in a few days. There are plenty iOS articles and examples to learn from and a little bit of Android ones, but I will try to change this deficit in this blog, using &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper&lt;/a&gt; - VIPER architecture library for Android.&lt;/strong&gt;&lt;/p&gt;

&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;Every developer encounters in his path similar obstacles, while trying to advance from basics to advanced solutions. I think that today’s tutorials and blog posts aren’t very helpful in such cases, because they form two groups in general - very basic ones and very advanced ones, so obviously, there is a huge gap between these clusters. In my blog, I will try to fill the aforementioned gap on the example of a one specific architecture, which I think, makes the journey from primitive to the masters knowledge somehow easy and pleasant. In this post, I will try to convince you that VIPER architecture is worth trying. Let’s begin with reminding ourselves what caused most of the problems on our developer’s path.&lt;/p&gt;

&lt;h1 id=&quot;junior-dev-retrospection-horror&quot;&gt;Junior Dev Retrospection (Horror)&lt;/h1&gt;

&lt;h2 id=&quot;how-to-split&quot;&gt;How to split?&lt;/h2&gt;

&lt;p&gt;Fellow mobile developer, at the very beginning, you probably implemented your first hello world app and then started to explore the depths of your platform. Very quickly you have realized that your Activities/View Controllers have grown to the enormous size, making you flea to the Google to find a remedy for that. Then you found it, the glorious MVP/MVC/MVVM/MV-something architecture that claimed it will resolve your problem for sure. So you grabbed your coffee, rushed to the keyboard and rewrote your app in the brand new, proper way.&lt;/p&gt;

&lt;p&gt;After a few long hours, you laid back in rejoice for a moment and admired the great piece of software you have just crafted. But then you froze in horror. Your Activities/View Controllers are nice and slim right now, but wait, we have another god-classes, the Controller/Presenter/ViewModel ones! Oh noes, they are responsible for handling the routing through the app, data management, interacting with system framework and many other things! That nasty classes for sure do not fulfill the idea of the &lt;a href=&quot;http://www.oodesign.com/single-responsibility-principle.html)&quot;&gt;Single Responsibility Principle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What shall I do now?&lt;/em&gt; Some senior developer looked at you with indulgence and advised warmly: &lt;em&gt;Delegate your responsibilities from presenter&lt;/em&gt;. Do what? Delegate what? After a quick research you instantly caught up, but then you got stuck again. &lt;em&gt;I still don’t know what I should delegate! How do I know if I should delegate every method, bunch of them or maybe I should just split the presenter in half? I’m just a junior developer, I don’t have such intuition!&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-test&quot;&gt;How to test?&lt;/h2&gt;

&lt;p&gt;Let’s skip the latter part for now. Instead, think about that other situation, the situation in which you have found a bug in your app. You found it, so you fixed it. The problem is that when you have fixed it, the two new nasty regressions came up in your project. After fixing one of them, another two showed up to accompany the one that have left from the first wave. It was like fighting a hydra. Very quickly you found yourself banging your head against the wall trying to get a grip on the project again.&lt;/p&gt;

&lt;p&gt;That sad scenario led you to discover testing and &lt;a href=&quot;http://agiledata.org/essays/tdd.html&quot;&gt;Test Driven Development&lt;/a&gt;. You quickly went through all the tutorials of TDD-ing a simple calculator app, instantly grasped the basics and rolled up your sleeves to reimplement your app in the proper way. It rapidly turned out that it’s like a tutorial of drawing an owl:&lt;/p&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/HowToDrawAnOwl.jpg&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/HowToDrawAnOwl.jpg&quot; alt=&quot;Funny, two step, owl drawing instruction.&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;That’s how the first approach to the testing looks like!
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;&lt;em style=&quot;text-align: center; display: block; font-size: 60%;&quot;&gt;Source: http://forimpact.org/for-impact-ideas/how-to-draw-an-owl/&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You quickly realized that you have no idea how to test your system. &lt;em&gt;What am I supposed to test? I click this button in app and load my data in Activity/View Controller, there is nothing to test really!&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;relief---viper-architecture&quot;&gt;Relief - VIPER architecture&lt;/h1&gt;

&lt;p&gt;Here comes the VIPER architecture — a relief for these problems. It proposes a pretty decoupled design of each scene (let’s say &lt;em&gt;“scene”&lt;/em&gt; like that for the simplicity right now), which is a good start for making all your responsibilities delegated. Moreover, decoupling the architecture makes it contain a reasonable amount of &lt;a href=&quot;https://www.philosophicalhacker.com/post/what-makes-android-apps-testable/&quot;&gt;seams&lt;/a&gt; that allows you TDD your app. Actually, it’s not a completely different approach than a well-known MVP, it’s just a concept of adding some modules to the presenter to delegate its responsibilities which repeatedly appear in all of the mobile application scenes. Let’s dive in!&lt;/p&gt;

&lt;p&gt;Each VIPER module consists of following sub-modules:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Contract&lt;/strong&gt;: defines the way sub-modules communicate,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;View&lt;/strong&gt;: user interface,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Presenter&lt;/strong&gt;: delegating appropriate tasks to Router and Interactor, deciding what and how to display,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Router/Routing&lt;/strong&gt;: system framework interactions - mostly app routing (switching views),&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Interactor&lt;/strong&gt;: data-related business logic,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Entity&lt;/strong&gt; (-ies): objects representing your data,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Builder/Starter&lt;/strong&gt;: starts a whole VIPER module.&lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;&quot;&gt;
  &lt;a href=&quot;https://mateuszkoslacz.com/assets/images/ViperDiagram.png&quot;&gt;
  &lt;img src=&quot;https://mateuszkoslacz.com/assets/images/ViperDiagram.png&quot; alt=&quot;this is a placeholder image&quot; /&gt;
    &lt;/a&gt;
  
    &lt;figcaption&gt;That’s the general look of the Viper architecture.
&lt;/figcaption&gt;
  
&lt;/figure&gt;

&lt;p&gt;I won’t cover each of them in this post as it’s rather a material for another publication. I will discuss it in the next article, but if you are really curious right now, you can read &lt;a href=&quot;https://www.objc.io/issues/13-architecture/viper/&quot;&gt;the original objc VIPER article&lt;/a&gt; (I guess). Instead, for now let’s focus on the general features of VIPER.&lt;/p&gt;

&lt;h1 id=&quot;main-viper-features&quot;&gt;Main VIPER features&lt;/h1&gt;

&lt;h2 id=&quot;modularity--interchangeability&quot;&gt;Modularity &amp;amp; interchangeability&lt;/h2&gt;

&lt;p&gt;It assigns each screen an independent module, so you can move around your project or even your whole projects portfolio. There’s even more: it makes every sub-module independent so you can ie. use VIPER from one project in the another one. You can switch the implementation of only one of sub-modules to meet the requirements of the target application.&lt;/p&gt;

&lt;h2 id=&quot;clean-code--easy-testing&quot;&gt;Clean code &amp;amp; easy testing&lt;/h2&gt;

&lt;p&gt;Having all the modules and sub-modules decoupled and independent makes them extremely easy to test. Every sub-module has its own responsibility, so it’s much easier to keep them small, neat and clean throughout whole development process. In addition, unified responsibilities split allows developers to understand the new modules at a glance.&lt;/p&gt;

&lt;h2 id=&quot;enhanced-agility&quot;&gt;Enhanced agility&lt;/h2&gt;

&lt;p&gt;What is more, making your app decoupled allows your team to be more agile, especially when circumstances of your project make the specification change frequently, because you can change any of the modules or the sub-modules without even touching the rest of the codebase.&lt;/p&gt;

&lt;h2 id=&quot;enterprise-acceleration&quot;&gt;Enterprise acceleration&lt;/h2&gt;

&lt;p&gt;Moreover, it introduces a huge acceleration to the enterprise mobile development process. It allows the entire team to work on a single screen at once, which leads to an increased frequency of a dev - QA iterations during the sprint. That powerfully eases an agile approach - customer can review screens earlier. It also soothes a dev - QA edge by keeping QA busy on the reasonable level. It’s not like in an „old” approach, where bored QA takes care about other projects at the beginning of a sprint and when a whole bunch of views is ready at the end of a sprint, you have to wait for QA to finish other projects and then you DDoS them using all the views you have developed.&lt;/p&gt;

&lt;h2 id=&quot;faster-multi-platform-development&quot;&gt;Faster multi-platform development&lt;/h2&gt;

&lt;p&gt;Furthermore, it makes multi-platform development much easier as Android and iOS can share Contracts, tests, Rx streams and general logic of internals, if you manage to maintain uniform architecture across platforms. In addition, if you write your Android code in &lt;a href=&quot;https://kotlinlang.org/&quot;&gt;Kotlin&lt;/a&gt;, you can port the presenter, tests and some utils between platforms with very little effort, as Kotlin and Swift have a very similar grammar. Android and iOS parts of the team can do different modules at once, and after finishing, they can switch and base their coding on already done components of another platform. It also enhances bugs detection as if both platforms share the same logic, if a bug is detected in one platform, it can be fixed on both.&lt;/p&gt;

&lt;p&gt;Looking at all the paragraphs above - well, that’s a pretty bunch of advantages!&lt;/p&gt;

&lt;h1 id=&quot;doubt&quot;&gt;Doubt&lt;/h1&gt;

&lt;p&gt;Yes, yes, I can hear you yelling &lt;em&gt;But my view X is so simple, I don’t care about creating six components for that! It’s over-engineering! There’s even nothing to test!&lt;/em&gt;. Now think about that app you did last time. You had pretty similar, very simple view X in there, but now it has grown to the enormous size. Have you managed to refactor it? No? Well. Is there something to test right now? And is it tested out? Well… Now you see.&lt;/p&gt;

&lt;p&gt;Moreover, I don’t think that having to create some components really is a downside if we can delegate this dirty work to some scripts or plugins like &lt;a href=&quot;https://github.com/mkoslacz/MoviperTemplateGenerator&quot;&gt;Moviper Templates Generator&lt;/a&gt; or &lt;a href=&quot;https://github.com/rambler-digital-solutions/Generamba&quot;&gt;Generamba&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, there is also some entry threshold but it usually takes only a few days to feel really confident in this architecture. And the gain of using VIPER grows with every line of code that adds a pinch of a complexity to your codebase. Of course, there is also some boilerplate added to define all the essential sub-modules, but I don’t think that it’s a significant downside in the face of the upsides of this approach.&lt;/p&gt;

&lt;h1 id=&quot;sum-up&quot;&gt;Sum up&lt;/h1&gt;

&lt;p&gt;Let’s sum up the upsides of VIPER:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;clean code,&lt;/li&gt;
  &lt;li&gt;easy TDD,&lt;/li&gt;
  &lt;li&gt;reusable modules and sub-modules,&lt;/li&gt;
  &lt;li&gt;easier work distribution,&lt;/li&gt;
  &lt;li&gt;instant understanding of modules implemented by other devs,&lt;/li&gt;
  &lt;li&gt;sharing logic across platforms,&lt;/li&gt;
  &lt;li&gt;enhanced agility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And check out the downsides as well:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;needs additional work to repeatedly create all the modules &lt;strong&gt;[BUSTED]&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;some entry threshold [to beat in few days],&lt;/li&gt;
  &lt;li&gt;some boilerplate added [but I personally think that it weighs nothing in comparison to all the upsides].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me it looks like upsides of this architecture weigh much more than downsides, so I think that it’s definitely worth trying to adopt in your workshop.&lt;/p&gt;

&lt;h1 id=&quot;but-wait&quot;&gt;But wait…&lt;/h1&gt;

&lt;p&gt;All of the iOS developers are happy now and they’ve just started reading various articles about iOS VIPER implementation, as there are &lt;a href=&quot;https://www.google.pl/#safe=off&amp;amp;q=ios+viper+architecture&quot;&gt;plenty of them&lt;/a&gt;. You, iOS fellas, can stop reading right now as you have lots articles to read about that (but remember about the fact that work at open-sourcing Moviper for iOS is in progress ;) ).&lt;/p&gt;

&lt;p&gt;On the other hand, Android developers got somehow confused, as searching for the &lt;a href=&quot;https://www.google.pl/#safe=off&amp;amp;q=android+viper+architecture&quot;&gt;“Android VIPER architecture”&lt;/a&gt; gives some appropriate results, but there isn’t even a full page of it. Let’s review what do we have here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lyubomir Ganev &lt;a href=&quot;http://luboganev.github.io/blog/clean-architecture-pt1/&quot;&gt;series of posts&lt;/a&gt; and a &lt;a href=&quot;https://github.com/luboganev/Carbrands&quot;&gt;related sample&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;Richa Khandelwal &lt;a href=&quot;https://realm.io/news/360andev-richa-khandelwal-effective-android-architecture-patterns-java/&quot;&gt;post on a Realm blog&lt;/a&gt; and a &lt;a href=&quot;https://github.com/richk/CourseraDemoApp&quot;&gt;related sample&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;Jiri Helmich &lt;a href=&quot;https://speakerdeck.com/helmisek/android-viper-architecture-implementation&quot;&gt;presentation&lt;/a&gt; and a &lt;a href=&quot;https://github.com/Helmisek/android-viper&quot;&gt;related sample&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;Dmytro Zaitsev &lt;a href=&quot;https://speakerdeck.com/dmitriyzaitsev/viper-sexy-architecting-or-mvp-on-steroids&quot;&gt;presentation&lt;/a&gt; and a &lt;a href=&quot;https://github.com/RxViper/RxViper&quot;&gt;library he created&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;and others that I probably couldn’t find.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, there are already some sources to learn from and it’s great if you liked and wanted to adopt one of these!&lt;/p&gt;

&lt;p&gt;Looking in the samples you can see that everyone has its own interpretation of VIPER. As you can see, there isn’t much about VIPER in the Android society and this concept still isn’t monolithic throughout developers, so I feel like there is yet a little bit of a room for me.&lt;/p&gt;

&lt;p&gt;Personally, in first two samples I somehow feel the lack of an architecture-enforced Router/Routing (correct me if I’m wrong of course). The following two, unfortunately, have only presentations with not much text that describes their usage which makes it not so easy to start using them. That’s why I decided to publish some articles about general VIPER and &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper&lt;/a&gt; usage and features.&lt;/p&gt;

&lt;p&gt;I discovered the aforementioned articles after I have started developing my VIPER library - &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper&lt;/a&gt; - and I perceive the roles of the VIPER components in a slightly different perspective. You can check out &lt;a href=&quot;https://github.com/mkoslacz/Moviper&quot;&gt;Moviper&lt;/a&gt; to investigate the differences for now, in later posts I will describe my feeling of this architecture in details.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great thanks to &lt;a href=&quot;http://damianchodorek.com/&quot;&gt;Damian Chodorek&lt;/a&gt; and Paweł Gawenda for reviewing this post.&lt;/em&gt;&lt;/p&gt;</content><author><name>Mateusz Koślacz</name><email>contact@mateuszkoslacz.com</email></author><category term="iOS" /><category term="Android" /><category term="Architecture" /><category term="Moviper" /><category term="VIPER" /><summary type="html">The essence of facts that shall convince you to start using Viper architecture.</summary></entry></feed>