<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Maxim Smirnov on Medium]]></title>
        <description><![CDATA[Stories by Maxim Smirnov on Medium]]></description>
        <link>https://medium.com/@atimca?source=rss-34717dc164a5------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*mqFLVHZ_jKZb-Xerbjrf3Q.jpeg</url>
            <title>Stories by Maxim Smirnov on Medium</title>
            <link>https://medium.com/@atimca?source=rss-34717dc164a5------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 13 Jul 2026 22:33:17 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@atimca/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[The Composable Architecture tutorial]]></title>
            <link>https://medium.com/@atimca/the-composable-architecture-tutorial-d220fd25cab3?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/d220fd25cab3</guid>
            <category><![CDATA[redux]]></category>
            <category><![CDATA[reactive-programming]]></category>
            <category><![CDATA[cats]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[unidirectional-data-flow]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Fri, 23 Jul 2021 11:07:31 GMT</pubDate>
            <atom:updated>2022-02-02T09:14:19.423Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Disclaimer<em>: This tutorial uses </em><strong><em>Xcode 12.4</em></strong><em>, </em><strong><em>Swift 5.3</em></strong><em>, and </em><strong><em>iOS 14</em></strong><em>.</em></blockquote><blockquote><em>You can find the source code of this tutorial </em><a href="https://github.com/Atimca/TCA-tutorial"><em>here</em></a><em>. If you’re so eager to try it that you want to skip the tutorial, just launch </em><em>RootView.swift preview.</em></blockquote><h3>Introduction</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XN3lnvuo7Bhd-3J4KZqpBA.png" /></figure><p>Today we are going to build a simple app, consisting of 2 screens, using the composable architecture (TCA for short). TCA is a variant of an <a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d">unidirectional architecture</a> built upon <a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">reactive programming principles</a>, created by PointFree. They provide extensive documentation about it and its creation process. You can check it out <a href="https://www.pointfree.co/collections/composable-architecture">here</a>. Interesting stuff and highly recommended if you like to understand every concept as intended by its creators.</p><p>The scope of this tutorial is to help onboard the TCA concepts as soon as possible. Which makes it a handy tutorial for people that need to work with these concepts right away.</p><p>This is what we are aiming for:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/323/1*Cl_x0KtIR60c2EhNemkCPQ.gif" /></figure><p>For this tutorial, we are going to use an open <a href="https://dog.ceo/dog-api/documentation/">Dogs API</a> which doesn’t require a token and perfectly suits the needs of this article. Let’s take a look at the app structure.</p><ul><li><strong>Main screen:</strong> List of dog breeds with a possibility to filter by name.</li><li><strong>Detailed screen:</strong> A screen with a particular dog’s breed as a title, random dog image + a list of dog’s sub-breeds if available.</li></ul><p>Both screens are going to be separate modules that don’t know about each other, so you can see modularization techniques of TCA as well. However, let&#39;s start with a bit of theoretical knowledge so we know what we&#39;re doing here.</p><h3>What is The Composable Architecture</h3><p>TCA is one of the variations of <a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d">unidirectional architectures</a> family, such as Redux, RxFeedback, Flux etc. Let&#39;s just copy some explanation from the <a href="https://github.com/pointfreeco/swift-composable-architecture">official GitHub</a>.</p><p>This library provides a few core tools you can use to build applications of varying purposes and complexity. It provides compelling stories that you can follow to solve many day-to-day problems you encounter when building applications, such as:</p><ul><li><strong>State management</strong><br>How to manage the state of your application using simple value types, and share the state across many screens. This way, you can see mutations in one screen immediately in another.</li><li><strong>Composition</strong><br>How to break down large features into smaller components that can be extracted to their own, isolated modules. And that you can easily glued back together to form the feature.</li><li><strong>Side effects</strong><br>How to let certain parts of the application talk to the outside world in the most testable and understandable way possible.</li><li><strong>Testing</strong><br>How to test a feature built in the architecture, but also write integration tests for features that have been composed of many parts. Also: how to write end-to-end tests to understand how side effects influence your application. This allows you to make strong guarantees that your business logic is running in the way you expect it to.</li><li><strong>Ergonomics</strong><br>How to accomplish all of the above in a simple API with as few concepts and moving parts as possible.</li></ul><p>To build a feature using the Composable Architecture, let’s define some types and values that model a domain:</p><ul><li><strong>State</strong><br>A type that describes the data your feature needs to perform its logic and render its UI.</li><li><strong>Action</strong><br>A type that represents all actions that can happen in your features, such as user actions, notifications, event sources et cetera.</li><li><strong>Environment</strong><br>A type that holds any dependencies the feature needs, like API clients, analytics clients and so on.</li><li><strong>Reducer</strong><br>A function that describes how to evolve the current state of the app to the next state given an action. The reducer is also responsible for returning any effects that should be run, such as API requests, which can be done by returning an Effect value.</li><li><strong>Store</strong><br>The runtime that actually drives your feature. You send all user actions to the store so that the store can run the reducer and effects. You can also check state changes in the store so that you can update UI.</li></ul><p>Now that the introduction is done, let’s get to the action 🚀</p><h3>The Setup</h3><p>Usually, every iOS tutorial starts with the project creation. But now, since it’s 2021 and all, you only need <a href="https://swift.org/package-manager/">SPM</a> to build this small app. Let’s do a little bit of <a href="https://www.raywenderlich.com">RW</a> style.</p><p>In Xcode, select <strong>File ▸ New ▸ Swift Package…</strong>. Then set the <strong>Product Name</strong> to <strong>DogBreedsComponent</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c_Yb4d2YORl_n_-wgi9yPg.png" /></figure><p>Click <strong>Create</strong> et voilà. Easy peasy right?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XGP8iELLlFWqVptgy3IaWQ.png" /></figure><h4>Adding necessary dependencies to the Project</h4><p>Let’s update the Package.swift file by adding necessary dependencies that we need for this tutorial. The final result will look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/72f83d4e412f1fccf277a972b60c9a86/href">https://medium.com/media/72f83d4e412f1fccf277a972b60c9a86/href</a></iframe><p>We’ve added 2 dependencies to the package:</p><ol><li>TCA framework itself</li><li>Kingfisher library, that we&#39;re going to use for async image loading</li></ol><h4>Extras</h4><p>For the implementation of this tutorial there are 2 simple extensions</p><p><strong>KFImage+Header.swift</strong></p><p>An extension that helps to build a proper layout with <strong>KFImage</strong>. That’s an <strong>Image</strong> type from the Kingfisher library, with a possibility to load async images:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae23335073027cbfae82fdf069c0fc12/href">https://medium.com/media/ae23335073027cbfae82fdf069c0fc12/href</a></iframe><p><strong>String+Capitalized.swift</strong></p><p>An extension we’re going to use for styling strings.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/03dc41750066d3465d80a8d634d5c06a/href">https://medium.com/media/03dc41750066d3465d80a8d634d5c06a/href</a></iframe><p>Please copy these 2 extensions into your project, to make sure your journey goes as smooth as butter. 🧈</p><h3>Dogs module</h3><p>First, we’re going to build the Dogs module. Basically the main and start module of this tutorial. With TCA it’s usually possible to start with 2 directions: business or layout. You could even split this work between 2 people via splitting business-logic-based State from view/layout-based ViewState.</p><h4>Build the Dogs screen</h4><p>In this tutorial, we’ll start with the layout for the main <strong>Dogs</strong> screen. Here’s what we’re going to build:</p><p><strong>Loading screen</strong>, while loading dog breeds:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*FfnW88LB4biLdmKSmNVimQ.png" /></figure><p><strong>Loaded screen</strong>, with loaded dog breeds and a filtering field:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*-uU0BJVqHuPajeB6ZvYRWw.png" /></figure><p>Let’s create a DogsView itself. The result is supposed to look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/18f3939007614a042568165c26d0bf1b/href">https://medium.com/media/18f3939007614a042568165c26d0bf1b/href</a></iframe><p>Nothing fancy, just a SwiftUI view from a template. However, we&#39;re going to use DogsView as a namespace for a further journey.</p><h4>ViewState</h4><p>Just a small reminder that unidirectional architectures are state-based with a data-driven model. In a data-driven approach, the life cycle will be triggered whenever a piece of data changes. As opposed to an event-driven model where a life cycle will be triggered whenever an event occurs. So, let’s build this “model” ViewState for <strong>Dogs</strong> screen.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f30ebebc0d6a4466b98d7ff15b02bf72/href">https://medium.com/media/f30ebebc0d6a4466b98d7ff15b02bf72/href</a></iframe><p>Here’s what happened:</p><ol><li>A struct <strong>ViewState</strong> which is going to represent <strong>DogsView</strong> layout.</li><li>A filterText property speaks for itself.</li><li>A loadingState state property which is a simple enum <strong>LoadingState</strong>. It&#39;s pretty important to have our <strong>ViewState</strong> consistent, so it&#39;s not possible to end up in a situation where the screen is loading and showing dogs at the same time (if that&#39;s not our intention, of course).</li></ol><h4>ViewAction</h4><p><strong>ViewAction</strong> only represents events from the user or view life cycle. Let’s build every needed action or event for <strong>DogsView</strong> as an enumeration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/60d4674f4896d8cc5beff7dcdec00875/href">https://medium.com/media/60d4674f4896d8cc5beff7dcdec00875/href</a></iframe><p>For <strong>DogsView.ViewAction</strong> we basically listed every action the <strong>DogsView</strong> is interested in. You’ll see how this is used soon.</p><h4>Layout</h4><p>Now let’s build a SwiftUI body for the <strong>DogsView</strong> as presented in the GIF earlier:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/46cec24ad4c8ba6d71d0216ae5d340e9/href">https://medium.com/media/46cec24ad4c8ba6d71d0216ae5d340e9/href</a></iframe><p>Here’s what happened:</p><ol><li><strong>DogsView</strong> owns its own <strong>Store</strong> based on <strong>ViewState</strong> and <strong>ViewAction</strong>.</li><li>SwiftUI TCA based implementation uses WithViewStore that returns a <strong>View</strong> and has a closure with <strong>ViewStore</strong> type inside. <strong>ViewStore</strong> is basically just a wrapper that allows you to have direct access to <strong>State</strong> and ability to send <strong>Action</strong>s.</li><li>Conditional check whether the ViewState.LoadingState is .loading. If it is, we show a progress view, or else a search bar and a breeds list. What&#39;s hidden under searchBar and breedsList you&#39;ll see in a moment.</li><li>In this particular scenario, it’s interesting to know when the view has appeared via sending ViewAction.onAppear to the <strong>Store</strong>. We&#39;ll cover the handling of these events in a bit.</li></ol><p>Now after the main layout was built, let’s take a look at the guts of the searchBar function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ff2d3c849f1ac5e10329d90c64570356/href">https://medium.com/media/ff2d3c849f1ac5e10329d90c64570356/href</a></iframe><p>Here’s only one thing that’s interesting. For the SwiftUI&#39;s text field you need to use <strong>Binding</strong> (A type that can read and write a value at the same time). However, the nature of unidirectional architectures allows mutating (write) values only via <strong>Reducer</strong>. That&#39;s why TCA provides a helper function binding on the <strong>ViewStore</strong>, that reads data from <strong>State</strong> and as a function sends data to the <strong>Store</strong> via Reducer with the given action ViewAction.filterTextChanged.</p><p>In other words, this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4b8000ba1e83e99a191d2b23193e8ba5/href">https://medium.com/media/4b8000ba1e83e99a191d2b23193e8ba5/href</a></iframe><p>Is equivalent to:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0d43f116caf1c666526afeff24067e80/href">https://medium.com/media/0d43f116caf1c666526afeff24067e80/href</a></iframe><p>Let’s have a look at breedsList function real quick:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c722df9f66941075604488e1cb28f77/href">https://medium.com/media/4c722df9f66941075604488e1cb28f77/href</a></iframe><p>Here’s what happened:</p><ol><li>By using ForEach we&#39;re going through the ViewState.breeds array and drawing cells for every breed.</li><li>The cell itself is presented via <strong>Button</strong> and when pressing on we send a ViewAction.cellWasSelected action to the <strong>Store</strong>.</li></ol><h4>Layout Testing</h4><p>What’s so great about SwiftUI? The previews are (when they work at least 😅). TCA&#39;s data driven approach offers super simple ways to test our layout. Here&#39;s an example for <strong>DogsView</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22da4252145a610b843b8e1d117e9e7b/href">https://medium.com/media/22da4252145a610b843b8e1d117e9e7b/href</a></iframe><p>As you can see, by simply stubbing layout data, we can easily test 2 main scenarios (loading and loaded states) for this view. We’re going to cover how to use a reducer and an environment in this scenario later on.</p><h3>Build Dogs business logic</h3><p>After we’ve finished the layout, we’re going to add some business logic. I’m a fan of separating layout and business logic domains. So, let’s build business logic for the Dogs module.</p><h4>State</h4><p>Let’s describe the data of Dogs module feature that needs to perform its logic:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c138e6f4e8a2d5c462c3bc493e7746d/href">https://medium.com/media/4c138e6f4e8a2d5c462c3bc493e7746d/href</a></iframe><p>As you can see, <strong>DogsState</strong> is pretty similar to the <strong>DogsView.ViewState</strong> but not quite the same. This separation approach gives us a possibility to completely split the layout from business logic. By using this approach, it’s also much easier to reuse the same <strong>State</strong> for several screens at the same time or for different layouts for iPhone and iPad.</p><h4>Action</h4><p>Alright, it’s time to build an action type that represents all of the actions that can happen in the Dogs module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/034df436ff4c1971a5ceb49e113ce6ab/href">https://medium.com/media/034df436ff4c1971a5ceb49e113ce6ab/href</a></iframe><p>Because the Dogs module itself is in charge of loading dogs, <strong>DogsAction</strong> has actions related to loading.</p><h4>Environment</h4><p>I already pointed out that we need to load dogs somehow. As you may remember, <strong>Environment</strong> is a type that holds all dependencies.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/05cb78bfb196880134d375bbeb4ce21d/href">https://medium.com/media/05cb78bfb196880134d375bbeb4ce21d/href</a></iframe><p>Here you can see <strong>DogsEnvironment</strong>, which holds loadDogs dependency. The return type of this dependency is an <strong>Effect</strong>. I can&#39;t phrase it any better than the way it&#39;s stated in the official documentation:</p><blockquote><em>The </em><em>Effect type encapsulates a unit of work that can be run in the outside world, and can feed data back to the </em><em>Store. It is the perfect place to do side effects, such as network requests, saving/loading from disk, creating timers, interacting with dependencies, and more. Effects are returned from reducers so that the </em><em>Store can perform the effects after the reducer is done running. It is important to note that </em><em>Store is not thread safe, and so all effects must receive values on the same thread, </em><strong><em>and</em></strong><em> if the store is being used to drive UI then it must receive values on the main thread. An effect simply wraps a </em><em>Publisher (Combine framework) value and provides some convenience initializers for constructing some common types of effects.</em></blockquote><h4>Reducer</h4><p>Let’s put everything together in the dogs reducer:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/25590b5f7d11f4b07f27c72992514ed9/href">https://medium.com/media/25590b5f7d11f4b07f27c72992514ed9/href</a></iframe><p>Here’s what happened:</p><p>First of all, let’s take a look at every return value in this switch. Side effects in TCA provided by Effect as mentioned earlier. TCA framework provides a helper for Effect as well - .none which basically means that none of the work is going to be performed. This .none helper is used for every switch case, but one, which we&#39;ll get to right now.</p><ol><li><strong>Reducer</strong> type in TCA is actually a wrapper structure over the function known as Reducer in unidirectional architectures. This type provides some helper functions that we&#39;ll cover soon.</li><li>DogsAction.breedWasSelected is not handled at this moment, because we&#39;re going to extract navigation from the Dogs module itself.</li><li>DogsAction.dogsLoaded is an action used for <strong>DogsState</strong> to update with new dogs when they&#39;re loaded.</li><li>DogsAction.filterQueryChanged is an action that&#39;s called when the user changes the filter query.</li><li>DogsAction.loadDogs is an action called for dogs request. There&#39;s only one place for this reducer, which returns a side effect via effect. As you can see, we map returned data from environment and map it back into <strong>DogsAction</strong>. Which is basically a great example for a unidirectional approach. After the side effect performed DogsAction.dogsLoaded, action will be called.</li></ol><h3>Finalize Dogs module</h3><p>In the previous steps, we’ve managed to create layout and business logic setups. Now it’s time to put everything together and make it work.</p><h4>ViewState conversion from State</h4><p>First, we need to bring our business logic world into Dogs screen layout. We’re going to use <a href="https://en.wikipedia.org/wiki/Adapter_pattern">converters</a> for it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9e7b706ad6d26ffb72a26159d4e23e1e/href">https://medium.com/media/9e7b706ad6d26ffb72a26159d4e23e1e/href</a></iframe><p>Here’s what happened:</p><ol><li>A simple function which converts <strong>DogsState</strong> into <strong>DogsView.ViewState</strong>.</li><li>Here you see the necessity of having separate states for business and layout domains. We don’t care about formatting in our business logic, but it’s important for the visual part.</li><li>Filtering logic is also just part of state conversion. We don’t perform any special logic for filtering.</li></ol><p>This approach helps with testing a lot too, since it makes our views as dumb as possible. Every view just renders simple data and sends actions back.</p><p>Here are some tests that should prove it:.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8d214456983ebd06aaf6e3723245d5da/href">https://medium.com/media/8d214456983ebd06aaf6e3723245d5da/href</a></iframe><p>We’re going to use this converter inside an extension of <strong>DogsState</strong> and we’ll see how to use it later.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/87c11c217d39092075c18f9af9f3d2cd/href">https://medium.com/media/87c11c217d39092075c18f9af9f3d2cd/href</a></iframe><h4>Action conversion from ViewState</h4><p>Despite state conversions for actions, it’s necessary to convert in the other direction.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0bf8c8de96e35924e42fdcd02dfd8dc2/href">https://medium.com/media/0bf8c8de96e35924e42fdcd02dfd8dc2/href</a></iframe><h4>Showtime</h4><p>Before we’ll show you the final result, we’re just going to add something small to the <strong>DogsEnvironment</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/528761d393cd3cf4cdd4d7481afc062f/href">https://medium.com/media/528761d393cd3cf4cdd4d7481afc062f/href</a></iframe><p>I really admire this way of treating dependencies, because with just a simple extension we’re able to test the whole logic without a real network call. If you’d like to learn more, there is a <a href="https://www.pointfree.co/collections/dependencies">series</a> from pointfree. To mimic some real network call behavior, we’ve added a small delay to see a transition from loading to loaded states.</p><p>Let’s add another <strong>DogsView</strong> preview and see what we’ve got:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c1328f5c99c0cd67d7930eb33c6bc2ee/href">https://medium.com/media/c1328f5c99c0cd67d7930eb33c6bc2ee/href</a></iframe><p>Here’s what happened:</p><ol><li>The first time we’ve only been interested in the layout, but here we used a business logic <strong>Store</strong>.</li><li>Here is a <a href="https://github.com/pointfreeco/swift-composable-architecture/blob/4ea3dfed61f7e60859b888050233dac4243715e0/Sources/ComposableArchitecture/Store.swift#L163-L178">scope</a> function to “scope” business domain into layout view one.</li></ol><p>Let’s take a look at the result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/323/1*CikudnI5wdQDMRK6n0R3QQ.gif" /></figure><p>And it works even without any real API on board! Pretty cool right?</p><h3>Dogs module testing</h3><p>We’ve already had the whole working Dogs module. But what about testing? There’s no need to copy the official readme, so here’s a <a href="https://github.com/pointfreeco/swift-composable-architecture#testing">link</a> on it. In short, the whole State/ Action based approach really helps with testing.</p><h4>TestStore</h4><p>If you’re already finished reading how <a href="https://github.com/pointfreeco/swift-composable-architecture#testing">testing and debugging</a> works in TCA, you probably know what <strong>TestStore</strong> is. Let&#39;s implement it for Dogs module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a2bc4a2b1fa975c983c15586a502d586/href">https://medium.com/media/a2bc4a2b1fa975c983c15586a502d586/href</a></iframe><p>Nothing fancy, just a helper function that takes the same values as a normal <strong>Store</strong> but provides some testing functionality for us. <strong>TestStore</strong> provides send and receive functions that mimic real app/user behavior. But wait a second... What&#39;s the environment: .failing here?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be0efd3521f3764834ff6a0322d14036/href">https://medium.com/media/be0efd3521f3764834ff6a0322d14036/href</a></iframe><p>Remember, how cool we’ve managed to create a fake implementation for <strong>DogsEnvironment</strong>? This is the same situation. But in this case we&#39;d like to fail if anything that used loadDogs dependency was not expected. Remember what I&#39;ve said in the beginning, that <strong>Effect</strong> is just a <strong>Publisher</strong> with helpers? This Effect.failing is one of them.</p><p>Let’s build our first test for dogs loading logic:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b64531362dd0fb181f95763366534c73/href">https://medium.com/media/b64531362dd0fb181f95763366534c73/href</a></iframe><p>Here’s what happened:</p><ol><li>Just a store: TestStore property, which we&#39;ll use for testing.</li><li>Mock of loadDogs dependency.</li><li>Sending an action DogsAction.loadDogs for a request of dogs loading.</li><li>Expecting to receive dogs response as DogsAction.dogsLoaded.</li><li>Here’s an assertion that <strong>DogsState</strong> mutated as expected.</li></ol><p>If you’d like to see how TCA helps with highlighting test fails, please comment on our 2–5 points of the listed code.</p><p>Here’s another filtering behavior that would be nice to test.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d54f524381cff3bf3952e20cd30c233/href">https://medium.com/media/5d54f524381cff3bf3952e20cd30c233/href</a></iframe><p>Nothing complicated, just state mutation when an action is sent.</p><p>Basically, that’s it for the Dogs module. Congratulations! We still have stuff to do though.</p><h3>Breeds module</h3><p>The Breeds module is going to be similar with regards to architectural principles. That’s why it’s a great opportunity to train your new skills.</p><p>Here are requirements for this screen:</p><ul><li>Use Dogs.breed as a title for screen.</li><li>Download a random picture for breed, according to this <a href="https://dog.ceo/dog-api/documentation/breed">documentation</a> and place it as a header.</li><li>Create a list with cells and use Dogs.subBreeds as a title for each cell.</li></ul><p>The final result would look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*n7-LVluWP395Dh5CYS5LOg.png" /></figure><p>After you finish or if just want to skip this exercise, check this proposed code:</p><p><a href="https://github.com/Atimca/TCA-tutorial/tree/master/Sources/DogBreedsComponent/Breed">Breeds module</a></p><p><a href="https://github.com/Atimca/TCA-tutorial/tree/master/Tests/DogBreedsComponentTests/Breed">Breeds module tests</a></p><h3>App module</h3><p>So far we’ve accomplished 2 modules: Dogs and Breeds. However, they are completely independent from each other. Also: there’s no way to navigate from Dogs to Breeds. Let’s try to solve it with modularization techniques in TCA. If you&#39;d like to know more details, watch this <a href="https://www.pointfree.co/collections/composable-architecture/modularity">pointfree collection</a> about modularity.</p><p>Navigation is still a topic under discussion and there’s no clear approach for it yet. I’m going to show you my vision on it. Well, one of my visions actually. For the App module there is no need to create a separate <strong>ViewState</strong> and <strong>State</strong> because the App module is going to serve only as a mediator with navigation over Dogs and Breeds modules.</p><h4>AppState</h4><p>First of all, it’s good to remember that TCA is a part of a state-based unidirectional architectures family. In these architectures, there is usually just <strong>ONE</strong> state for the whole application. However, TCA framework provides some helpers for state composition. In other words, we can create several independent modules with independent states, which connect inside a single bigger state.</p><p>Let’s start with the heart of the module <strong>AppState</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d249699912402bc6a1be988b84b82e95/href">https://medium.com/media/d249699912402bc6a1be988b84b82e95/href</a></iframe><p>Here’s what happened:</p><ol><li>In this example, a dogs property is a shared property within the whole application. For other scenarios, it could be a <strong>User</strong> property, which you&#39;ll need access to throughout the app.</li><li><strong>DogsInternalState</strong> we’re going to cover the next step. You could treat it as a Dog module state inside the <strong>AppState</strong>. It’s not optional, because the Dogs module basically exists within the whole app life cycle.</li><li><strong>BreedState?</strong> is an optional state for the Breeds module. This state is optional because we use it for our detailed screen aka Breeds module.</li></ol><p>But what’s this <strong>DogsInternalState</strong> thing? Let’s take a look:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c13e8216ce88bb969764e0cacef2226c/href">https://medium.com/media/c13e8216ce88bb969764e0cacef2226c/href</a></iframe><p>Here’s what happened:</p><ol><li>You may remember <strong>DogsState</strong> contains 2 properties: filterQuery and dogs. However, dogs is shared within the whole application. So, <strong>DogsInternalState</strong> is a helper entity, which consists of every property inside <strong>DogsState</strong> that are not shared with an upper module <strong>AppState</strong>. <strong>DogsInternalState</strong> has 2 initializers: one as an initial for <strong>AppState</strong> and a second one as a helper for initialization from <strong>DogsState</strong>.</li><li>This extension is just a convenience initializer from <strong>DogsInternalState</strong>, which contains any not shared property and the shared property itself.</li><li>A computed property dogsState which actually is a <strong>DogsState</strong> part of <strong>AppState</strong>.</li></ol><h4>AppAction</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b94686637010242c85b63e3e265a5c14/href">https://medium.com/media/b94686637010242c85b63e3e265a5c14/href</a></iframe><p><strong>AppAction</strong> as <strong>AppState</strong> is a composition of <strong>BreedAction</strong> and <strong>DogsAction</strong>. However, there’s one extra action <strong>AppAction.breedsDisappeared</strong> which speaks for itself.</p><h4>AppReducer</h4><p>Let’s now try to build a reducer for App module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1e529619df3e21f649b3ab271a46c824/href">https://medium.com/media/1e529619df3e21f649b3ab271a46c824/href</a></iframe><p>Here’s what happened:</p><ol><li>Breed module actions inside <strong>AppReducer</strong>, in which we have no interest whatsoever.</li><li>AppAction.breedsDisappeared an action where we need to clear <strong>BreedState</strong> after a screen disappeared.</li><li>DogsAction.breedWasSelected was abandoned inside <strong>DogsReducer</strong>. Now it&#39;s time to handle this action. We simply create a new <strong>BreedState</strong> that serves as a state for the Breed module. We&#39;ll show you how this state change will reflect navigation in the next steps.</li><li>Because we are interested in just one action from the Dogs module, all other actions can be safely ignored.</li></ol><p>But wait! If the <strong>AppReducer</strong> ignores almost every action from Dogs and Breed modules, how ‘s this thing supposed to work at all? 🤔 The answer is simple. We’ve mentioned that <strong>Reducer</strong> is basically a wrapper over a reducer function + some handy helpers, right?</p><p>Before the big reveal, let’s implement prod or live versions for our environments.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f9d29e1d80a893fab7d4145fdfc8370/href">https://medium.com/media/1f9d29e1d80a893fab7d4145fdfc8370/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/072c468b66b56928f3c2ce5b24422c72/href">https://medium.com/media/072c468b66b56928f3c2ce5b24422c72/href</a></iframe><p>Nothing really interesting here, just simple backing <strong>URLSession</strong> calls into needed dependencies. But have you already noticed we have 3 different implementations (failing, fake, and live) of environments without using protocols and such?</p><p>Now let’s go back to the reducers:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cef8889b189eeac6321c17d9b00de900/href">https://medium.com/media/cef8889b189eeac6321c17d9b00de900/href</a></iframe><p>Here’s what happened:</p><ol><li>Combining method helps to “combine” different reducers into one big reducer. So this combined reducer is going to work with every performed action from App, Dogs, and Breed modules as we’d like it to work.</li><li>As the first reducer here we use an <strong>AppReducer</strong> itself.</li><li><strong>DogsReducer</strong> that we combined with a big <strong>AppReducer</strong> .That’s possible thanks to the <strong>AppState</strong> and <strong>AppAction</strong> structure.</li><li><strong>DogsReducer</strong> is pulled back into <strong>AppReducer</strong> with the pullback function help. And as a result of this function we have <strong>AppReducer</strong>.</li><li>Via the usage of Swift <strong>KeyPath</strong>, we can say that <strong>DogsReducer</strong> is only going to work with the dogsState part of the <strong>AppState</strong>.</li><li>Via the usage of pointfree <strong>CasePath</strong> (if you’d like to know more, check out this <a href="https://github.com/pointfreeco/swift-case-paths">repository</a>. In short, it’s a way to use enums in the same fashion as KeyPaths). We can say that <strong>DogsReducer</strong> is only going to work with the AppAction.dogs part of <strong>AppAction</strong>.</li><li>Here, we’ve just created a <strong>DogsEnvironment</strong>. If our app is more complicated and has a lot of dependencies, we’d use a closure parameter <strong>AppEnviroment</strong>. But in this case it’s just a <strong>Void</strong>, so we don’t need it.</li><li><strong>BreedReducer</strong> that’s also combined into the big <strong>AppReducer</strong></li><li><strong>BreedState</strong> is optional inside <strong>AppState</strong>, so we use another <strong>Reducer</strong> helper optional.</li></ol><h4>RootView</h4><p>Basically, we’ve built the whole necessary logic, but haven’t made a real navigation yet. The final <strong>RootView</strong> of the app:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e119615570008833c99c933fa1948a76/href">https://medium.com/media/e119615570008833c99c933fa1948a76/href</a></iframe><p>Here’s what happened:</p><ol><li><strong>DogsView</strong> was created as an immutable variable because it exists in the whole app life cycle and basically the main view of the app.</li><li>In the <strong>RootView</strong> we’re just interested in the breedState part of the <strong>AppState</strong> only for navigation purposes, which means that closure will be called only on breedState changes.</li><li>The body of the view contains <strong>DogsView</strong> and invisible <strong>NavigationLink</strong> which is backed by <strong>ViewStore</strong> <strong>Binding</strong> with a destination of <strong>BreedView</strong>.</li><li>A property for <strong>BreedView</strong> creation. If you take a look inside, you’ll see the <strong>IfLetStore</strong> entity, which helps to create views, backed by store, only when it’s possible.</li></ol><p>That’s basically it. For the last step, let’s put everything together inside the <strong>RootView</strong> preview.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d859a216cac9aaa2cf14bf3c9b0b78b/href">https://medium.com/media/5d859a216cac9aaa2cf14bf3c9b0b78b/href</a></iframe><p>You should see a working app with a real live API.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/323/1*Cl_x0KtIR60c2EhNemkCPQ.gif" /></figure><h4>App tests</h4><p>Last but not least. Here’s the one test for App module:</p><p><strong>AppStoreTests.swift</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9d0677683aebbf3189ce886dd9f640a9/href">https://medium.com/media/9d0677683aebbf3189ce886dd9f640a9/href</a></iframe><p>That’s all folks! You’ve just built you’re first TCA based application. Congratulations! 🥳</p><h3>Where to go next</h3><ul><li><a href="https://github.com/pointfreeco/swift-composable-architecture">The framework itself</a></li><li><a href="https://www.pointfree.co/collections/composable-architecture">PointFree TCA video collection</a></li><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">Series of articles about reactive programming and unidirectional architectures</a> Learn more about the paradigm behind it and how to build your own unidirectional architecture framework.</li><li><a href="https://academy.realm.io/posts/try-swift-nyc-2017-krunoslav-zaher-modern-rxswift-architectures/">A video of another unidirectional architecture RxFeedback</a> A solid introduction to the concepts.</li><li><a href="https://redux.js.org">redux.js.org</a> Thorough documentation about Redux framework for js. Don&#39;t need to go into the details, but this website contains a good explanation of the concept.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d220fd25cab3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to cook reactive programming. Part 4: Testing.]]></title>
            <link>https://medium.com/@atimca/how-to-cook-reactive-programming-part-4-testing-529bd0404270?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/529bd0404270</guid>
            <category><![CDATA[unidirectional-data-flow]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[rxswift]]></category>
            <category><![CDATA[combine]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Wed, 08 Jul 2020 16:42:31 GMT</pubDate>
            <atom:updated>2020-07-08T16:42:31.162Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*Vopo_TfaUWfy5A2C2Xu8Lg.png" /></figure><p>Last time we were talking about different types of modularization for Unidirectional data flow. And this time we are going to talk about the most important topic - testing. I&#39;d say the whole of this journey was about this topic.</p><blockquote><em>This time I’d highly recommend reading all the previous articles, because reading about testing in isolation doesn’t make any sense, without understanding the concepts of </em><em>reactive programming and </em><em>Unidirectional data flow.</em></blockquote><ol><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7">How to cook reactive programming. Part 1: Unidirectional architectures introduction.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">How to cook reactive programming. Part 2: Side effects.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=friends_link&amp;sk=53e13576063afefd4a533944eee5d183">How to cook reactive programming. Part 3: Modularization.</a></li></ol><p>Thousands of kudos to <a href="https://medium.com/u/a737a378ae61">Dave Phillips</a>. He really helped with this article!</p><h3>Intro</h3><p>I think this article will be the shortest one in the whole cooking saga, but as I said above and I want to repeat, it will be the most important one. Let&#39;s take for the experiments our old friend:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ea7dd4ebee8ef37cc0220714c7ece44e/href">https://medium.com/media/ea7dd4ebee8ef37cc0220714c7ece44e/href</a></iframe><p>It’s quite a simple state machine, where every state is represented as an enum case. I don’t think it’s a secret for anyone that unidirectional architecture is highly based on functional programming approaches. That’s why we’ll start with the most functional thing about all unidirectional architecture — reducer.</p><h3>Reducer</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4a2176af5e706d09cf983da58f059e18/href">https://medium.com/media/4a2176af5e706d09cf983da58f059e18/href</a></iframe><p>If you remember, reducer is a pure function. It has two inputs: previous state of the system and event for mutation of this state. As output, there’s a resulting state.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c8e40ee5426bb4a39a3b6b2cc7333612/href">https://medium.com/media/c8e40ee5426bb4a39a3b6b2cc7333612/href</a></iframe><p>It should be quite obvious how to write tests for this kind of function. For these inputs, we have this output, zero dependencies, zero surprises. I want to show you one example, just to be sure that everyone stays in sync.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/77e07757d97854eff9c07388b6a4f19f/href">https://medium.com/media/77e07757d97854eff9c07388b6a4f19f/href</a></iframe><p>And that’s it. I bet it’s one of the most simple tests that you’ve ever seen. However, there’s not only a reducer in the system. Moreover, we have the whole system with side effects and everything else. How do we test all this stuff? Actually I’m going to say that integration tests couldn’t be easier as in unidirectional approaches.</p><h3>Testing the system</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ahFm1u9XPvO9GbV3dZCegw.png" /></figure><p>Because we have a unidirectional data flow system which is based on events, and can be mutated only with events, testing the whole user flow becomes super easy. Unfortunately, the <strong>Combine</strong> framework doesn’t have a testing SDK yet, so that’s why I’ll use a little bit of <strong>RxSwift</strong> code, but don’t worry, here I’m going to use the most primitive concepts of <strong>RxSwift</strong>. Firstly let me show the test of the quite complicated user scenario. The user wants to add an event into the calendar but doesn’t have a calendar permission for it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2aafbc54deaa4bb576be197e4f66f88f/href">https://medium.com/media/2aafbc54deaa4bb576be197e4f66f88f/href</a></iframe><p>Firstly, I’ve used a TestStore which is a special test implementation of the store. The biggest difference is that this store can receive events as input for the sake of real user behavior simulation. We have two events from the user right here: showScene, where the user tries to open a calendar for adding a new event and userFinishedWithCalendarEditor, whose name speaks for itself.</p><p>Also, inside the TestStore I&#39;ve mocked the permissionService to return the <strong>authorized</strong> status for every authorization attempt it helps to test a successful flow.</p><p>And last but not least we received an array of every state mutation in the result, which helps us to see what’s really going on there. Which scenes were opened and closed, how permissions were changed. I can even say that it looks like a UI testing, but without UI.</p><p>But what is this TestStore and what is the difference with the normal store?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/228e227c5f10aa2c76bc8d65583be2ce/href">https://medium.com/media/228e227c5f10aa2c76bc8d65583be2ce/href</a></iframe><p>Please don’t be scared of <strong>RxSwift</strong> code here, everything is quite simple. Let me explain. As far as you know every reactive framework is based on the event sequences. And every event has its own time when to appear in this sequence. <strong>RxTest</strong> in this play is a special framework, which can help us to avoid all this timing complexity. Moreover, in this particular case, it helps us to provide an array of input events for our system, which helps to simulate real user behavior. That’s it, there’s no other difference compared to a normal Store.</p><p>Actually, there’s one other cool feature, which we can do with a concrete <strong>TestStore</strong> implementation for the concrete system. It’s about mocking dependencies. I don’t think it’s a secret that one event or state mutation can produce a side effect. Sometimes it’s not so handy when your state could be mutated by some events, caused by other side effects. Let me provide an example. You’ve started to work with adding new events into the calendar, but by the app logic, we should first show you an alert with a login option, even if the login itself is not required for adding an event into the calendar. It doesn’t sound very user friendly, but I made up this example only as an example. However you really want to avoid this complexity for your test. You have two solutions here. The first solution is just to mock an auth service and say to it that your user has already been authorized. However, if that’s not an option for any reason, you can just mock your alert module with a <strong>never</strong> return. Remember, that in reactive frameworks we speak in the language of data sequences. So, technically every sequence could produce zero elements for the whole time, so it’s a <strong>never</strong>. This is an example, how could it look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00d1b39fa271d078d8cdbda04c3c5280/href">https://medium.com/media/00d1b39fa271d078d8cdbda04c3c5280/href</a></iframe><p>Also, you can see a TestScheduler. This is a special scheduler, which helps us to work with a made-up (virtual) time. If you don’t know what scheduler is, in simple terms every one of your events in the system goes according to the imaginary clock, with this clock ticking and on every tick, an event could appear. So, this clock is the scheduler itself.</p><h3>TCA</h3><p>No articles without Composable Architecture so far... These two fellas really provide a lot of information to think about. While working with the approach that I&#39;ve shown you before, <a href="http://pointfree.co">pointfree.co</a> shows an even more advanced version of testing the whole system. I&#39;ll show you a little bit of it, but you can make yourself familiar with this <a href="https://www.pointfree.co/episodes/ep103-a-tour-of-the-composable-architecture-part-3">episode</a> which is free to watch.</p><p>The test itself looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fdae3de9c4cab7f29d63f32092d4ee68/href">https://medium.com/media/fdae3de9c4cab7f29d63f32092d4ee68/href</a></iframe><p>They use the same concept of the <strong>TestStore</strong>, that I’ve shown before, but it’s really more advanced. The testing of the system is now like magic.</p><p>One remark I’d make is their reducer looks a little bit different, and I’ve already made an overview of it in my article about side effects.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e642803495d317da374e1380da9b365b/href">https://medium.com/media/e642803495d317da374e1380da9b365b/href</a></iframe><p>It has an environment, which holds all dependencies. So, how does their approach work? Firstly they can provide mocks for every dependency inside the test itself, mostly in the same way as I’ve shown you before. But further cool things happen. They have two different directives — send and receive. What are they about? The Send directive is the same as I&#39;ve demonstrated in the previous approach, it is just what the user or other part of the app could send into your system. Inside a closure of it, you provide all changes of the state which should happen, to validate them. The Receive directive is the event which you will expect from the system, according to your side effects work. And the same closure to validate the state changes. So here, you really can test the whole flow.</p><p>However, <a href="http://pointfree.co">pointfree.co</a> is not <a href="http://pointfree.co">pointfree.co</a> if they don’t take one step further. Just look how their assert function shows you if your state wasn&#39;t mutated as expected:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62adb5945944e59757705d827943e27f/href">https://medium.com/media/62adb5945944e59757705d827943e27f/href</a></iframe><p>And yes, it shows you the exact place, where the error happened. It’s crazily cool I would say.</p><h3>Outro 😔</h3><p>Usually, I say here something about that there’s no silver bullet, but this article was mostly not about approaches, but to show you how it is easy to test unidirectional approach. You really firstly can put all feature behavior in your tests and only after it starts to write a working code. If you don’t write the test before, you will after adopting unidirectional approaches. So this was the last article about reactive programming and unidirectional approaches! I hope for now you have enough experience to cook it in the right way.</p><p>If you liked this article don’t forget to smash that clap button. Moreover, you can do it 50 times, for you, it’s super easy, but it will be really helpful for me.</p><p>If you don’t want to lose any new articles subscribe to my <a href="https://twitter.com/atimca">twitter account</a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/73c1e854b65467ed35182dfbf1e2df9f/href">https://medium.com/media/73c1e854b65467ed35182dfbf1e2df9f/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=529bd0404270" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to cook reactive programming. Part 3: Modularization.]]></title>
            <link>https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e1d593bfb11</guid>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[unidirectional-data-flow]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[rxswift]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Mon, 22 Jun 2020 09:14:51 GMT</pubDate>
            <atom:updated>2020-09-04T09:46:00.072Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ck0gvPO8UVDgGwrlmjeGqw.png" /></figure><p>Last time we were talking about different types of Side Effects, and moreover I showed you some libraries which support Unidirectional data flow approaches. I can certainly say if you’ve already read all the previous articles you now have a clear idea of how reactive programming works, and how to build a unidirectional architecture by yourself.</p><p>I would highly recommend firstly reading at least the two previous articles. However, if you’re not familiar with frameworks such as RxSwift or Combine, or reactive programming in general, I’d suggest reading my first article as well.</p><p>Thousands of kudos to <a href="https://medium.com/u/a737a378ae61">Dave Phillips</a>. He really helped with this article!</p><h3>Back to the future</h3><p>I’ve finished all my articles already. And now we can go back to the future 🏎…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/1*GYDwNtW2C-vulJX4LefGXg.jpeg" /></figure><ol><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7">How to cook reactive programming. Part 1: Unidirectional architectures introduction.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">How to cook reactive programming. Part 2: Side effects.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=friends_link&amp;sk=53e13576063afefd4a533944eee5d183">How to cook reactive programming. Part 3: Modularization.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-4-testing-529bd0404270?source=friends_link&amp;sk=d6a5bba89e00afe8fce18dba5ced814b">How to cook reactive programming. Part 4: Testing.</a></li></ol><h3>Intro</h3><p>As I mentioned in my previous article, we live in a world where applications are not one button flashlight apps anymore. We have teams of more than ten people. And if you noticed, the main idea of Unidirectional architecture is to keep all data in one place. I bet, if you start with this approach, you’ll end up with a huge State and Reducer if not at the end of the week, then certainly by the end of the month. You may wonder how it&#39;s possible to separate the Unidirectional approach on different modules when the main idea is to keep everything in one place. That’s exactly what I&#39;m going to show you today.</p><p>Today I will show you two approaches for Unidirectional architecturemodularization. I picked these two not because there are not more out there - you can easily find them if you search the internet. I picked them because they are opposite to one another. As a starting point, I picked a module that I want to use for experiments from the previous chapter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a387bb8d5482e7810b192fec47b361ad/href">https://medium.com/media/a387bb8d5482e7810b192fec47b361ad/href</a></iframe><p>But this time we need an app, where all the magic will happen. I’d like to keep it as simple as possible.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/df16e43b4fc4b93b72a3f2e2f1357caf/href">https://medium.com/media/df16e43b4fc4b93b72a3f2e2f1357caf/href</a></iframe><p>Imagine you have a small module like I’ve shown you recently, which can download news titles. Let’s just name it News. And you have the app itself, let&#39;s just call it App. Quite a simple module I’d say, but this time we need a User who’s shared within the whole app. Moreover, let&#39;s add a situation when the main app should know about the loading step from the news module, for example, it has another page, which depends on the news titles. So, let&#39;s start with the first approach on how to connect it to the main app. A list of requirements would look like this:</p><ul><li>The App needs to know about all changes in the News</li><li>The News needs to know about all changes in the part of the App (User)</li></ul><p>I think these requirements are simple and are enough for showing modularization concepts. So, let’s start with the first approach.</p><h3>Composable Reducers</h3><p>If you read my previous article, I bet you’ve already understood what architecture I’m going to talk about. <a href="https://github.com/pointfreeco/swift-composable-architecture.git">Composable Architecture</a> provides a really good way for modularization. What do they do?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*InTKrzZ_jRk5uw2kKh1HaA.png" /></figure><p>The main idea of the modularization with the composable approach is to store every Eventand every State in the App module. Let&#39;s change the app a little bit to conform to the new requirement.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ac4f41f901e7dad848b6e6550eae6f2/href">https://medium.com/media/3ac4f41f901e7dad848b6e6550eae6f2/href</a></iframe><p>So far, I’ve just put everything inside the App itself. We’ll talk about problems with this approach a little bit later. For now, we need to proceed and solve the next problem. How would this system work? Maybe you&#39;ve noticed that I omitted reducer for the new app variation. I did this on purpose because the entire work which should be done exists in the reducer itself.</p><p>Let’s try to solve this problem as it stands with building a new reducer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ff2031214c3f5bf88f10d04f687dda5/href">https://medium.com/media/1ff2031214c3f5bf88f10d04f687dda5/href</a></iframe><p>It’s a little bit clumsy, but it works. However, I’ve just generated another problem. NewsStateis optional and should be created somewhere. Let&#39;s try to create it the first time when .newsEvents have appeared. The final reducer would look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/232498530bfa5e60c9e1d04289cc37d7/href">https://medium.com/media/232498530bfa5e60c9e1d04289cc37d7/href</a></iframe><p>Now the system works. However, it doesn’t look like a modularization at all. All actions happen inside one function in the main application. Let’s try to fix it a little bit. We’ve already had a reduce function for the News module. I want to try to adopt it as is to the previously implemented reducer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bf298b549edaf45ae8571dbc41901f24/href">https://medium.com/media/bf298b549edaf45ae8571dbc41901f24/href</a></iframe><p>Now we have the composition of the most primitive function. It looks better, but it’s still not what we would expect from modularization. Could we somehow improve this composition? Of course we can — in the end, I’m not inventing here anything.</p><p>I’d suggest starting with the functions declaration first. What do we already have? We have two reducers, which work like one reducer. What does that mean? It means we want a function which could compose two separate reducers into one. So, for the first step, we need a reducer declaration.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7ef19d8bb25a2c5b2b54dbb17f727d1f/href">https://medium.com/media/7ef19d8bb25a2c5b2b54dbb17f727d1f/href</a></iframe><p>Just a type alias for the function, which takes State and Event as the input and provides a result state as an output. Ok, so there’s nothing new here. For the next step let&#39;s make a declaration for the combine function, which combines multiple reducers into one.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/66c03c2a587f922a33fcabd5a8b38d0a/href">https://medium.com/media/66c03c2a587f922a33fcabd5a8b38d0a/href</a></iframe><p>Things are progressing easily so far. Now with these declarations, we’ll write a realization for the combine function. We just need to chain every reducer with the provided state and event.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b870ec5ce85290c2f6343c52beeecf4c/href">https://medium.com/media/b870ec5ce85290c2f6343c52beeecf4c/href</a></iframe><p>This function could be realized with a simple “for” loop, however, the usage of the reducefunction inside our combine looks more symbolic, doesn&#39;t it? Let&#39;s try out what we&#39;ve done so far.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2df80dcf24997e9d35e13115cf2466fe/href">https://medium.com/media/2df80dcf24997e9d35e13115cf2466fe/href</a></iframe><p>What have I just done? I’ve created two reducers, combined them into one result reducer, and performed two mutations. As a result you can see that two completely separated reducers mutate one state, which is a proof of concept. However, I created another problem, and I’ve started to have the feeling that I’m only creating problems, not solving them. The combinefunction can work only over one type of state - AppState- and one type of event - AppEvent. We have the News module, which has different state and event types. How could this situation be resolved? Maybe you&#39;ve already guessed, according to my first iterations, that NewsState, now a part of AppState and NewsEvent, is a part of AppEvent and we could apply some conversions to fulfill combine function requirements. But what should we do exactly? We need to convert NewsReducer into AppReducer.</p><p>NewsReducer has this declaration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d0a869e135a31e5ac8502b2584b15c9a/href">https://medium.com/media/d0a869e135a31e5ac8502b2584b15c9a/href</a></iframe><p>And AppReducer this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/626d55a25fb739de35b30e6ce963f481/href">https://medium.com/media/626d55a25fb739de35b30e6ce963f481/href</a></iframe><p>I want to split this task into two smaller ones. Let’s start with transforming</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7987fa5addbf651734d847f8b1276366/href">https://medium.com/media/7987fa5addbf651734d847f8b1276366/href</a></iframe><p>into</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/080e0432e0bfd0e2c7ac9ad22beb1dcc/href">https://medium.com/media/080e0432e0bfd0e2c7ac9ad22beb1dcc/href</a></iframe><p>As usual I want to start with a function definition:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/14da42fc3739f58defd36442d636a799/href">https://medium.com/media/14da42fc3739f58defd36442d636a799/href</a></iframe><p>Because Reducer is a function itself, we need to build a function inside another function 🤯. The first step will look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ea93eb5dfab85dd986b5da845871b500/href">https://medium.com/media/ea93eb5dfab85dd986b5da845871b500/href</a></iframe><p>To build a function which uses AppEvent and AppState we have NewsState and AppEvent. What can we do here? Because we need to put NewsState inside NewsReducer we need to somehow transform AppState into NewsState:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/29c55953a73fbff9f3f8e634d34a2fdd/href">https://medium.com/media/29c55953a73fbff9f3f8e634d34a2fdd/href</a></iframe><p>We’re Halfway there, but it’s not enough, as we’ve got an error</p><blockquote><em>Cannot convert return expression of type ‘NewsState’ to return type ‘AppState’</em></blockquote><p>It means that we need somehow to transform the news reducer result in AppState. We already know that NewsState is a part of the AppState, so it shouldn’t be so hard.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/efc9bc649edd2518f9d59ad5d9bfee64/href">https://medium.com/media/efc9bc649edd2518f9d59ad5d9bfee64/href</a></iframe><p>It will work, I can assure you. However, it doesn’t look generic enough for usage for different applications with different state interfaces. So let’s fix it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c471ed2fa436b3a9a01903e64a67eab/href">https://medium.com/media/4c471ed2fa436b3a9a01903e64a67eab/href</a></iframe><p>Much better, but we could refactor it a little bit more with a KeyPath usage, and decrease the number of input parameters of the function, so let&#39;s try it out.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/17527a62a819452621055f5a284837b1/href">https://medium.com/media/17527a62a819452621055f5a284837b1/href</a></iframe><p>That’s what I’m talking about. Let’s move forward, we still have unfinished business according to events. The desired transform function will look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d15db1e7b1f7c4f94612558ce9676fc8/href">https://medium.com/media/d15db1e7b1f7c4f94612558ce9676fc8/href</a></iframe><p>Let’s start with an update to the existing one:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/648040417515d6fdcd74c7c642af8cc2/href">https://medium.com/media/648040417515d6fdcd74c7c642af8cc2/href</a></iframe><p>This code will show another error:</p><blockquote><em>Cannot convert value of type ‘AppEvent’ to expected argument type ‘NewsEvent’</em></blockquote><p>As far as you can see a Swift compiler really helps in these kinds of things, as throughout I’m just doing whatever it says to me. And now we need to convert AppEvent into NewsEvent. We&#39;ve already made one as a part of another. Now we should make one small addition to make things easier.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a4300b83bf92bf806cee310916f9db9/href">https://medium.com/media/3a4300b83bf92bf806cee310916f9db9/href</a></iframe><p>We have a newsEvent property, which allows us to easily convert AppEvent into NewsEvent if it&#39;s possible. I&#39;m going to add this update and fix the error.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a82bc723b228ec2c401af339b1ad2505/href">https://medium.com/media/a82bc723b228ec2c401af339b1ad2505/href</a></iframe><p>In this case, if the app event was a news event we will perform a news reducer. However, the same small change should be added to make the transform function more generic. What have we done so far? We converted AppEvent into NewsEvent, so should we just add a conversion function as another parameter of the transform function?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/85b74b3c06d58125a937b260893af151/href">https://medium.com/media/85b74b3c06d58125a937b260893af151/href</a></iframe><p>Perfect! Now we have a transform function, which will really help with the reducers composition. Shall, we add the final step to make transform and combine into generic functions?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ba87c5be030bc1ab04a078434bf1129d/href">https://medium.com/media/ba87c5be030bc1ab04a078434bf1129d/href</a></iframe><p>Voila! So it’s a small change, but we can use these functions for every reducer right now. Let’s test them with our previous test case.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a1c52129ae2854165ef3555f2ae52220/href">https://medium.com/media/a1c52129ae2854165ef3555f2ae52220/href</a></iframe><p>The output is the same as on the previous occasion, however we now have a fully generic approach to achieve this. And that’s it, we’ve achieved a fully generic way of Unidirectional architecture modularization. It&#39;s actually quite a straightforward way to modularize your system. Before we move forward to another modularization approach, let&#39;s talk a little bit about the pros and cons.</p><p><strong>Pros </strong>👍<strong>:</strong><br>The true way of Unidirectional data flow. You don&#39;t lose any of the advantages of the unidirectional approach and as far as you can see the main mantra still applies - everything is in the one place, everything works in the one direction, everything is consistent. It goes from the previous point, there&#39;s no way - unless of course you deliberately make one - when you have for instance different users in different modules.</p><p><strong>Cons </strong>👎<strong>:</strong><br>Not true module separation. To achieve this modularization approach you need to reveal the State and Event of the underlying module to the module where you attach things. It shouldn&#39;t be a big problem if all your modules work together only in one project or several affiliated projects. However, it could cause some problems in two cases. The first case is if you just have started to use unidirectional approaches in your codebase. I bet you want to isolate and reuse modules in this case, not connect them in one place. In the second case when you work over a framework, you shouldn’t expect your customers to adopt a way of modularization, which I&#39;ve just shown to you.</p><p>As I’ve mentioned before, what I’ve shown you I took from the <a href="https://www.pointfree.co/collections/composable-architecture">pointfree</a> channel. I’ve tried to make things a little bit different. They separated the app by modules, but I attached the existing module to the app. It’s not a big difference, but if you want to go deeper consider watching their videos as well. Also, they’ve explained a lot of functional programming concepts, which we used to achieve this modularization approach.</p><h3>Fully separated approach</h3><p>Do you remember what were the problems of the previous approach? That it’s hard to use in isolation and you have to reveal a state and event for an upper module. With this approach, you can solve these problems.</p><p>For this time we need to remember about Store.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/60ff12d14d2ea28103b53079918d3457/href">https://medium.com/media/60ff12d14d2ea28103b53079918d3457/href</a></iframe><p>Why do we need Store here so badly? Because Store is an entry point of the whole module creation. We actually need it for Composable Reducers, but it’s not so bad and I wanted to save a little bit of your time.</p><p>So, how do we achieve modularization? The answer is actually more straightforward or even easier than with a previous approach. We just need to provide a way of updating information from the outside world and provide a way to notify changes from the child module.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*zIdaTjc-Bq6Wsoun3ko9Lw.png" /></figure><p>With any reactive framework, it’s a super-easy task. So, let’s implement it in one step.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/84337f1da9dc3cf2067f22247072e988/href">https://medium.com/media/84337f1da9dc3cf2067f22247072e988/href</a></iframe><p>What are all the interesting things that happened in the Store? I&#39;ve just added two publishers Input and Output. With input, I can observe what happened in the outside world of the module and update data, according to the input event. With output, I can cut a piece of the state, which could be interesting in the outside world. Also, there’s one small addition because the sink method produces Cancellable type, so we need to somehow utilize this sinksubscription. I&#39;ve attached it to the lifecycle of the view controller however, it could be done in different ways since unidirectional architecture could be used not only in the partnership with a view.</p><p>The second approach part ended up much shorter than the previous one. I hope it’s because this approach is far easier to understand and to implement, not because I’m too lazy to write it step by step. Now let’s talk about the pros and cons of this approach.</p><p><strong>Pros </strong>👍<strong>:</strong><br>True modularization. An application doesn’t depend on the underlying module realization. If you want to try unidirectional approaches, it’s a way to adopt this as an only part of the project. Also, it’s suitable for SDKs creation.</p><p><strong>Cons </strong>👎<strong>:</strong><br>It’s too easy to create the not true unidirectional state, because modules could have their own independent states and the whole app state could be inconsistent. Because it’s a state-based system, sometimes you have to almost manually reset a state. Imagine the situation, that you need to open another scene from your child module. You have something like sceneForOpen property in the child module. The main module should send something, like sceneWasShown, back to the child module for clearing sceneForOpen property. Otherwise, if you go back and want to open the same page again nothing would happen, because the child&#39;s state hasn&#39;t been changed.</p><h3>What about Side Effects?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*qMBiYIS1-lmXiSt7VIukPA.jpeg" /></figure><p>Side effects realization with modularization highly depend on the way you implement these side effects.</p><p>With the second fully separated approach there’s no difference in handling side effects at all. You have a fully separated module with its own side effects, when you create this module side effects will work, as I’ve shown in the <a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">previous article</a>.</p><p>On the other hand, we have an approach with composable reducers. And thus I don’t want to repeat the <a href="http://pointfree.co">pointfree.co</a> Effects approach to modularization. You can easily find an explanation in their videos or on <a href="https://github.com/pointfreeco/swift-composable-architecture">github</a>.</p><p>However, I want to show you at least something. Composable architecture has its effects system, but imagine the situation when you have composable reducers as a modularization approach and query-based side effects. Here’s some code, showing how you could create a child store (child module) from the main store (main module). The main idea here is that every module has its own store, but every child module has a piece of this store from the main module.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3f8b40ab8ef1d9b00e9955fe49477191/href">https://medium.com/media/3f8b40ab8ef1d9b00e9955fe49477191/href</a></iframe><p>In this case, we have a scope function which transforms the main store to the child one. Here SideEffect&lt;LocalState, LocalEvent&gt; is a pairing of query and action. The main idea of this approach is that while we create a child module, we inject side effects from it to the scope function. It gives us a way to construct modules with independent side effects. Every other action which is occurring in this function is mostly about main - child communication. It&#39;s necessary because we want to reflect changes from the main module inside the child one and visa versa.</p><p>There’s nothing hard to understand if you’ve already got how to handle modularization in general, trust me.</p><h3>Outro</h3><p>As usual, there’s no silver bullet for modularization. You can decide for yourself what to use. So far, you’ve become familiar with how to work and even how to build your own reactive framework and unidirectional architecture. Actually you know most of these things already. However, in my opinion, there’s still one important topic left — testing. Unidirectionalarchitectures give us a super elegant way of testing your code. How to do the testing I will show you in the next article. So, let&#39;s keep in touch!</p><p>If you liked this article don’t forget to crash a clap button. Moreover, you can do it 50 times, for you, it’s super easy, but it will be really helpful for me.</p><p>If you don’t want to lose any new articles subscribe to my <a href="https://twitter.com/atimca">twitter account</a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a35d0f23b04b60c49952ac388fcbfba6/href">https://medium.com/media/a35d0f23b04b60c49952ac388fcbfba6/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e1d593bfb11" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to cook reactive programming. Part 2: Side effects.]]></title>
            <link>https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/2ce50f6fd966</guid>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[rxswift]]></category>
            <category><![CDATA[unidirectional-data-flow]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Wed, 03 Jun 2020 09:15:33 GMT</pubDate>
            <atom:updated>2020-09-04T10:09:35.228Z</atom:updated>
            <content:encoded><![CDATA[<p>Despite the number, this is the third article about reactive programming. Today we are going to talk about how to handle side effects while using unidirectional approaches.</p><blockquote><em>Before we start, I’d firstly highly recommend reading at least </em><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7"><em>How to cook reactive programming. Part 1: Unidirectional architectures introduction.</em></a><em>. However, if you’re not familiar with frameworks such as </em><em>RxSwift or </em><em>Combine, or reactive programming in general, I’d suggest reading </em><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef"><em>this article</em></a><em> as well.</em></blockquote><p>Thousands of kudos to <a href="https://medium.com/u/a737a378ae61">Dave Phillips</a>. He really helped with this article!</p><h3>Back to the future</h3><p>I’ve finished all my articles already. And now we can go back to the future 🏎…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xty3wRUdOzgtr-RO2xrJYw.jpeg" /></figure><ol><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7">How to cook reactive programming. Part 1: Unidirectional architectures introduction.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">How to cook reactive programming. Part 2: Side effects.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=friends_link&amp;sk=53e13576063afefd4a533944eee5d183">How to cook reactive programming. Part 3: Modularization.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-4-testing-529bd0404270?source=friends_link&amp;sk=d6a5bba89e00afe8fce18dba5ced814b">How to cook reactive programming. Part 4: Testing.</a></li></ol><h3>Intro</h3><p>Before we will move to the talk about Side Effects I want to introduce you to the main subject of this article.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*oMfcJ4t2sgtgqHeomJEOvg.png" /></figure><p>This is a representation of the simplest State which you actually can find in nearly every application. Let me transform this image into the real code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/49707f361bd3036b8f0ba6b55e6411cc/href">https://medium.com/media/49707f361bd3036b8f0ba6b55e6411cc/href</a></iframe><p>Much better! If you’re familiar with a state machine theory from the computer science class, this picture will be very recognisable to you. This is a simple state machine with 3 states. The Initial state can go to the Loading state. The Loading state to the Loaded state. And the Loaded state can go back to the Loading state. Remember I was talking about Statedata consistency. In this particular case it&#39;s really hard to make the state inconsistent. Each state of the system is represented as an enum case.</p><p>Don’t worry, I’m not going to bother you with any computer science concepts here. It was mostly a representation of the ideal State which could be achieved. In the real world it&#39;s really hard to create only an enum state. In most cases it would be a structure. However, for the purposes of this article we will use this State for the experiments. And now let&#39;s move to the main topic.</p><h3>What are Side Effects?</h3><p>According to <strong>Wikipedia</strong></p><blockquote><em>In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the main effect) to the invoker of the operation. State data updated “outside” of the operation may be maintained “inside” a stateful object or a wider stateful system within which the operation is performed. Example side effects include modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other side-effect functions. In the presence of side effects, a program’s behaviour may depend on history; that is, the order of evaluation matters. Understanding and debugging a function with side effects requires knowledge about the context and its possible histories.</em></blockquote><p>However, here we’re not talking about the strict definition of the side effects. Let’s remember where we ended up the last time.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/31a6c935be40a5eb26dc2254f3c5ad4c/href">https://medium.com/media/31a6c935be40a5eb26dc2254f3c5ad4c/href</a></iframe><p>Generally, nearly all unidirectional architectures look like this. We have a State on which the rest application relies as only one source of truth. A reducer which alongside Event is the only way to mutate or update State. However, there should be something else. We don&#39;t live in a synchronous world, where every update for State can be done only with a synchronous reduce function. Every application needs to go to the network or database, for the new cat images. Every developer moves even hard computations on the background thread. So, how will all of this work with the existing code? The answer is side effects. In our case Side Effects are something asynchronous, which could mutate State and this &quot;something&quot; works on the side of the reducer. Imagine your beloved network service which somehow needs to be connected to the rest of the system. But first let&#39;s talk about why this architecture is called &#39;unidirectional&#39;.</p><p>One remark: Event in different implementations of unidirectional architectures could be called a Mutation or Action or Message, or maybe something different, for our purposes however naming is not so important.</p><h3>Why is the architecture called unidirectional?</h3><p>Unidirectional architecture is also known as one-way data flow. This means that data has one, and only one way to be transferred to other parts of the application. In essence, this means child components are not able to update the data that is coming from the parent component. The main benefit of this approach is that data flows throughout your app in a single direction, giving you better control over it.</p><p>I think it should be quite easy to understand with the State reduce approach from the beginning. We can change or mutate State only with a strict described Event. As a result we&#39;ve got a one-way (unidirectional) data flow. However, what should we do with Side Effects?</p><p>Imagine that for the State we have a service which as a result returns a list of the news titles.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e8b45894d1dcfb2dea0ae18137b8b087/href">https://medium.com/media/e8b45894d1dcfb2dea0ae18137b8b087/href</a></iframe><p>We know that reducer takes Event as an input not a closure... How can we connect this service to the reducer? The answer is quite simple. Let&#39;s have a Side Effect, which will return Event, not just requested data.</p><p>The resulting system will look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e103a320eb351e47394e365d344252b/href">https://medium.com/media/8e103a320eb351e47394e365d344252b/href</a></iframe><p>As you can see for now loadNewsTitles returns an Event, which could mutate the state. Our system works only in a unidirectional way. And there&#39;s an answer to why the architecture is called Unidirectional. After I’d answered one question, I&#39;ve subsequently produced another one. How can we connect Side Effects and the rest of the system? This question actually is the most complicated so far. I&#39;ll try to answer it in the next section.</p><h3>Which types of side effects exist?</h3><p>In nearly every unidirectional architecture you&#39;ll see a collaboration of State and some function for reducing this State according to the input Event. With Side Effects it&#39;s much more complicated. Almost every framework does this in a different way. Let me try to make you familiar with the most popular of them.</p><h3>Middleware</h3><p>Let’s start with the Middleware approach. Middleware provides a third-party extension point between dispatching an Event, and the moment it reaches the reducer. In simple terms Middleware, sits in the middle between you performing or dispatching an Event and mutating your State inside the reducer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/406/1*JoyM7z7IimpIzsr5zji97Q.png" /></figure><p>Let me provide you with a code example, which I found in one well-known framework for Redux implementation for Swift.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f100796ead5ccf79c05826dcea256b8b/href">https://medium.com/media/f100796ead5ccf79c05826dcea256b8b/href</a></iframe><p>As you can see a Middleware could be treated as an asynchronous pre Reducer. It catches all Events, carries out some manipulations over it - in our case, loading news titles -, and performs a new Event for the system if it&#39;s necessary. So, if the Event is loadData, listed Middleware will load news titles and in the closure send another Event to the Store. The next dataLoaded Event will just be ignored by this Middleware. One of the pros of this method is the possibility to chain Middlewares quite easily.</p><p>Also, if you want to read more about this approach, I’d highly recommend taking a look at <a href="http://reswift.github.io/ReSwift/master/getting-started-guide.html">ReSwift framework</a>. This framework is an implementation of a unidirectional architecture, which is called Redux for Swift language. For those, who still refuse reactive frameworks, ReSwift could be a good start, because ReSwift doesn&#39;t use any.</p><h3>Effects</h3><p>The next approach I want to talk about is the Effects approach. The main idea is almost the same as the Middleware, but all actions are going on inside Reducer itself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*sJr5zybQR7W27TUR1l9RFw.png" /></figure><p>In this approach Reducer has a little bit of a different shape, that I showed you before. It has a shape, which you can see below.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5743e172393bed277f621fd68e0198af/href">https://medium.com/media/5743e172393bed277f621fd68e0198af/href</a></iframe><p>Nearly everything should be familiar. State is a type that holds the current state of the application. Event is a type that holds all possible events that cause the state of the application to change. However, there are two new characters: Environment and Effect. Environment is a type that holds all dependencies needed in order to produce Effect(s), such as API clients, analytics clients, random number generators, and so on.</p><p>So, how does it work for our example?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/10844824516cdc1d7361b189de7068e7/href">https://medium.com/media/10844824516cdc1d7361b189de7068e7/href</a></iframe><p>How does this approach work? For every call of Reducer you provide all necessary dependencies via Environment to the Reducer itself, and afterward your Store will perform every workItem from the Effect itself. And then every Effect will return another Event to the Reducer. Unidirectional data flow works with all power here.</p><p>You may ask, but what about the pure Reducer over there? You told us that Reducer is a pure function, and now you put Side Effects directly inside this function. Moreover, we mutate State inside this function, not just creating a new value. So, I can definitely explain that this variation of the Reducer is the most complicated one which we&#39;ve seen so far. It has the Environment inside and it mutates State. However, let&#39;s take a closer look. If we provide one implementation for the loadNewTitles service, our Reducer will perform the same and our State in the end will be the same. Yeah, in the real world, our server can answer with the different replies or different news titles, but it still has the same output - Effect as a return value, with the same network client in it. I hope you&#39;ve got the idea. What about State mutation? Since all real mutations are always going on inside the Store, the main situation around changing State hasn&#39;t changed itself. Moreover, mutating State against creating new values for every reduce saves some performance for us. We don&#39;t need to allocate new memory each time.</p><p>I don’t want to provide a working example of this approach as well. My job is to make you familiar with it and explain the basics. However, I highly recommend taking a look at <a href="https://github.com/pointfreeco/swift-composable-architecture.git">The Composable Architecture TCA</a> from <a href="http://pointfree.co">pointfree.co</a>. In my personal opinion this framework is the most promising for now. It has its own cons such as the minimum iOS 13 version.</p><h3>Query Feedback</h3><p>Let’s move forward or downstairs. In contrast with Middleware or Effect approaches from the previous sections, there&#39;s a Query approach. The Query Feedback approach reactsto new changes from the different side of the Reducer compared to Middleware.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/464/1*IfPym9KSsm0TXx1-ooMxvg.png" /></figure><p>Did you notice? We’ve moved the whole way through Side Effects approaches? Middleware was before Reducer, Effects approach was inside Reducer and now Query Feedback is after reducer. Quite a journey, huh?</p><p>However, how does it work? We need to take a small piece of the State and start to Observe every change of this state. For the previous example it will look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/45595102357e9a7ad0c11e5912daa830/href">https://medium.com/media/45595102357e9a7ad0c11e5912daa830/href</a></iframe><p>In other words, there’s some kind of Observer, which follows every change of this query and performs some actions over it. The optional Void type for my taste is the best representation when you need to understand whether you need to do any work or not.</p><p>I think you’ve likely become bored with non-working examples in this article. So, let’s try at least to implement this one. I’ll use the Combine framework for this implementation. Whoah, this is the third article about reactive programming, and only now I&#39;ll start to use a reactive framework. Also, afterward, I&#39;ll explain why I prefer to use Combine over vanilla Swift. Technically Combine is already vanilla as well, but you&#39;ve got the point.</p><p>Here is a small table of concepts for those who are new in Combine.</p><ul><li><a href="https://developer.apple.com/documentation/combine/publisher"><strong>Publisher</strong> declares that a type can transmit a sequence of values over time.</a></li><li><a href="https://developer.apple.com/documentation/combine/published"><strong>@Published </strong>is a type that publishes a property marked with an attribute</a></li><li><a href="https://developer.apple.com/documentation/combine/future/3362552-sink"><strong>Sink</strong> attaches a subscriber with closure-based behavior to a publisher</a></li><li><a href="https://developer.apple.com/documentation/combine/cancellable"><strong>Cancellable</strong> a protocol indicating that an activity or action supports cancellation.</a></li><li><a href="https://developer.apple.com/documentation/combine/cancellable/3343581-store"><strong>Store</strong> stores this cancellable instance in the specified collection</a></li></ul><p>From now a little bit of tutorial started. Everything that I’ll write below you can copy to your project and play with it afterward.</p><p>Let’s introduce our old characters: State, Reducer, Query and Event:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6200c4d5125b981dbe0180ec862d3c5a/href">https://medium.com/media/6200c4d5125b981dbe0180ec862d3c5a/href</a></iframe><p>Nothing new so far — only a Query which I&#39;ve shown to you recently. Now let&#39;s remove the callback from loadNewsTitles service and rewrite it in Combine fashion.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c2faa6475b1570477ea9266b84ae0b94/href">https://medium.com/media/c2faa6475b1570477ea9266b84ae0b94/href</a></iframe><p>Mostly it’s just a pre-prepared mock with a small delay, which should simulate a real network environment. And now there’s a new character in this play. Let’s call it SideEffects. Obviously it&#39;s not me who invented this name, but let&#39;s imagine it for the bigger narrative of the story.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c53157076e9174f86a79b5db40125034/href">https://medium.com/media/c53157076e9174f86a79b5db40125034/href</a></iframe><p>As far as you can see, SideEffects for the Query Feedback approach is almost the same thing, as Environment for the Effect approach. I prefer to keep it as simple as possible, and most of the time it just converts the output from the services into Event which could be consumed by the Reducer.</p><p>And for now, there’s only one question left- how do we connect SideEffects with the rest of the system? The answer isn’t so complicated, and Combine helps with it very much. Let&#39;s build our boss Store entity in which we&#39;ll connect every piece of our system.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/222889fdd93dbb905654a406776d0f93/href">https://medium.com/media/222889fdd93dbb905654a406776d0f93/href</a></iframe><p>The most interesting part of the code listing above is the start function. As far as you can see, I made our SideEffects react to the change of the piece of the State loadQuery. And for every time when our system will be in the loading State, our SideEffects will go to the network service, download new newsTitles and notify our system that new titles have been downloaded. Do you see it? Everything in the cycle, all data flow works in the one direction.</p><p>Let’s test what I’ve done so far.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b2c67f227acdc70c46ae428592cb9cb/href">https://medium.com/media/5b2c67f227acdc70c46ae428592cb9cb/href</a></iframe><p>And it works, as expected! The system started from initial state then it went to the loading state after the new Event was sent, and ended up in loaded state. If you want to play with it some more, I&#39;ve prepared <a href="https://gist.github.com/c0c48c02088f9ce6543ab6328732b6b4">a gist</a>.</p><p>I know that twoCancelables could look a little bit clumsy here, but I didn&#39;t want to make this example too complicated. There&#39;s <a href="https://github.com/NoTests/RxFeedback.swift">another framework called </a><a href="https://github.com/NoTests/RxFeedback.swift">RxFeedback</a> where all these problems were solved. I think that you&#39;ve already got it, that this framework uses RxSwift from the title, right? However, there&#39;s a constructor of Observable - it&#39;s a Publisher from the Combine - which creates the whole unidirectional system for you.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a66c00470f221fd786daa372086276ff/href">https://medium.com/media/a66c00470f221fd786daa372086276ff/href</a></iframe><p>Typealias Feedback is a SideEffect itself. It takes changes in the State as an input and provides a sequence of Events as output.</p><p>In my personal opinion, this approach is the most hardcore one. As an advantage, you can take that your State always reflects what&#39;s going on in the system. The previous two rely on Event while doing any Side Effects, but this one only relies on the State itself. If you want to read a little bit more about the pros and cons of the Effect and Query approaches, you could read my <a href="https://github.com/pointfreeco/episode-code-samples/issues/53">discussion with TCA creators</a>.</p><h3>Why do we need a reactive framework for this?</h3><p>There are a lot of people who don’t want to accept any reactive frameworks and don’t understand why they are even needed. If you’re still reading this, and you are one of them, crash the like or clap button. This section is mostly for those who’ve been intrigued by the Unidirectional approach, but for some reason don&#39;t want to use reactive frameworks. Firstly I want to say, that you&#39;ve already seen in my articles, that there’s nothing to be scared by inreactive frameworks and reactive programming in general. Most of you already use some techniques from it. I can say that it&#39;s much more handy to handle your data like a sequence or array than work with enormous closures. Use some functions, like filter, mapor reduce etc. It really makes your code more clean and understandable. It&#39;s really hard to make a lot of mistakes from the start if you don&#39;t know how to cook it 😉. That&#39;s why I write these articles for you.</p><p>Let me show you another advantage in a reactive framework usage. Do you remember that I relied on <a href="http://reswift.github.io/ReSwift/master/getting-started-guide.html">ReSwift framework</a> while showing a Middleware approach? This is a great framework, which was written by brilliant people. However, if you try to understand how it works under the hood, or even try to work with it you will end up with structures like this.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/addcf76522f38e2fa8f8479806c63a0c/href">https://medium.com/media/addcf76522f38e2fa8f8479806c63a0c/href</a></iframe><p>There are three closures inside each other! Moreover, I’ve used a helper to make it more simple. Of course, you could separate all of this somehow and avoid all the callback hell. However, if you take a look at my previous Query example you will see how everything was simple and straightforward. I wanted to say elegant as well, but for elegance it has to be refactored a little bit 😑. If you want to have a closer look at ReSwift in action, I did a small <a href="https://github.com/Atimca/Currencies">test project</a> some time ago.</p><h3>Outro</h3><p>There’s no silver bullet on how to handle Side Effects. You can decide for yourself what to use. However, I think that most of you and myself will choose some pre-prepared solution like RxFeedback or TCA or ReSwift or something else.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/1*LuhcR-4v2iy6MOqzNgRw-A.gif" /></figure><p>Finally, I have a chance to show you this gif. I took it from the ReSwift repo. This gif in full form represents the whole power of Unidirectional approaches. Technically you can store the whole history of State mutations and replay them at any moment you want.</p><p>So far, you’ve become familiar with how to work and even how to build your own reactive framework and unidirectional architecture. However, we live in a world where applications are not one button flashlight apps anymore. We have teams of more than ten people. And if you noticed, the main idea of Unidirectional architecture is to keep all data inside one struct. I bet, if you start with this approach you will end up with a huge State and Reducer if not at the end of the week, then by at the end of the month. You may wonder how it&#39;s possible to separate the Unidirectional approach on different modules when the main idea is to keep everything in one place. What to do in this situation and what are the ways of app modularization I will show you in the next article. Let&#39;s keep in touch!</p><p>If you don’t want to lose any new articles subscribe to my <a href="https://twitter.com/atimca">twitter account</a>))</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a35d0f23b04b60c49952ac388fcbfba6/href">https://medium.com/media/a35d0f23b04b60c49952ac388fcbfba6/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2ce50f6fd966" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to cook reactive programming. Part 1: Unidirectional architectures introduction.]]></title>
            <link>https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/5c73f3f7793d</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[reactive-programming]]></category>
            <category><![CDATA[unidirectional-data-flow]]></category>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[rxswift]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Thu, 14 May 2020 10:17:01 GMT</pubDate>
            <atom:updated>2020-09-04T09:42:45.080Z</atom:updated>
            <content:encoded><![CDATA[<p>I wrote an article <a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a> where in a simple way I described how to build your own Reactive Framework, and helped you to understand that no-one should be scared by the reactive approach. The previous article could now be named <strong>How to cook reactive programming. Part 0.</strong>, since this is a continuation. I would recommend reading the previous article if you are not familiar with the reactive programming concepts.</p><h3>Back to the future</h3><p>I’ve finished all my articles already. And now we can go back to the future 🏎…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lSZj7xZ4XQse2GkbtRjkNA.jpeg" /></figure><ol><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7">How to cook reactive programming. Part 1: Unidirectional architectures introduction.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">How to cook reactive programming. Part 2: Side effects.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=friends_link&amp;sk=53e13576063afefd4a533944eee5d183">How to cook reactive programming. Part 3: Modularization.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-4-testing-529bd0404270?source=friends_link&amp;sk=d6a5bba89e00afe8fce18dba5ced814b">How to cook reactive programming. Part 4: Testing.</a></li></ol><h3>Back to the article</h3><blockquote>This article can be read not just by iOS developers. I used only the basic concepts of Swift. You will understand it if you have knowledge of any modern programming language.</blockquote><p>Today we are going to talk more about the practical aspects of reactive programming. I’ve already mentioned it’s too easy to make a lot of errors with this approach after you’ve begun using any reactive framework, so I want to show you how to avoid any problems.</p><p>Thousands of kudos to <a href="https://medium.com/u/a737a378ae61">Dave Phillips</a>. He really helped with this article!</p><h3>The problems</h3><p>To start, I want to describe some common problems with reactive programming and with the most common approaches nowadays.</p><p>Let’s begin with reactive problems. The most common fear about reactive programming is that when you start to use it, you can reach a point where there are hundreds of uncontrolled data sequences in your code base and you as a developer no longer have any power over it.</p><h3>Unpredicted mutations</h3><p>The first and the biggest problem of what a reactive way could do for you is unpredicted mutations. Let me make an example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/beb955201724ce74965d73e32fb58855/href">https://medium.com/media/beb955201724ce74965d73e32fb58855/href</a></iframe><p>For the simplest of reasons, I’ve replaced the reactive sequence with an array. The example itself is an oversimplified way of how you can make a mistake, doing any reactive things. Nobody can predict where and when you changed data, we have so many ways to do it and there are so many of them hidden under reactive framework implementations.</p><p>However, how can we handle this, how can we protect ourselves? First of all, we should move from reference types to the value ones.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/36a4d65a5dd37d6412e62fb5756d15ff/href">https://medium.com/media/36a4d65a5dd37d6412e62fb5756d15ff/href</a></iframe><p>Just with this simple change, I protect my array from an unpredicted mutation. As far as you know structs are value types, and they copy themselves all the time (there&#39;s a copy on write mechanism, but you&#39;ve got the idea).</p><p>However, let’s wait for a moment, and let’s try to move one step forward and try to make one radical movement. Let’s make variable val a constant.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4bca3b5e6d8e8a5950608dd3033851af/href">https://medium.com/media/4bca3b5e6d8e8a5950608dd3033851af/href</a></iframe><p>Yes! That’s the protection I’m talking about. Now we don’t have any chance to mutate our data on the way through the data Sequence.</p><p>What are we going to do with all this? A mobile application is not a painting, it is not static, we need to mutate data to react on user behavior or any other external changes such as network data or timers. An app is a living thing. So we have two problems to solve. We need to keep our value entities in the floating sequences, and we need somehow to mutate data to show changes to the user. That sounds like a challenge but wait for it, let&#39;s talk a little bit about modern architectures. This is an article about architecture after all.</p><h3>MV family</h3><p>The problem above is not only about the reactive approach. You can face it everywhere, no matter the paradigm you use. Let’s take a small step back and talk a little bit about modern app architectures.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PAlqHyheq3P4xnOM.png" /></figure><p>I can bet you’ve seen this guy before. Actually, in my personal opinion, most modern architectures look like this. They could be called the MVsomething family. MVP, VIPER, MVVM, the same but different. I don’t want to go deep inside to try to understand what all the differences are between them, you already know this. Let’s talk about common things. They are all small pieces, separated by screens, single views, or just a piece of business logic. Whoever is familiar with the topic will understand in advance what I’m getting at. With all these architectures it’s easy to bump into an inconsistent state of the app. Let me provide an example — imagine you have a home page in your app, and this home page depends on the logged-in user. You have a quite complicated app already with a possibility to sign in or sign out the user from different parts of the app. Already understand what I’m talking about? Imagine you decided to sign out from one part of the app and your home page should react on this change. Let me just show a gif as an example.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/0*H6FBy3bEGWhIdZS7.gif" /></figure><p>You can use some sort of user service, which will notify all subscribers to this service about any changes to a user. This approach has two problems. First problem: I think that services should be stateless; they shouldn’t hold any information, just perform actions. Second problem: imagine that we have more than one situation where we need to share information between several modules. In this case, we’d have a bunch of dirty services and we’d simply return to the starting point with a lot of floating mutations.</p><p>What to do in this situation? I’ll give you an answer shortly.</p><h3>One ring to rule them all</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/843/0*Hu9O5FM7FTovZGWA.jpg" /></figure><p>As I said above, an application is a living, changing system. For now, we have two problems, which should be solved. The first problem is that we need to keep data in the sequences immutable. The second one is that we need to stop producing sources of truth inside the codebase. How can we achieve this? What if I say, we can have a single source of truth for the entire application? It sounds ridiculous, but let’s try to build this kind of system.</p><p>As I said before only one state object is needed. Let’s create it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/780fed035a343d8aab0d49ec7e7a7a5b/href">https://medium.com/media/780fed035a343d8aab0d49ec7e7a7a5b/href</a></iframe><p>Quite easy, yes? The system should be as simple as possible. There is only one source of truth, and every other participant in the codebase observes all changes within this source. Let&#39;s try to implement this as well.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5619a4ad75f5f0fc9a65828e6d556c3c/href">https://medium.com/media/5619a4ad75f5f0fc9a65828e6d556c3c/href</a></iframe><p>What have I done? There’s a state object which holds data from the whole application. Store is an entity, which holds everything. Two Observer objects, which subscribed on every state change. And mostly that&#39;s it. By the way, do you remember the user example before? The listed solution perfectly handles this situation. However, there&#39;s one big problem. The state was changed directly via store.state.value = 10. This approach could lead to the same problems, which I&#39;m trying to remove right now. I&#39;m going to fix it with a solid сoncept of Event.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6394c2b0fcaaa733c7f06174fee462d4/href">https://medium.com/media/6394c2b0fcaaa733c7f06174fee462d4/href</a></iframe><p>One remark. I know that observers are held with a strong reference in Store, and it should be avoided in the real project. You can find out how to achieve this in the previous article. Here I want to save some time. Back to the Event.</p><p>For now, no-one can mutate the state in an unpredictable way. The way of mutation is clear, structured and encapsulated under the Event concept. If you have noticed, for now, you cannot reach State just like a property of the store. I&#39;ve done this on purpose, because reactive programming is about reaction on system changes, not taking data whenever you want, as I described in my previous article.</p><p>Wait one moment… Take a look at this signature of standard reduce function in Swift:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a653a9382f0a9ce439d2f1f14e250941/href">https://medium.com/media/a653a9382f0a9ce439d2f1f14e250941/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/410/0*8yeAKSGlyzGImmGd.png" /></figure><p>It looks almost the same as our accept function. There&#39;s an intialResult as the previous State, and some function to mutate State according to the Event. Let&#39;s refactor existing code a little bit.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2f476bf5a9a610035575d438a5312515/href">https://medium.com/media/2f476bf5a9a610035575d438a5312515/href</a></iframe><p>That’s much better. However, take a look at this reduce function... It looks like it&#39;s completely independent of the Store and mostly any other objects. Why is this so? A reduce function is a pure function - it has its input parameters and one output. It also means that no matter what is going on in Store itself, reduce will work in the same way. So, maybe we should extract it from the store and make it a high order function? It sounds like a great idea, doesn&#39;t it? Again, let&#39;s wait one moment. Seems like reduce is closer to State than to Store, so let&#39;s put it under the State namespace.</p><p>Here’s the final solution for our DIY architecture.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb3d2d9e33aa716b2f5211aa729254cd/href">https://medium.com/media/eb3d2d9e33aa716b2f5211aa729254cd/href</a></iframe><p>As a result, we’ve got a simple unidirectional architecture. However, there are so many questions remaining. We don’t live in the synchronous world, where it’s possible to put every mutation through the reduce function synchronously. Indeed internet requests or timers couldn&#39;t be added like this to the approach that I&#39;ve introduced before. To resolve this problem, we&#39;ll use the SideEffects approach, but I&#39;ll write about that in my next article. And I almost forgot about one important thing. Why is the architecture called unidirectional? To provide a clear explanation, I&#39;ll need to make you familiar with the SideEffects as well. So, stay tuned!</p><p>PS: This is already the second article about reactive programming, and I haven’t used any framework such as RxSwift or Combine... It actually means that most of you have already been using reactive approaches, without even noticing it. If you don&#39;t want to lose any new articles subscribe to my <a href="https://twitter.com/atimca">twitter account</a>))</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2cfa0f80e2bcb69f60438eeb6a40eb70/href">https://medium.com/media/2cfa0f80e2bcb69f60438eeb6a40eb70/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5c73f3f7793d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is Reactive Programming?]]></title>
            <link>https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=rss-34717dc164a5------2</link>
            <guid isPermaLink="false">https://medium.com/p/43e60cc4c0f</guid>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[reactive-programming]]></category>
            <category><![CDATA[rxswift]]></category>
            <category><![CDATA[design-patterns]]></category>
            <dc:creator><![CDATA[Maxim Smirnov]]></dc:creator>
            <pubDate>Tue, 14 Apr 2020 18:36:37 GMT</pubDate>
            <atom:updated>2021-04-15T14:48:19.547Z</atom:updated>
            <content:encoded><![CDATA[<h3>What is Reactive Programming? iOS Edition</h3><p>So, what is R̶x̶S̶w̶i̶f̶t̶ ̶C̶o̶m̶b̶i̶n̶e̶ Reactive programming?</p><p>According to Wikipedia:</p><blockquote>Reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm, it is possible to express static (e.g., arrays) or dynamic (e.g., event emitters) data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.</blockquote><p>Excuse me, WHAT?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IT2KsoUPvfFEFvuwNnUsdQ.png" /></figure><p>Let’s start from the beginning.</p><p>Reactive programming is an idea from the late 90s that inspired Erik Meijer, a computer scientist at Microsoft, to design and develop the Microsoft Rx library, but what is it exactly?</p><p>I don’t want to provide one definition of what reactive programming is. I would use the same complicated description as Wikipedia. I think it’s better to compare imperative and reactive approaches.</p><p>With an imperative approach, a developer can expect that the code instructions will be executed incrementally, one by one, one at a time, in order as you have written them.</p><p>The reactive approach is not just a way to handle asynchronous code; it’s a way to stop thinking about threads, and start to think about sequences. It allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. You think about how your system reacts to the new information. In simple words, our system is always ready to handle new information, and technically the order of the calls is not a concern.</p><p>I assume that most of the readers of this article came from iOS development. So let me make an analogy. Reactive programming is Notification center on steroids, but don’t worry, a counterweight of the reactive frameworks is that they are more sequential and understandable. Moreover in iOS development, it’s hard to do things in one way, because Apple gave us several different approaches like delegates, selectors, GCD and etc. The reactive paradigm could help solve these problems in one fashion.</p><p>It sounds quite simple. Let’s take a look ar a couple of functions in one class implementation of one of the most popular frameworks RxSwift:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc2d9da116be0d34036216f830f61834/href">https://medium.com/media/cc2d9da116be0d34036216f830f61834/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/445/1*ldBNAZBAf42ePMTXYn4tng.png" /></figure><p>This even partial example does not look easy at all… As we can see the implementation of RxSwift is not so simple. But let me explain myself. RxSwift is an advanced, highly optimized framework with wide functionality. To understand the principles of the reactive world, this framework doesn&#39;t fit. So, what are we going to do? We are going to write our own reactive solution from scratch. To do this, firstly we need to understand which parts this library consists of.</p><h3>The tale of two friends</h3><p>Let me answer again the question: What is reactive programming? Reactive programming is a friendship of two design patterns: Iterator and Observer. Let&#39;s have a quick reminder of how these patterns work.</p><p>Iterator is a behavioral design pattern that lets you traverse elements of a collection without exposing its underlying representation (list, stack, tree, etc.). You can read more at this <a href="https://refactoring.guru/design-patterns/iterator">link</a>.</p><p>Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they&#39;re observing. You can read more at this <a href="https://refactoring.guru/design-patterns/observer">link</a>.</p><p>How do these two friends work together? In simple terms, you use the Observer pattern to be subscribed for new events, and use the Iterator pattern to treat streams like sequences.</p><p><strong>Iterator</strong></p><p>Let’s start from the beginning. From the Iterator pattern.</p><p>Here’s a simple sequence of integers:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ef56e7765afc292b09d87fd810628067/href">https://medium.com/media/ef56e7765afc292b09d87fd810628067/href</a></iframe><p>And I want to iterate through it. Easy enough:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/959ed59e58669d9d0441a3b8c6efed9b/href">https://medium.com/media/959ed59e58669d9d0441a3b8c6efed9b/href</a></iframe><p>However, I think that everybody would say this way of iteration via sequence is a little bit weird. Let’s do this the proper way:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9f8cf9f2837a82d6d2c0e28775041947/href">https://medium.com/media/9f8cf9f2837a82d6d2c0e28775041947/href</a></iframe><p>For now, it looks more natural, or at least I hope so. I used the forEach method on purpose. forEach has this signature</p><p>func forEach(_ body: (Element) -&gt; Void)</p><p>It&#39;s a function which takes a function(handler) as an argument and performs this handler over the sequence. Let&#39;s try to build forEach by ourselves.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a8abb24b67f6c6cceeff899f66c4263e/href">https://medium.com/media/a8abb24b67f6c6cceeff899f66c4263e/href</a></iframe><p>With forEach semantics it&#39;s possible to write this elegant code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/04f0dc1955efccb847828a5eb4085ea2/href">https://medium.com/media/04f0dc1955efccb847828a5eb4085ea2/href</a></iframe><p>As I said before, that reactive programming is above all thread problems. Let’s add to our custom forEach some thread abstraction.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/edccbce8e8cf8299c39d33be6f2f6a8a/href">https://medium.com/media/edccbce8e8cf8299c39d33be6f2f6a8a/href</a></iframe><p><strong>Observer</strong></p><p>I went so far and did some strange custom forEach for Array. What is this for? We&#39;ll know about this a little bit later, but now let&#39;s move to Observer.</p><p>There are many terms used to describe this model of asynchronous programming and design. This article will use the following terms: an Observer and Observable. An Observer subscribes to an Observable, and the Observable emits items or sends notifications to its observers by calling the observers&#39; methods.</p><p>In other words: Observable is a stream with data itself, and Observer is a consumer of this stream.</p><p>Let’s start with the Observer. As I said, it&#39;s a consumer of a data stream, which can do something around this data. Let me translate, it&#39;s a class with a function inside, which calls when new data arrives. Let&#39;s implement this class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cca94718d6a454e57900a6c824a873b8/href">https://medium.com/media/cca94718d6a454e57900a6c824a873b8/href</a></iframe><p>And now let’s move to Observable. Observable it&#39;s data itself. Let&#39;s make it simple for the first iteration.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf8136e961127278e966fbd0c5c7cc33/href">https://medium.com/media/cf8136e961127278e966fbd0c5c7cc33/href</a></iframe><p>The most interesting part is that Observable should allow to subscribe to a consumer of this data. And via changing this data in Observable, Observer needs to know about these changes.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e98daa8025613ec08424742b39989f8/href">https://medium.com/media/8e98daa8025613ec08424742b39989f8/href</a></iframe><p>Actually we just build our Observer pattern. So, let&#39;s try this out.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/97b2434c838e6dc3769b21ee9253a45e/href">https://medium.com/media/97b2434c838e6dc3769b21ee9253a45e/href</a></iframe><p>And it works! But hold on for a second — let’s add some modifications before we go further.</p><p>Maybe you’ve already mentioned that our Observable stores all input Observers via subscription, which is not so great. Let&#39;s make this dependency weak. However, Swift doesn&#39;t support weak arrays for now and maybe forever, that&#39;s why we need to handle this situation otherwise. Let&#39;s implement the class wrapper with a weak reference in it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9a0a33d1f0a137c3a2962191ed203783/href">https://medium.com/media/9a0a33d1f0a137c3a2962191ed203783/href</a></iframe><p>As a result, you can see a generic object, which could hold other objects weakly. Now let’s make some improvements to Observable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c5204433a1774f1a2bbe4f05b00d1144/href">https://medium.com/media/c5204433a1774f1a2bbe4f05b00d1144/href</a></iframe><p>For now Observers not held by Observable. Let&#39;s try this out and create two observers.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8d5f22158c5337329867412860999deb/href">https://medium.com/media/8d5f22158c5337329867412860999deb/href</a></iframe><p>As you can see, the second Observer was destroyed after 2, which proves the workability of the code. However, I think creating an Observer object by hand all the time could be annoying, so let&#39;s improve Observable to consume a closure, not an object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a4342f33c6f4977197ca687804c131e2/href">https://medium.com/media/a4342f33c6f4977197ca687804c131e2/href</a></iframe><p>For my taste usage is more clear now, however it’s possible to use both subscribe functions.</p><p>For now, our tiny reactive framework looks finished, but not exactly. Let’s do some asynchronous stress tests for the Observable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/186642d78245fdeb4cc32d36600b0a8d/href">https://medium.com/media/186642d78245fdeb4cc32d36600b0a8d/href</a></iframe><p>In this case, we should receive numbers from 1 to 9 in random order, because changes run in the different asynchronous queues. For my case, it was like this</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/53c86318cbfd2b7d8f9eb808caf8ae71/href">https://medium.com/media/53c86318cbfd2b7d8f9eb808caf8ae71/href</a></iframe><p>As you can see, it’s not the expected result. A race condition happened and it should be fixed. The solution is easy — let’s add some thread synchronization. There are several ways to achieve this, but I’ll use a method with a dispatch barrier. Here’s the solution.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c57be4f10e9092db5515f503e168426f/href">https://medium.com/media/c57be4f10e9092db5515f503e168426f/href</a></iframe><p>The same test as before gave me this result:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/16ce3d4c6e8c9777fe4ef6726e9d5ae7/href">https://medium.com/media/16ce3d4c6e8c9777fe4ef6726e9d5ae7/href</a></iframe><p>This time it’s even in the right order, but be aware that it’s not guaranteed. Now our reactive framework has thread synchronization.</p><p>Let’s move further and there’s another difference between a vanilla Observer pattern and most of the reactive frameworks. Usually, as an Element from Observable, you manipulate not just an Element, but some kind of Event enumeration, which looks like this.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0441086176364abf5294d68de91f0800/href">https://medium.com/media/0441086176364abf5294d68de91f0800/href</a></iframe><p>It’s a handy solution, because you can handle situations when your sequence completed or received an error. I don’t want to spend time adopting this practice right now, I think it doesn’t matter for concept understanding.</p><p><strong>Let’s compose </strong><strong>Observer and </strong><strong>Iterator</strong></p><p>One of the killer features for reactive programming is the possibility to treat your Observable sequence as a Sequence I think everybody knows these handy functions like map, flatMap, reduce, and so on. As an example, let&#39;s try to add to our Observable the map function. But firstly let&#39;s remember how it works with a simple array.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d202ded1c169d3870895e4b040824e0/href">https://medium.com/media/7d202ded1c169d3870895e4b040824e0/href</a></iframe><p>This case is a primitive adding 1 to every element. Can we do the same with an Observable? Sure we can. Let&#39;s add a map function to our Observable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b036d3c1b96b7336be2cdd921385430/href">https://medium.com/media/8b036d3c1b96b7336be2cdd921385430/href</a></iframe><p>Yeah, you can mention that I’ve cheated a little bit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/180/1*jecwLqic_4dbJlk7Lc4x9A.png" /></figure><p>True map function would have structure with a generic like this:</p><pre>func map&lt;T&gt;(_ transform: <a href="http://twitter.com/escaping">@escaping</a> (Element) -&gt; T) -&gt; Observable&lt;T&gt;</pre><p>However, for the sake of simplicity in this article I just added this:</p><pre>func map(_ transform: <a href="http://twitter.com/escaping">@escaping</a> (Element) -&gt; Element) -&gt; Observable&lt;Element&gt;</pre><p>I hope you could forgive me and understand the point.</p><p>Actually, we’re done for now with our own reactive framework, congratulations to everybody who followed until the end. It’s super simplified but it works. Gist with the last iteration of this article you can find <a href="https://gist.github.com/Atimca/51c83f4c9161fc36bed340b02e605d09">here</a>.</p><p>I hope at least for now, reactive programming doesn’t look scary anymore. However, I hear all the time from people, that reactive way could lead us t an enormous number of sequences flying around the project and it’s very easy to shoot yourself in the foot with this approach. I won’t fight against this, and you can easily Google a bad style of doing reactive. I don’t want to leave you with a cliffhanger, but I hope to show you a way, how to treat a reactive approach in the next chapters.</p><h3>Where to go after</h3><ul><li><a href="http://reactivex.io">http://reactivex.io</a></li><li><a href="https://github.com/ReactiveX/RxSwift">https://github.com/ReactiveX/RxSwift</a></li><li><a href="https://refactoring.guru/">https://refactoring.guru/</a></li></ul><h3>Back to the future</h3><p>I’ve finished all my articles already. And now we can go back to the future 🏎…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QcHeH5UmfAExDguQS9RM3g.jpeg" /></figure><ol><li><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f?source=friends_link&amp;sk=4ab8aa82f6e669bad59be42cba67e0ef">What is Reactive Programming? iOS Edition</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-1-unidirectional-architectures-introduction-5c73f3f7793d?source=friends_link&amp;sk=56793e72690bb9703560cfc686d29aa7">How to cook reactive programming. Part 1: Unidirectional architectures introduction.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-2-side-effects-2ce50f6fd966?sk=fd5ab407dd4bd71076944e8fb08c709f">How to cook reactive programming. Part 2: Side effects.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-3-modularization-2e1d593bfb11?source=friends_link&amp;sk=53e13576063afefd4a533944eee5d183">How to cook reactive programming. Part 3: Modularization.</a></li><li><a href="https://medium.com/@atimca/how-to-cook-reactive-programming-part-4-testing-529bd0404270?source=friends_link&amp;sk=d6a5bba89e00afe8fce18dba5ced814b">How to cook reactive programming. Part 4: Testing.</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=43e60cc4c0f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/atimca/what-is-reactive-programming-43e60cc4c0f">What is Reactive Programming?</a> was originally published in <a href="https://medium.com/atimca">atimca</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>