<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The Coded Self</title>
    <link>https://www.thecodedself.com</link>
    
      
        <item>
          <title>Perfect is the Enemy of the Good</title>
          <description>&lt;h3 style=&quot;margin-top: 0px; color: #777777;&quot;&gt;
&lt;em&gt;How the Wrong Architecture Can Cripple Development&lt;/em&gt;
&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;A couple of years ago, I was working on a side project with a few friends. We thought that it would be the next big thing. We put our collective best efforts into it; I worked long, hard hours fleshing out the scaffolding of the perfect architecture. Little did I know that my effort would doom the project to join the abyss of failed projects as quickly as it had begun.&lt;/p&gt;

&lt;h2 id=&quot;we-had-the-best-tools&quot;&gt;We had the best tools&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/PerfectEnemyGood/toolbox.png&quot; alt=&quot;All the best iOS Swift tools&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Since this was &lt;em&gt;The Next Big Thing&lt;/em&gt;™, we used everything at our disposal.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;RxSwift for reactive programming&lt;/li&gt;
  &lt;li&gt;VIPER for our architecture pattern&lt;/li&gt;
  &lt;li&gt;Swinject for dependency injection&lt;/li&gt;
  &lt;li&gt;Cuckoo for mocking&lt;/li&gt;
  &lt;li&gt;Flow Operations for managing navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;Flow Operations&lt;/strong&gt; were a particularly interesting concept, inspired by the &lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2015/226/&quot;&gt;Advanced NSOperations&lt;/a&gt; session from WWDC 2015. We used Flow Operations to manage navigation in the app. For instance, if you wanted to register a new user, you’d invoke a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegisterFlowOperation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A FlowOperation was a subclass of Operation:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FlowOperation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Operation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;https://developer.apple.com/documentation/foundation/operation&quot;&gt;Operation&lt;/a&gt; class represents the code and data for a task of your choosing. It also handles concurrency and dependencies. So, our Flow Operations represented the task of flowing from one screen to another in an app.&lt;/p&gt;

&lt;p&gt;Operations can be dependent on each other - for instance, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EditProfileFlowOperation&lt;/code&gt; is dependent on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SignInFlowOperation&lt;/code&gt;. If you’ve already signed in, you can edit your profile, but if you haven’t, then you’ll be directed to sign in if you invoke the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EditProfileFlowOperation&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;how-does-it-work&quot;&gt;How does it work?&lt;/h2&gt;

&lt;p&gt;There was a lot of hidden complexity in the Flow Operation system, and some trickiness that you wouldn’t notice until you started using it. I’ll briefly go over some of the code.&lt;/p&gt;

&lt;p&gt;You could sell products in this app we were building. This is how you’d start the Sell Flow:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startSellFlow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;navController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;flow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SellFlowOperation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;navigationController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;navController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;flow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;beginFlow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;flow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;waitUntilFinished&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You create the flow operation, call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beginFlow&lt;/code&gt; to navigate to the first screen, and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;waitUntilFinished&lt;/code&gt; to prevent other flows from executing until this one is done.&lt;/p&gt;

&lt;p&gt;But, don’t forget to put it on a background queue, or the app will hang. Also, don’t forget to call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;waitUntilFinished&lt;/code&gt;, or nothing interesting will happen at all. If another flow was already executing, yours wouldn’t run until that one finished. I shudder when I think back on the hours of debugging issues like this. 💀&lt;/p&gt;

&lt;p&gt;A flow can have one or more ViewControllers to display in succession. How? With a bunch of complicated RxSwift code, of course.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;present&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;viewControllers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UIViewController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
             &lt;span class=&quot;nv&quot;&gt;finishWhenDone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;viewControllers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;MainScheduler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;viewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pushViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finishWhenDone&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addDisposableTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disposeBag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It subscribes to an RxSwift Observable of UIViewControllers that come from the Presenter portion of the VIPER architecture. When a new ViewController is received from the FlowAction, it’s pushed onto the navigation stack. When there are no more ViewControllers, the FlowAction finishes (if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finishWhenDone&lt;/code&gt; is true).&lt;/p&gt;

&lt;p&gt;A Router object ➡️  invokes the Flow Operation ➡️  which gets View Controllers from a Presenter ➡️  and then pushes them onto the navigation stack.&lt;/p&gt;

&lt;h2 id=&quot;technically&quot;&gt;Technically…&lt;/h2&gt;

&lt;p&gt;It’s a great system. It’s a complex, well-thought out architecture. Dependencies are managed elegantly and each part of the system has its own single responsibility.&lt;/p&gt;

&lt;p&gt;Sounds good, right?&lt;/p&gt;

&lt;h2 id=&quot;in-practice&quot;&gt;In practice…&lt;/h2&gt;

&lt;p&gt;It’s a mess. The architecture is extremely hard to use. You need to remember to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Invoke the FlowOperation on the background thread, or you’ll cause a deadlock.&lt;/li&gt;
  &lt;li&gt;Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beginFlow&lt;/code&gt; to start the flow, or nothing will happen.&lt;/li&gt;
  &lt;li&gt;Supply ViewControllers from a Presenter or no new screens will display.&lt;/li&gt;
  &lt;li&gt;Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finish&lt;/code&gt; when you’re done to allow the next flow to start.&lt;/li&gt;
  &lt;li&gt;Don’t create dependency cycles between flows or the app will crash.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Complex architectures create complex problems. Building the right architecture for the right app is extremely important. I’m not advocating for spaghetti code. But when you build unnecessary complexity into an architecture like the one I just described, you’re asking for trouble.&lt;/p&gt;

&lt;p&gt;Developers follow the &lt;strong&gt;path of least resistance&lt;/strong&gt;. A hard to use architecture causes a lot of resistance. When no one can figure out how to put a simple ViewController on the screen, they’ll just opt for MVC instead. If you want your team using something other than Massive View Controllers, you need to provide something that’s easy to use, or it won’t be used at all.&lt;/p&gt;

&lt;p&gt;With a hard-to-use system like the Flow Operations, it’s probably better that they follow the path of least resistance and default to MVC anyways. A system with so many ‘gotchas’ makes it extremely easy to write buggy code. &lt;em&gt;Remember the background thread. Remember to avoid dependency cycles.&lt;/em&gt; The more tricky bits you need to remember, the more likely you are to create bugs and spend more time in debugging than building actual features.&lt;/p&gt;

&lt;h1 id=&quot;a-better-approach&quot;&gt;A better approach&lt;/h1&gt;

&lt;p&gt;What could have changed in the Flow Operation architecture that might have led the project to better success?&lt;/p&gt;

&lt;h3 id=&quot;easier&quot;&gt;Easier&lt;/h3&gt;

&lt;p&gt;Your architecture shouldn’t make life harder. If you want things to be hard, program in assembly. I’d much rather build my apps in a way that’s easy to build now, and easy to maintain later.&lt;/p&gt;

&lt;h3 id=&quot;enabler&quot;&gt;Enabler&lt;/h3&gt;

&lt;p&gt;The structure you have in place is not meant to be a barrier that keeps you from moving forward. Following VIPER or MVVM provides you with some scaffolding, but building something new shouldn’t be a complicated process that’s prone to errors. These architectural patterns are there to make development faster, in the long run.&lt;/p&gt;

&lt;p&gt;When you have to keep a list of tricky problems in your head just to push a new ViewController onto the screen, then something’s gone wrong.&lt;/p&gt;

&lt;h3 id=&quot;dont-make-me-think&quot;&gt;Don’t make me think&lt;/h3&gt;

&lt;p&gt;How easy is the system to understand? How easy was it to write? Will you be able to comprehend things 6 months from now? What about a new developer on the team: will they be able to ramp up without too many headaches in the process?&lt;/p&gt;

&lt;p&gt;This is why I’ve fallen out of love with frameworks like RxSwift. It makes code hard to understand, and harder for team members that are less versed in the library. I love the benefits of reactive programming, but I’d rather take a simpler approach such as using &lt;a href=&quot;https://medium.com/the-andela-way/property-observers-didset-and-willset-in-swift-4-c3730f26b1e9&quot;&gt;property observers&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;getting-there&quot;&gt;Getting there&lt;/h1&gt;

&lt;p&gt;There are a few things that I like to keep in mind when building an architecture. This works for scaffolding a project, building a class interface, or choosing third-party frameworks.&lt;/p&gt;

&lt;h3 id=&quot;the-right-tool-for-the-job&quot;&gt;The right tool for the job&lt;/h3&gt;

&lt;p&gt;Complexity has its time and its place. Techniques that flourish in a large team of ten or more developers aren’t necessarily the right approach for your side projects. A complicated architecture shouldn’t be the starting point - add in the extra structure when your team grows and your needs evolve.&lt;/p&gt;

&lt;h3 id=&quot;rule-of-three&quot;&gt;Rule of Three&lt;/h3&gt;

&lt;p&gt;Preventing code duplication seems like the #1 rule of clean programming. While removing code duplication is a commendable goal, &lt;strong&gt;don’t do it&lt;/strong&gt; at the cost of creating an incorrect abstraction. When you’re looking at duplicated code, do the two pieces in question share a similar purpose? Or is their similarity merely coincidental?&lt;/p&gt;

&lt;p&gt;Code duplication is bad. Creating leaky and incorrect abstractions is worse. They will mutate your code base into an abstract mess that requires a lexicon to make sense of.&lt;/p&gt;

&lt;h3 id=&quot;yagni&quot;&gt;YAGNI&lt;/h3&gt;

&lt;p&gt;You Ain’t Gonna Need It. For every possible future scenario that you can think of, 90% of them won’t happen. Don’t spend your time preparing for the possibility that a project manager might have a change of heart six months down the line.&lt;/p&gt;

&lt;p&gt;Rather write clean, flexible code that can adapt to change. Write code that’s well tested and easy to change when the time comes. When a change of plans presents itself, you’ll be ready. But if you try and prepare for every possible future outcome? YAGNI.&lt;/p&gt;

&lt;h1 id=&quot;the-result&quot;&gt;The result&lt;/h1&gt;

&lt;p&gt;The unnecessary complication that I introduced to the side project mentioned earlier made development a pain. It was hard to build, and hard to use. The other developers on the project battled against the Flow Operations. RxSwift was a huge learning barrier for those that didn’t know it. And, for a small app and team like ours, VIPER was most likely overkill.&lt;/p&gt;

&lt;p&gt;If, instead, we followed the principles mentioned in this post, we could have built something that was easy to understand. The less you have to think when figuring out how to use it, the better. It should be easy to use. An enabler to your programming, not a barrier.&lt;/p&gt;

&lt;p&gt;The system should be only as complex as it needs to be to solve the problem at hand. If the problem changes, the complexity of the system can change to follow suit.&lt;/p&gt;

&lt;h1 id=&quot;please-share-your-thoughts&quot;&gt;Please share your thoughts&lt;/h1&gt;

&lt;p&gt;Do you have any horror stories from failed projects? Do you have any thoughts to share on this advice, or some of your own? Please leave it in the comments below!&lt;/p&gt;
</description>
          <pubDate>2018-11-13T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Perfect-Is-The-Enemy-Of-The-Good/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Perfect-Is-The-Enemy-Of-The-Good/</guid>
        </item>
      
    
      
        <item>
          <title>UI Testing the Clean Way</title>
          <description>&lt;p&gt;I write software, and sometimes I write bugs. But, when I do, I catch them early with testing.&lt;/p&gt;

&lt;p&gt;I do manual tests before I commit, I write unit tests as I write my code. Lately, I’ve also been getting into writing UI tests.&lt;/p&gt;

&lt;p&gt;One critique of UI testing is how messy and brittle it can be. Building the tests can be complicated. You might spend hours on a test just for a design to change that breaks the test and ruins all your hard work.&lt;/p&gt;

&lt;p&gt;So, I want to tell you about some problems you might face in keeping your UI tests clean and readable, and how we can leverage Swift for this endeavour.&lt;/p&gt;

&lt;p&gt;I’ll walk you through my approach to UI testing with everyone’s favorite example project - a To-Do list app. I know, boring, right? Well, it works perfectly for the examples we’ll be looking at, so…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/UITestingClean/dealwithit.png&quot; alt=&quot;Deal with it&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can download the &lt;a href=&quot;https://github.com/TheCodedSelf/POP-Approach-To-UI-Testing&quot;&gt;example project here&lt;/a&gt;. It’s a simple app that allows us to create, edit, and delete a to-do.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/UITestingClean/walkthru-small.gif&quot; alt=&quot;Walking through the app&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;just-press-record&quot;&gt;Just press record&lt;/h1&gt;

&lt;p&gt;UI testing in Xcode is easy. Click inside the body of an empty UI test, click the Record button, and you’re up and running.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/UITestingClean/PressRecord.png&quot; alt=&quot;Record UI Test Button&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s start off by recording a UI test to add a new to-do.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/UITestingClean/Record.gif&quot; alt=&quot;Recording test&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That was easy! And it sure did create a lot of code. That must be good, right?&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testExample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigationBars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Todo List&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;textField&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;otherElements&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;containing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigationBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;New Todo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;textField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;textField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;datePickersQuery&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datePickers&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;datePickersQuery&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pickerWheels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;October&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/*@START_MENU_TOKEN@*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;press&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/*[[&quot;.tap()&quot;,&quot;.press(forDuration: 0.6);&quot;],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;datePickersQuery&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pickerWheels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/*@START_MENU_TOKEN@*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;press&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/*[[&quot;.tap()&quot;,&quot;.press(forDuration: 0.5);&quot;],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Done&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ll be honest, most of that is unreadable to me. Run the test, and you’ll see it doesn’t work, either. It completely missed the name of the to-do that we typed in, and the interaction with the date pickers doesn’t work either.&lt;/p&gt;

&lt;p&gt;It’s clear that this approach won’t work for a large suite of UI tests. It’s a good learning experience to figure out what XCTest has to offer, but code like that shouldn’t be part of your code base.&lt;/p&gt;

&lt;h1 id=&quot;not-as-easy-as-we-thought&quot;&gt;Not as easy as we thought&lt;/h1&gt;

&lt;p&gt;There are clearly some problems with the recording approach to UI testing.&lt;/p&gt;

&lt;h2 id=&quot;complicated-setup&quot;&gt;Complicated setup&lt;/h2&gt;

&lt;p&gt;Each of your tests will start on the main screen of your app. What if you want to test the editing of a to-do? Your test will start by opening a to-do, tapping the Edit button, and then proceed to the actual meat of the test. What if you need to sign in with a particular username and password? Each of your tests will need to do that, as well.&lt;/p&gt;

&lt;h2 id=&quot;duplicated-code&quot;&gt;Duplicated code&lt;/h2&gt;

&lt;p&gt;There’s no code reuse when recording your tests. You can’t build any meaningful abstractions, or create helper functions that make the code easier to maintain and understand.&lt;/p&gt;

&lt;h2 id=&quot;hard-to-read&quot;&gt;Hard to read&lt;/h2&gt;

&lt;p&gt;With lines like this in your code base:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;textField&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;otherElements&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;containing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigationBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;New Todo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;matching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You won’t be able to figure out what’s going on in your tests a month from now. Enough said.&lt;/p&gt;

&lt;h1 id=&quot;a-better-approach&quot;&gt;A better approach&lt;/h1&gt;
&lt;p&gt;There are many ways to improve the code that we got from recording a test, but since we’re using Swift, why not make use of protocol-oriented programming?&lt;/p&gt;

&lt;p&gt;We’ll attempt to tackle the three problems of setup, reusability, and readability by using three families of protocols.&lt;/p&gt;

&lt;h2 id=&quot;-starting-for-setup&quot;&gt;-Starting for setup&lt;/h2&gt;
&lt;p&gt;Remember the example of tests that start on the Edit screen of our to-do app, or a test that needs the user to be signed in?&lt;/p&gt;

&lt;p&gt;When we need to specify where the test should start, we’ll create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Starting&lt;/code&gt; protocol to carry that setup code. For instance, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EditScreenStarting&lt;/code&gt;. By conforming to this protocol, we declare that a particular test case starts on the Edit screen. Anyone looking at the protocol conformances of the test case knows exactly what screen will be tested.&lt;/p&gt;

&lt;h2 id=&quot;-interacting-for-reusability&quot;&gt;-Interacting for reusability&lt;/h2&gt;

&lt;p&gt;Recording your tests can spit out some complicated code that you’d need to copy-paste everywhere you want to perform the same action.&lt;/p&gt;

&lt;p&gt;If we want to tap on a to-do named &lt;em&gt;Buy Groceries&lt;/em&gt;, we’ll need to do something like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;containing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Buy Groceries&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;firstMatch&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It requires knowledge that the list of to-dos is a table view with cells that contain a label with the title. It’s not that complicated, but if the structure of your app changes and you have this code copy-pasted throughout your test suite, you’re gonna have a bad time.&lt;/p&gt;

&lt;p&gt;Instead, we’ll wrap that into a protocol called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoListInteracting&lt;/code&gt; later on. Any test case that is concerned with manipulating to-do list items will have to make its intention clear by conforming to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoListInteracting&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;-verifying-for-readability&quot;&gt;-Verifying for readability&lt;/h2&gt;

&lt;p&gt;Tapping on the Plus button in the navigation bar should take you to the Add To-Do screen. This is how we can verify that the user is indeed on the Add screen:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;XCTAssert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigationBars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;New Todo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticTexts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Todo Title:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DoneButtonIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It does the job, but it’s not very clear what ‘the job’ is. Rather than seeing that everywhere we want to verify that we’re on the Add screen, we’ll just put it into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddScreenVerifying&lt;/code&gt; protocol instead.&lt;/p&gt;

&lt;p&gt;When we want to verify that we’re on the Add screen, we can just do something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XCTAssert(addScreenIsShowing())&lt;/code&gt;. Any file that wants to test aspects of the Add screen will have to conform to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddScreenVerifying&lt;/code&gt; protocol, making it clear what the test is actually testing.&lt;/p&gt;

&lt;h1 id=&quot;lets-get-started&quot;&gt;Let’s get started!&lt;/h1&gt;

&lt;p&gt;We’ll dive straight in and test the deleting of a to-do. Here’s the completed test running:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/UITestingClean/DeleteTodo4.gif&quot; alt=&quot;Delete To-do Test&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the test, we delete a to-do titled ‘Go to Gym’. To delete the to-do, and verify that it was deleted, you need to perform these steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tap on the to-do titled ‘Go to Gym’ to show the View To-do screen&lt;/li&gt;
  &lt;li&gt;Tap on the delete button&lt;/li&gt;
  &lt;li&gt;Ensure that the View To-do screen is no longer showing&lt;/li&gt;
  &lt;li&gt;Ensure that no to-do exists with the title ‘Go to Gym’&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great, with that item deleted, I’ll finally have time for some Netflix! Here’s what the test class looks like:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoTests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewScreenStarting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TodoListInteracting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoScreenVerifying&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;titleOfTodoForTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Go to Gym&quot;&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCanDeleteTodo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Accessibility&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DeleteButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 3&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewTodoScreenIsShowing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forTodoTitled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 4&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;titled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;waitForExistence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;body-of-the-test&quot;&gt;Body of the test&lt;/h2&gt;

&lt;p&gt;Most of the magic is being done by protocols, so the actual test is very light: only four lines.&lt;/p&gt;

&lt;p&gt;Let’s walk through it:&lt;/p&gt;

&lt;h3 id=&quot;1-finding-the-delete-button&quot;&gt;1. Finding the delete button&lt;/h3&gt;
&lt;p&gt;First, we need a handle on the delete button of the View To-do screen. To access a UI element from the tests, you generally use its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accessibilityIdentifier&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Using the accessibilityIdentifier is something that recording your tests won’t do. If you have a ‘Submit’ button for a form, then recorded tests will look for a button titled ‘Submit’. If the button title changes, the tests will fail. Using the accessibilityIdentifier is a way to get a handle on the button even if something like its title changes.&lt;/p&gt;

&lt;p&gt;To find the delete button, we just look for a button with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Accessibility.View.DeleteButton&lt;/code&gt; identifier. I’ve created an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Accessibility&lt;/code&gt; enum to hold the identifiers for our elements. It looks like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Accessibility&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DeleteButton&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Delete Todo&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This enum is a member of the UI Testing target as well as the app target, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeleteButton&lt;/code&gt; identifier is set on the the actual delete button in the app, in the ViewController for the View To-do screen:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;deleteButton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accessibilityIdentifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Accessibility&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DeleteButton&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2-tapping-on-the-button&quot;&gt;2. Tapping on the button&lt;/h2&gt;

&lt;p&gt;Now that we have a handle on the delete button, tap it.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the same as physically tapping the delete button on the View To-do screen.&lt;/p&gt;

&lt;h2 id=&quot;3-verify-that-the-view-screen-is-dismissed&quot;&gt;3. Verify that the View screen is dismissed&lt;/h2&gt;

&lt;p&gt;Now that the delete button has been tapped, the View To-do screen should pop and navigate back to the main screen. What do you think this line does?&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewTodoScreenIsShowing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forTodoTitled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re asserting that the View To-do screen is not showing for the to-do that we’re testing. It reads quite well, doesn’t it?&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;viewTodoScreenIsShowing&lt;/code&gt; is defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewTodoScreenVerifying&lt;/code&gt; protocol to which this class conforms.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoScreenVerifying&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewTodoScreenIsShowing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forTodoTitled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoScreenVerifying&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;viewTodoScreenIsShowing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forTodoTitled&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dateHeader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticTexts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Is Scheduled For:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;titleLabel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticTexts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateHeader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see if we’re on the View To-do screen, we look for a couple of known elements on that screen. There should be a label titled ‘Is Scheduled For:’, and a label with the title of the to-do. If the composition of the View To-do screen changes, we only need to update the body of this function.&lt;/p&gt;

&lt;p&gt;Any test case that is verifying an aspect of the View To-do screen will conform to the ViewTodoScreenVerifying protocol. ViewTodoTests conforms to ViewTodoScreenVerifying, so we know that it’s a test case that is verifying aspects of the View To-do screen.&lt;/p&gt;

&lt;h2 id=&quot;4-verify-that-the-to-do-is-deleted&quot;&gt;4. Verify that the to-do is deleted&lt;/h2&gt;

&lt;p&gt;In the previous step, we verified that we’re no longer on the View To-do screen. Next, we need to make sure that the deleted to-do doesn’t exist any more.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;titled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;waitForExistence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re looking for a to-do with the same title as the one we’re testing with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo(titled: titleOfTodoForTest)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This test needs to interact with an element on the list of to-dos from the main screen, so we conform to TodoListInteracting to make use of this function.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo(titled:)&lt;/code&gt; is a convenience function to make the task of finding a to-do a little bit easier and more readable:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TodoListInteracting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;titled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIElement&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TodoListInteracting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;titled&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIElement&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;containing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;firstMatch&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;waitForExistence&lt;/code&gt; gives the app some time to wait and see if the element comes into existence. We’re navigating back to the main screen from the View To-do screen, so we want to wait a bit to make sure that the navigation has completed to verify that the to-do doesn’t exist anymore.&lt;/p&gt;

&lt;p&gt;All together now: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo(titled: titleOfTodoForTest).waitForExistence(timeout: 1)&lt;/code&gt; will wait 1 second, and return false if the to-do does not exist.&lt;/p&gt;

&lt;h1 id=&quot;wait-a-second&quot;&gt;Wait a second…&lt;/h1&gt;

&lt;p&gt;I’ve established that the test starts on the View To-Do screen. How did we get there in the first place?&lt;/p&gt;

&lt;p&gt;Let’s take another look at the protocol conformance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewTodoTests&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoTests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewScreenStarting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewTodoScreenVerifying&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The class conforms to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewScreenStarting&lt;/code&gt;, indicating that all tests start on the View To-Do screen. Let’s take a closer look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewScreenStarting&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewScreenStarting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TodoListInteracting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startViewScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewScreenStarting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startViewScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;launch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;titled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configureStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;startViewScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The magic happens inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startViewScreen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, we launch the app with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XCUIApplication().launch()&lt;/code&gt;. In a UI test, the test starts with the app closed.&lt;/p&gt;

&lt;p&gt;ViewScreenStarting also conforms to TodoListInteracting, so it can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;todo(titled:)&lt;/code&gt; function that we used in the body of our test. We need a to-do to open, so ViewScreenStarting has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;titleOfTodoForTest&lt;/code&gt; property that the test case provides. Inside ViewTodoTests, we set the title of the to-do that we’re testing:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;titleOfTodoForTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Go to Gym&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startViewScreen&lt;/code&gt; will know which to-do item to tap.&lt;/p&gt;

&lt;h3 id=&quot;running-code-with-startupconfigurable&quot;&gt;Running code with StartupConfigurable&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startViewScreen&lt;/code&gt; needs to run when the test starts. To do so, we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StartupConfigurable&lt;/code&gt;. ViewScreenStarting conforms to StartupConfigurable. It’s a simple protocol:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;StartupConfigurable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configureStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ViewScreenStarting calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startViewScreen&lt;/code&gt; from this function.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configureStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;startViewScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In turn, we have a base test class that will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configureStartup&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UITestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCTestCase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;StartupConfigurable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configureStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember, ViewTodoTests conforms to ViewScreenStarting, which conforms to StartupConfigurable. This means that ViewTodoTests conforms to StartupConfigurable as well.&lt;/p&gt;

&lt;p&gt;When one of the tests from ViewTodoTests start, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUp&lt;/code&gt; method in UITestCase will run the necessary startup work.&lt;/p&gt;

&lt;h2 id=&quot;tying-it-all-together&quot;&gt;Tying it all together&lt;/h2&gt;

&lt;p&gt;To summarise the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewTodoTests&lt;/code&gt; class:&lt;/p&gt;

&lt;p&gt;It is a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITestCase&lt;/code&gt;, which allows it to run any setup code specified by conformance to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StartupConfigurable&lt;/code&gt; protocol. Tests will start on the View To-do screen, because it conforms to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewScreenStarting&lt;/code&gt;. The boilerplate of the test is cleaned up by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewTodoScreenVerifying&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TodoListInteracting&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It can be a lot to take in, but through this approach, we gain a very simple and easy to read test:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testCanDeleteTodo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Accessibility&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;DeleteButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  
  &lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;viewTodoScreenIsShowing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;forTodoTitled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;XCTAssertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;todo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;titled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titleOfTodoForTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;waitForExistence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-else-can-we-do&quot;&gt;What else can we do?&lt;/h2&gt;

&lt;p&gt;For tests on the Edit screen, you need to navigate to the View screen and then tap the edit button. You could create an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EditScreenStarting&lt;/code&gt; protocol that inherits its functionality from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewScreenStarting&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EditScreenStarting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewScreenStarting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startEditScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EditScreenStarting&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startEditScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Navigate to the view screen&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;startViewScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Tap on the edit button&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCUIApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Accessibility&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;EditButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configureStartup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;startEditScreen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Starting&lt;/code&gt; protocols can cascade - in this example, EditScreenStarting builds off of ViewScreenStarting. You can very easily write tests for a deep and complex ViewController hierarchy in this manner.&lt;/p&gt;

&lt;p&gt;This does a lot to simplify the setup of tests. Combined with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Verifying&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Interacting&lt;/code&gt; protocols, building UI tests is like working with building blocks - just combine the protocols you want, and the tests are easy!&lt;/p&gt;

&lt;h1 id=&quot;please-share-your-thoughts&quot;&gt;Please share your thoughts&lt;/h1&gt;

&lt;p&gt;What do you think of this approach? It’s definitely a work in progress, but I’ve found it to be useful in my tests. I don’t put everything into a protocol, but rather just the repetitive boilerplate, or repeated code that deserves a higher level of abstraction.&lt;/p&gt;

&lt;p&gt;Do you have something to share? Please leave it in the comments below!&lt;/p&gt;
</description>
          <pubDate>2018-10-23T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/UI-Testing-The-Clean-Way/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/UI-Testing-The-Clean-Way/</guid>
        </item>
      
    
      
        <item>
          <title>Creating a macOS Action (Gear) Button Programmatically in Swift</title>
          <description>&lt;p&gt;For a list of actions on macOS, the standard control is an action button as defined in the macOS &lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/macos/buttons/pull-down-buttons/&quot;&gt;Human Interface Guidelines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the definition from that page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;An action button (often referred to as an action menu) is a specific type of pull-down button that operates like a contextual menu, without the disadvantage of being hidden, providing access to app-wide or table-specific commands. An action button includes a gear icon when closed and a downward arrow indicator that alludes to its menu. Action buttons are often used in toolbars, but can also be used in the content area of a view beneath a table view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/ActionButton/ActionButton.png&quot; alt=&quot;Example macOS action button&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Apple isn’t very clear about how to create one of these in code. They tell you to create a button using the system-provided gear icon by making use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSImageNameActionTemplate&lt;/code&gt; image name, but try as I might, I couldn’t replicate the action button used in Finder from that image name alone.&lt;/p&gt;

&lt;p&gt;It turns out that there are a few more steps involved.&lt;/p&gt;

&lt;h2 id=&quot;create-an-nspopupbutton&quot;&gt;Create an NSPopupButton&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let actionButton = NSPopUpButton(frame: .zero, pullsDown: true)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s clear that the button is an NSPopupButton due to the dropdown that it presents.&lt;/p&gt;

&lt;h2 id=&quot;position-the-button&quot;&gt;Position the button&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;view.addSubview(actionButton)
actionButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
  actionButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  actionButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
  ])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Position the button where you need it. For the purposes of this demo, I’m leaving it right in the middle of the parent view. For the reasoning behind &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actionButton.translatesAutoresizingMaskIntoConstraints = false&lt;/code&gt;, take a look at my post on &lt;a href=&quot;http://www.thecodedself.com/autoresizing-masks/&quot;&gt;autoresizing masks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ve created the button and positioned it in the view. This is the result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/ActionButton/Default NSPopupButton.png&quot; alt=&quot;Example macOS action button&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s coming together!&lt;/p&gt;

&lt;h2 id=&quot;add-some-items&quot;&gt;Add some items&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[&quot;Option 1&quot;, &quot;Option 2&quot;, &quot;Option 3&quot;].forEach(actionButton.addItem)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;An action button isn’t too useful without some actions. With an array of item titles, we use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forEach&lt;/code&gt; operator to add the items to the action button. You’ll see these options when clicking on the dropdown arrow.&lt;/p&gt;

&lt;h2 id=&quot;add-the-gear-icon&quot;&gt;Add the gear icon&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let actionItem = NSMenuItem()
actionItem.image = NSImage(named: .actionTemplate)
actionButton.menu?.insertItem(actionItem, at: 0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From the Human Interface Guidelines section on Action Buttons, we learnt that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.actionTemplate&lt;/code&gt; image name will give us the appropriate gear icon.&lt;/p&gt;

&lt;p&gt;Don’t forget to insert the gear icon as the first item in the menu, or it won’t show up as the button’s icon.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/ActionButton/With Gear Icon.png&quot; alt=&quot;Example macOS action button&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Looking good, but we need to remove the text and the blue styling around the dropdown arrow.&lt;/p&gt;

&lt;h2 id=&quot;style-the-cell&quot;&gt;Style the cell&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let cell = actionButton.cell as? NSButtonCell
cell?.imagePosition = .imageOnly
cell?.bezelStyle = .texturedRounded
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On macOS, most of the UI configuration is done by modifying the NSCells belonging to your views.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actionButton.cell&lt;/code&gt; is of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSCell&lt;/code&gt;, but the properties that we need exist on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSButtonCell&lt;/code&gt;. We know that the cell is an NSButtonCell because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actionButton&lt;/code&gt; is a type of NSButton, so we cast the cell as an NSButtonCell.&lt;/p&gt;

&lt;p&gt;Next, we set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;imagePosition&lt;/code&gt; to get rid of the text that was displaying on the button.&lt;/p&gt;

&lt;p&gt;To style the shape of a bordered button, we make use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bezelStyle&lt;/code&gt; property. Kuba Suder has &lt;a href=&quot;https://mackuba.eu/2014/10/06/a-guide-to-nsbutton-styles/&quot;&gt;a guide to NSButton styles&lt;/a&gt; that is invaluable when creating buttons in code.&lt;/p&gt;

&lt;p&gt;To get rid of the blue dropdown arrow, make use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.texturedRounded&lt;/code&gt; style. That gives us our final result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/ActionButton/Finished Action Gear Button.png&quot; alt=&quot;Example macOS action button&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A button that fully matches the system’s action button. Here’s all of the code together:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/TheCodedSelf/e07a789cb6319cc8cd70a21cb5ce0989.js&quot;&gt;&lt;/script&gt;

&lt;p class=&quot;notice--info&quot;&gt;I hope that this post has been useful to you, and that you’ve enjoyed this small foray into macOS development. Are you an iOS developer that’s been playing around with macOS? I’d love to hear about your journey in the comments below.&lt;/p&gt;
</description>
          <pubDate>2018-07-17T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/macOS-action-button-swift/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/macOS-action-button-swift/</guid>
        </item>
      
    
      
        <item>
          <title>Autoresizing Masks and You</title>
          <description>&lt;p&gt;You’re an Autolayout Wizard. You know Interface Builder like the back of your hand. Then, one day, you create a simple UIView, add it as a subview with some elegantly crafted constraints, and.. it blows up in your face. What gives?&lt;/p&gt;

&lt;p&gt;Take a look at this code example that tries to create a UILabel and center it in the view.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let centerLabel = UILabel()
centerLabel.text = &quot;Perfectly centered!&quot;
view.addSubview(centerLabel)

NSLayoutConstraint.activate([
  centerLabel.centerXAnchor.constraint(
    equalTo: view.centerXAnchor, constant: 0),
  centerLabel.centerYAnchor.constraint(
    equalTo: view.centerYAnchor, constant: 0)
  ])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Try this, and you’ll be thoroughly disappointed. The perfectly centered label is nowhere to be found.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AutoResizing/empty.png&quot; alt=&quot;A disappointing result&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Luckily, the console output provides a vital clue.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[LayoutConstraints] Unable to simultaneously satisfy constraints.
	Probably at least one of the constraints in the following list is one you don't want. 
	Try this: 
		(1) look at each constraint and try to figure out which you don't expect; 
		(2) find the code that added the unwanted constraint or constraints and fix it. 
	(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    &quot;&amp;lt;NSAutoresizingMaskLayoutConstraint:0x60400009cb60 h=--&amp;amp; v=--&amp;amp; UILabel:0x7f927f2021b0'Perfectly centered!'.midY == 0   (active)&amp;gt;&quot;,
    &quot;&amp;lt;NSLayoutConstraint:0x608000099140 UILabel:0x7f927f2021b0'Perfectly centered!'.centerY == UIView:0x7f927f1017b0.centerY   (active)&amp;gt;&quot;,
    &quot;&amp;lt;NSLayoutConstraint:0x60400009cd90 'UIView-Encapsulated-Layout-Height' UIView:0x7f927f1017b0.height == 568   (active)&amp;gt;&quot;,
    &quot;&amp;lt;NSAutoresizingMaskLayoutConstraint:0x60400009ce30 h=-&amp;amp;- v=-&amp;amp;- 'UIView-Encapsulated-Layout-Top' UIView:0x7f927f1017b0.minY == 0   (active, names: '|':UIWindow:0x7f927bd073a0 )&amp;gt;&quot;
)

Will attempt to recover by breaking constraint 
&amp;lt;NSLayoutConstraint:0x608000099140 UILabel:0x7f927f2021b0'Perfectly centered!'.centerY == UIView:0x7f927f1017b0.centerY   (active)&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looks like it’s a problem with Autolayout constraints.&lt;/p&gt;

&lt;p&gt;`
[LayoutConstraints] Unable to simultaneously satisfy constraints.
`&lt;/p&gt;

&lt;p&gt;It goes on to say:&lt;/p&gt;

&lt;p&gt;`
(Note: If you’re seeing NSAutoresizingMaskLayoutConstraints that you don’t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
`&lt;/p&gt;

&lt;p&gt;Looking at the conflicting constraints in the console output, we’re getting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSAutoresizingMaskLayoutConstraints&lt;/code&gt; that were just mentioned.&lt;/p&gt;

&lt;p&gt;`
&amp;lt;NSAutoresizingMaskLayoutConstraint:0x6080000993c0 h=–&amp;amp; v=–&amp;amp; UILabel:0x7ff037604a20’Perfectly centered!’.midY == 0   (active)&amp;gt;
`&lt;/p&gt;

&lt;p&gt;So, it’s finally time to ask:&lt;/p&gt;

&lt;h2 id=&quot;what-the-heck-is-an-autoresizing-mask&quot;&gt;What the heck is an Autoresizing Mask?&lt;/h2&gt;

&lt;p&gt;Before Auto Layout, the current layout system on iOS, views were resized using the &lt;em&gt;springs and struts&lt;/em&gt; layout system. A view’s width and height are its &lt;em&gt;springs&lt;/em&gt; which can stretch. The &lt;em&gt;struts&lt;/em&gt; are the view’s distance to its container. You can imagine that the view is ‘sitting’ on the struts, held in place, to determine the view’s position. The view’s springs can stretch as necessary to determine the size and shape of the view.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;autoresizing mask&lt;/em&gt; determines which springs and struts can change to position the view in different layouts.&lt;/p&gt;

&lt;p&gt;The autoresizing mask can be any combination of these values:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleBottomMargin&lt;/code&gt;: Allows the bottom strut (the distance between the bottom of the view and its container) to change&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleTopMargin&lt;/code&gt;: Allows the top strut (the distance between the top of the view and its container) to change&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleLeftMargin&lt;/code&gt;: Allows the left strut (the distance between the left of the view and its container) to change&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleRightMargin&lt;/code&gt;: Allows the right strut (the distance between the right of the view and its container) to change&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleHeight&lt;/code&gt;: Allows the height spring to change&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIViewAutoresizingFlexibleWidth&lt;/code&gt;: Allows the width spring to change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a lot easier to visualize by looking at the example at Interface Builder gives you. Drag any view into a nib or storyboard. Before adding any constraints, choose the Size Inspector tab in the right pane (Alt-Cmd-5) and play with the values in the Autoresizing section.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AutoResizing/Autoresizing-Example.gif&quot; alt=&quot;Autoresizing example&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-does-it-cause-conflicting-constraints&quot;&gt;Why does it cause conflicting constraints?&lt;/h2&gt;

&lt;p&gt;At the introduction of Autolayout, a lot of views were still laid out using springs and struts, both internal to UIKit as well as in third-party apps. For this reason, UIKit creates constraints automatically to adapt the springs and struts layout system to Autolayout.&lt;/p&gt;

&lt;p&gt;If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatesAutoresizingMaskIntoConstraints&lt;/code&gt; property of your UIView is set to true, UIKit will create Autolayout constraints that best fit your view’s autoresizing mask.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatesAutoresizingMaskIntoConstraints&lt;/code&gt; is automatically set to false when you create a view inside Interface Builder and start to add your own constraints. You don’t have this luxury if you’re laying out your view in code, and you’ll have to set the property manually.&lt;/p&gt;

&lt;p&gt;So, if you add constraints to a view created in code, you’ll most likely see conflicting constraints until you set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatesAutoresizingMaskIntoConstraints&lt;/code&gt; to false.&lt;/p&gt;

&lt;p&gt;Making that change in the previous example will cause the label to display correctly.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let centerLabel = UILabel()

// Don't forget this!
centerLabel.translatesAutoresizingMaskIntoConstraints = false

centerLabel.text = &quot;Perfectly centered!&quot;
view.addSubview(centerLabel)

NSLayoutConstraint.activate([
  centerLabel.centerXAnchor.constraint(
    equalTo: view.centerXAnchor, constant: 0),
  centerLabel.centerYAnchor.constraint(
    equalTo: view.centerYAnchor, constant: 0)
  ])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AutoResizing/perfectly-centered.png&quot; alt=&quot;Autoresizing example&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Looking good!&lt;/p&gt;

&lt;h1 id=&quot;you-probably-wont-need-the-autoresizing-mask&quot;&gt;You probably won’t need the autoresizing mask.&lt;/h1&gt;

&lt;p&gt;You’ll almost always be using Autolayout when laying out your views. Interface Builder sets &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatesAutoresizingMaskIntoConstraints&lt;/code&gt; to false for you, and you’ll need to do it yourself when creating views in code.&lt;/p&gt;

&lt;p&gt;I hope this post has been useful to you! You might already know to flip the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatesAutoresizingMaskIntoConstraints&lt;/code&gt; switch when you’re seeing strange behavior, but it’s helpful to get some background to help you remember.&lt;/p&gt;

&lt;p class=&quot;notice--info&quot;&gt;Thanks for taking the time to read this. If you enjoyed it, please share it with your friends. I’d also love to hear your suggestions in the comments below.&lt;/p&gt;
</description>
          <pubDate>2018-01-23T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/autoresizing-masks/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/autoresizing-masks/</guid>
        </item>
      
    
      
        <item>
          <title>Functions Deserve Injection, Too</title>
          <description>&lt;p&gt;Lately, I’ve been taking advantage of Swift’s functional abilities where it makes sense to help me write concise and clear code that’s easy to test. I’d like to share one technique that has helped me to eliminate repetition and breakages of encapsulation in tests: &lt;strong&gt;function injection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In traditional &lt;a href=&quot;https://en.wikipedia.org/wiki/Dependency_injection&quot;&gt;dependency injection&lt;/a&gt;, an object that is dependended on is passed to the method that depends on it. Function injection is my name for following the same approach when your function consumes another function.&lt;/p&gt;

&lt;p&gt;As a code base evolves over time, a lot of small, focused utilities are added. Here’s one small utility function that I use quite often:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;extension String {
    func isNonEmpty() -&amp;gt; Bool {
        return !trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This eliminates the verbosity of checking if a string is empty or contains only whitespace. It is, understandably, quite easy to test as well.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    func testNoCharactersReturnsTrue() {
        XCTAssertFalse(&quot;&quot;.isNonEmpty())
    }
    
    func testOnlyBlankSpacesReturnsTrue() {
        XCTAssertFalse(&quot;         &quot;.isNonEmpty())
    }
    
    func testNewlineReturnsTrue() {
        XCTAssertFalse(&quot;  \n   &quot;.isNonEmpty())
    }
    
    func testNonEmptyStringReturnsFalse() {
        XCTAssertTrue(&quot;Hello there&quot;.isNonEmpty())
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As an example, imagine that we’re using this in an app for a clothings store. When you walk into the store, you should get a push notification from the app with a greetings message containing the user’s name. If there’s something wrong with the user’s name - if it’s empty or whitespace - we’ll throw an error.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;struct Greeter {
    func greet(name: String) throws -&amp;gt; String {
        guard name.isNonEmpty() else { throw GreetingError.invalidName }
        return &quot;Welcome, \(name)! Have you seen the specials on offer?&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s write some tests for this function.&lt;/p&gt;

&lt;p&gt;We want to test two things:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The returned message is correct when the name is valid&lt;/li&gt;
  &lt;li&gt;An error is thrown when the business logic determines that a name is invalid&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    func testGreetingWithValidNameReturnsGreetingString() {
        let expected = &quot;Welcome, Caroline! Have you seen the specials on offer?&quot;
        let actual = try? Greeter().greet(name: &quot;Caroline&quot;)
        XCTAssertEqual(expected, actual)
    }
    
    func testGreetingWithEmptyNameThrowsInvalidNameError() {
        verifyGreetingErrorIsThrown(whenGiven: &quot;&quot;)
    }
    
    func testGreetingWithBlankSpaceNameThrowsInvalidNameError() {
        verifyGreetingErrorIsThrown(whenGiven: &quot;   &quot;)
    }
    
    func testGreetingWithNewlineCharacterNameThrowsInvalidNameError() {
        verifyGreetingErrorIsThrown(whenGiven: &quot;  \n &quot;)
    }
    
    func verifyGreetingErrorIsThrown(whenGiven name: String) {
        do {
            try Greeter().greet(name: name)
            XCTFail(&quot;An error should have been thrown&quot;)
        } catch GreetingError.invalidName {
            return
        } catch {
            XCTFail(&quot;Incorrect error type was thrown&quot;)
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, that’s a lot of tests for such a small function…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/FunctionInjection/interesting.gif&quot; alt=&quot;So many tests? Interesting.&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;If you look closely, you’ll see that we’re basically repeating all of the negative tests of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isNonEmpty&lt;/code&gt; function. If we follow this approach, we’ll be repeating the tests at every use site of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isNonEmpty&lt;/code&gt;. That breaks the DRY principle, and it could be much worse if you had more complex logic than simply checking if a user typed a bunch of spaces for their username.&lt;/p&gt;

&lt;p&gt;When we’re testing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet&lt;/code&gt; function, we don’t actually want to be testing what it means for a string to be empty or not. That’s already been defined somewhere else in the code base. We simply want to test what the function does when it works, and how it fails when it doesn’t.&lt;/p&gt;

&lt;p&gt;When you’re testing a component that depends on another, we make use of Dependency Injection to pass the dependence in. That way we can control the behavior. It keeps tests short and focused.&lt;/p&gt;

&lt;p&gt;We could refactor the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isNonEmpty&lt;/code&gt; function to its own class, and inject it either by using a dependency container or as a parameter to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet&lt;/code&gt; function, but that seems like overkill. This is where the functional nature of Swift comes in. Rather than creating a class to pass as a parameter, we can &lt;strong&gt;apply dependency injection by injecting the function itself.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;/h2&gt;

&lt;p&gt;Rather than directly calling isNonEmpty in the greet function, we’ll pass it in as a parameter.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    func greet(name: String,
               isNonEmpty: (String) -&amp;gt; Bool = { $0.isNonEmpty() })
        throws -&amp;gt; String {
            guard isNonEmpty(name) else { throw GreetingError.invalidName }
            return &quot;Welcome, \(name)! Have you seen the specials on offer?&quot;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The new parameter has a default value set to call the intended closure. We can use it in production code without worrying about the extra parameter:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter.greet(name: &quot;Batman&quot;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This adheres to the “Clarity at the point of use” section of the &lt;a href=&quot;https://swift.org/documentation/api-design-guidelines/#fundamentals&quot;&gt;Swift API Design Guidelines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, when testing, we don’t need to check every permutation of the isNonEmptyFunction. We just inject a closure that returns true for testing the happy path, and we return false when testing the failure case.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    func testGreetingReturnsGreetingStringWhenNotEmpty() {
        let expected = &quot;Welcome, Caroline! Have you seen the specials on offer?&quot;
        let actual = try? Greeter().greet(name: &quot;Caroline&quot;, isNonEmpty: { _ in true })
        XCTAssertEqual(expected, actual)
    }
    
    func testGreetingThrowsInvalidNameErrorWhenEmpty() {
        do {
            try Greeter().greet(name: &quot;asdf&quot;, isNonEmpty: { _ in false })
            XCTFail(&quot;An error should have been thrown&quot;)
        } catch GreetingError.invalidName {
            return
        } catch {
            XCTFail(&quot;Incorrect error type was thrown&quot;)
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From four tests down to two! The tests are now focused solely on the purpose of the greet function and no longer leak the implementation of isNonEmpty.&lt;/p&gt;

&lt;p&gt;A lot of developers tend to be quite good at following dependency injection when depending on another class, but when the dependence is a function, it can sometimes be overlooked. &lt;strong&gt;Function injection&lt;/strong&gt; provides the same benefits to testing and composability of regular dependency injection.&lt;/p&gt;

&lt;p&gt;This approach can be followed whenever one function depends on the output of another.  You can use it when querying important business logic, to dictate the output of utility functions, or to set the expected behavior of standard library functions.&lt;/p&gt;

&lt;h2 id=&quot;please-share-your-thoughts&quot;&gt;Please Share Your Thoughts&lt;/h2&gt;

&lt;p&gt;I like how straightforward testing can be when following this approach. The most common use case for me is small utility functions that build on other utility functions.&lt;/p&gt;

&lt;p&gt;However, make sure to use it only when it makes sense. Sometimes the right thing to do is to create a new class behind a new protocol, and then inject that protocol instead.&lt;/p&gt;

&lt;p&gt;I’ve put the complete example code in a Playground &lt;a href=&quot;https://github.com/TheCodedSelf/FunctionInjection&quot;&gt;on my GitHub account&lt;/a&gt; if you’d like to see more. What do you think? Do you have any alternatives? Let me know.&lt;/p&gt;

&lt;p&gt;Have fun, and happy Swifting!&lt;/p&gt;
</description>
          <pubDate>2017-11-28T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/functions-deserve-injection/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/functions-deserve-injection/</guid>
        </item>
      
    
      
        <item>
          <title>Staying Sane with Cuckoo and Code Generation</title>
          <description>&lt;p class=&quot;notice--info&quot;&gt;&lt;strong&gt;Please note&lt;/strong&gt; that this post won’t go over the basics of Cuckoo, as the &lt;a href=&quot;https://github.com/Brightify/Cuckoo/blob/master/README.md&quot;&gt;README&lt;/a&gt; provides a great introduction to the library.&lt;/p&gt;

&lt;p&gt;Do you write unit tests? You should. Writing mocks for my tests seemed to be a lot easier in Objective-C. &lt;a href=&quot;http://ocmock.org/&quot;&gt;OCMock&lt;/a&gt; makes great use of Objective-C’s dynamic nature and it makes mocking a breeze. However, the OCMock website has &lt;a href=&quot;http://ocmock.org/swift/&quot;&gt;this to say&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/Cuckoo/ocmock-swift-comment.png&quot; alt=&quot;No mocking frameworks for Swift&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Disappointing. Accurate.&lt;/p&gt;

&lt;p&gt;Alright, off to find an alternative. The best that I could find was &lt;a href=&quot;https://github.com/mflint/SwiftMock&quot;&gt;SwiftMock&lt;/a&gt;, but that came with an even sharper let-down:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/Cuckoo/SwiftMock.png&quot; alt=&quot;Roll your own Swift mocks&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It seems that Swift’s lack of reflection means that we’ll be doomed to doing things manually and rewriting the same type of code, again and again.&lt;/p&gt;

&lt;p&gt;So, I resorted to rolling my own mocks. It’s not that bad. Really. I built a little mocking framework of my own based off of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt; protocol and use of Swift’s basic reflection, and all was happy in the world of TDD.&lt;/p&gt;

&lt;p&gt;When you’re writing a lot of code and all of the tests that should come with it, all of the time spent writing boilerplate for your mocks gets tiring. I was hungry for something more efficient.&lt;/p&gt;

&lt;h1 id=&quot;then-i-was-introduced-to-cuckoo&quot;&gt;Then, I was introduced to Cuckoo.&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/Brightify/Cuckoo&quot;&gt;Cuckoo&lt;/a&gt; is a mocking framework for Swift that uses code generation to create the boilerplate that you’d otherwise be writing yourself. It comes with a lot of functionality that I think would be far too tedious and repetitive to do on your own. It also ensures consistency, which is something that I’ve found to be sorely lacking in the world of hand-rolled mocks.&lt;/p&gt;

&lt;h1 id=&quot;code-generation-versus-reflection&quot;&gt;Code Generation versus Reflection&lt;/h1&gt;

&lt;p&gt;Most programming languages use reflection to dynamically perform things that we would otherwise have to write repetitive boilerplate for. OCMock uses reflection to create mock objects. It doesn’t actually create a new class for each type you wish to mock. Reflection allows languages like Objective-C to dynamically create mocks, check for equatability, and perform JSON serialization.&lt;/p&gt;

&lt;p&gt;As of yet, this isn’t an easy feat in Swift. The Swift language shuns dynamic behaviour and encourages safer methods. Code generation, on the other hand, fits very well with Swift’s type safety. You have code that can be read by a human and verified by a compiler.&lt;/p&gt;

&lt;p&gt;It felt weird to me at first. I may not have written the boilerplate, but it’s still there. Written by a tool and hidden in the background. But this seems to be the way forward in a language like Swift. Frameworks like &lt;a href=&quot;https://github.com/krzysztofzablocki/Sourcery&quot;&gt;Sourcery&lt;/a&gt; and &lt;a href=&quot;https://github.com/SwiftGen/SwiftGen&quot;&gt;SwiftGen&lt;/a&gt; let you adopt code generation for these tasks that might otherwise be done via reflection.&lt;/p&gt;

&lt;p&gt;The lack of reflection and strong type safety mean that code generation is the new go-to when it comes to reducing your time spent on monotonous tasks and more time working on the important parts of your app.&lt;/p&gt;

&lt;p&gt;Cuckoo’s use of code generation has numerous benefits over the reflection approach, such as type checking, optimization, and the ability to step through and debug the generated code.&lt;/p&gt;

&lt;h1 id=&quot;using-cuckoo-without-going-nuts&quot;&gt;Using Cuckoo without going nuts&lt;/h1&gt;

&lt;p&gt;Cuckoo has become easier to use with a fair bit of trial and error. Here are some insights that I’ve learned so far.&lt;/p&gt;

&lt;h2 id=&quot;get-comfortable-with-parametermatchers&quot;&gt;Get comfortable with ParameterMatchers&lt;/h2&gt;

&lt;p&gt;Looking at this example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;stub(mock) { stub in
  when(stub.greetWithMessage(&quot;Hello world&quot;)).thenDoNothing()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re stubbing the behaviour of calls to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greetWithMessage&lt;/code&gt; function when passed the string “Hello World”. It’s important to note here that the code doesn’t actually expect a String object. It expects a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Matchable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Matchable&lt;/code&gt; protocol is used to verify that an argument matches a set of criteria. The reason we can pass the “Hello World” string to the example above is because Cuckoo kindly extends String to conform to Matchable out of the box:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;extension String: Matchable {
    public var matcher: ParameterMatcher&amp;lt;String&amp;gt; {
        return equal(to: self)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This means that any mocked function expecting a String Matchable can be passed an instance of String.&lt;/p&gt;

&lt;p&gt;How can we match on our own custom objects?&lt;/p&gt;

&lt;p&gt;Say we have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logInWithCredentials&lt;/code&gt; function that takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UserCredentials&lt;/code&gt; object as an argument. When Cuckoo generates mocks, we’ll need to pass a Matchables object to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginWithCredentials&lt;/code&gt; function. We can extend the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UserCredentials&lt;/code&gt; object just like String was extended:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;extension UserCredentials: Matchable {
    public var matcher: ParameterMatcher&amp;lt;UserCredentials&amp;gt; {
        return ParameterMatcher { $0 == self }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now we can stub the function like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let testCredentials = UserCredentials(name: &quot;Bradley&quot;, password: &quot;pass&quot;)
stub(mock) { stub in
    when(stub.logInWithCredentials(testCredentials)).thenDoNothing() 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember that you can also do more complex checks than just comparing equality.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let matchesUserStartingWithB = ParameterMatcher&amp;lt;UserCredentials&amp;gt; { 
    $0.name.first! == &quot;B&quot; 
}

stub(mock) { stub in
    when(stub.logInWithCredentials(matchesUserStartingWithB)).thenDoNothing() 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;run-the-script-before-compiling-your-tests&quot;&gt;Run the script before compiling your tests&lt;/h2&gt;

&lt;p&gt;Cuckoo’s documentation suggests that you add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run Script&lt;/code&gt; phase to your test target for the generation of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneratedMocks.swift&lt;/code&gt; file that contains your mocks.&lt;/p&gt;

&lt;p&gt;You can save yourself some time by avoiding my stupid mistake: Make sure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run Script&lt;/code&gt; phase for Cuckoo is placed &lt;strong&gt;before&lt;/strong&gt; actually compiling your tests.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/Cuckoo/RunCuckoo.png&quot; alt=&quot;Run Cuckoo before compiling tests&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;break-down-unclear-compilation-errors&quot;&gt;Break down unclear compilation errors&lt;/h2&gt;

&lt;p&gt;Cuckoo can throw some rather cryptic compilation errors when things aren’t right. Cuckoo has also been known to break the Swift compiler at times and give it a segmentation fault, in which case you won’t get the helpful red text on the line that is causing the breakage. Make sure to look carefully at any compiler errors and read the messages to pinpoint your problem.&lt;/p&gt;

&lt;p&gt;Standard debugging techniques apply: break the issue down into its simplest parts. Eliminate all possibilities until you know what the issue is. Simplify what you’re trying to do until you get it to work, and build it up from there.&lt;/p&gt;

&lt;p&gt;If you mismatch types, the errors can be particularly bad:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/Cuckoo/CrypticCuckooError.png&quot; alt=&quot;Cryptic Cuckoo error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What’s happened here is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginWithCredentials&lt;/code&gt; method is expecting a Matchable for a UserCredentials object, but instead, I’ve passed it a String.&lt;/p&gt;

&lt;p&gt;In situations like these, or when you have complex expressions and suspect that it might be impacting the compiler, it helps to strip away the type inference until things start working again. So rather than:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;stub(mock) { stub in
    when(stub.logInWithCredentials(ParameterMatcher { $0.userId == 123 })).then { response in
        print(response.statusCode)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’d be more explicit in specifying the types, like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let matchesUser123 = ParameterMatcher&amp;lt;LoginCredentials&amp;gt; { $0.userId == 123 }
stub(mock) { stub in
    when(stub.logInWithCredentials(matchesUser123).then { (response: LoginResponse) in
        print(response.statusCode)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;call-verify-last-not-first&quot;&gt;Call verify last, not first&lt;/h2&gt;

&lt;p&gt;Here comes the facepalm moment.&lt;/p&gt;

&lt;p&gt;Coming from an OCMock background, you may be used to calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OCMExpect&lt;/code&gt; before actually calling your production code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- (void)testLoggingInCallsLoginService {
    OCMExpect([mockLoginService loginWithCredentials:OCMOCK_ANY]);
    [classUnderTest startLoginProcess];
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Do this with Cuckoo and your tests will always fail. Calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;verify&lt;/code&gt; are checked when you call it, so call it after calling your other code, not before.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;func testLoggingInCallsLoginService {
    classUnderTest.startLoginProcess()
    verify(mockLoginService).loginWithCredentials(any())
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/Cuckoo/facepalm.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;if-you-cant-beat-them-exclude-them&quot;&gt;If you can’t beat them, exclude them&lt;/h2&gt;

&lt;p&gt;Structs can’t be mocked due to the fact that they can’t be inherited from (you’d stub a protocol instead). Some classes can be tricky as well, such as complex subclasses of UIViewController. Sometimes, I have a protocol in a file that I want Cuckoo to generate mocks for, and another object in that same file that I want Cuckoo to ignore. You can do this quite easily with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--exclude&lt;/code&gt; option:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;${PODS_ROOT}/Cuckoo/run generate --testable &quot;$PROJECT_NAME&quot; \
--exclude &quot;ThatStructIWantToExclude,\
ThatOtherObjectThatBreaksMyBuild&quot; \
--output &quot;${OUTPUT_FILE}&quot; \
&quot;$INPUT_DIR/FileName1.swift&quot; \
&quot;$INPUT_DIR/FileName2.swift&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--exclude&lt;/code&gt; option is a relatively new addition that solved quite a few problems that would otherwise cause a need to revert to hand-rolled mocks. Let that be a good lesson to read the documentation frequently.&lt;/p&gt;

&lt;h1 id=&quot;use-it-when-it-makes-sense&quot;&gt;Use it when it makes sense&lt;/h1&gt;

&lt;p&gt;Cuckoo is a time saver. Spend a bit of time up front to learn its ins and outs, and you may find it to be the most efficient tool for the job. If it isn’t, don’t use it.&lt;/p&gt;

&lt;p&gt;There are scenarios where a quick hand-rolled mock is the best way to go, and I still do it when it’s the quicker option. Be pragmatic and do what works for you and your team.&lt;/p&gt;

&lt;p&gt;Write valuable software. Test your code. Have fun. And happy Swifting!&lt;/p&gt;
</description>
          <pubDate>2017-10-30T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/cuckoo-and-code-generation/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/cuckoo-and-code-generation/</guid>
        </item>
      
    
      
        <item>
          <title>Lessons learned from Systems Thinking</title>
          <description>&lt;p&gt;I was lucky enough to attend my first meetup in Poland this month: &lt;a href=&quot;https://www.meetup.com/Agile-Poznan/events/242364938/&quot;&gt;Agile Poznan&lt;/a&gt;. The talk was on &lt;a href=&quot;http://managedagile.com/what-is-systems-thinking-and-why-is-it-important/&quot;&gt;Systems Thinking&lt;/a&gt;, a topic that bored me in college but fascinated me when I entered the real world. Applying systems thinking can reveal the origins behind events and behaviors we see every day. Using this clarity can make you a better software developer, and a better asset to your organisation in general.&lt;/p&gt;

&lt;p&gt;Here are some of my insights from the meetup.&lt;/p&gt;

&lt;h2 id=&quot;a-quick-definition&quot;&gt;A quick definition&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;system&lt;/strong&gt; is made up of elements that share a purpose. &lt;strong&gt;Elements&lt;/strong&gt; can be people, machines, or other sub-systems within the system. The elements are connected within the &lt;strong&gt;boundary&lt;/strong&gt; of a system.&lt;/p&gt;

&lt;p&gt;You can identify a system through its elements and the connections between them, its purpose, and its boundary. Identifying the elements is easy. The purpose, boundary, and connections might be a little harder to find.&lt;/p&gt;

&lt;h2 id=&quot;its-not-the-fault-of-the-person-its-the-system&quot;&gt;It’s not the fault of the person. It’s the system.&lt;/h2&gt;

&lt;p&gt;A surprising majority of problems can be mitigated when you stop blaming the person that made a mistake, and build your system so that the problem won’t happen again. The person is just the messenger that’s showing you that the house is burning down.&lt;/p&gt;

&lt;p&gt;Code reviews used to occasionally frustrate me before I came to this way of thinking. I’d find myself reiterating the same comments repeatedly. I want to learn, and I want to help others to learn, but learning gets diluted when we are forced to focus on miniscule issues like styling in a code review and miss the real opportunities for growth.&lt;/p&gt;

&lt;p&gt;I see using a tool like &lt;a href=&quot;http://danger.systems/ruby/&quot;&gt;Danger&lt;/a&gt;, or adding any linting or code formatting to your development pipeline, as a great application of systems thinking. You’re building safeguards in the system that will allow you to focus on more important and nuanced issues.&lt;/p&gt;

&lt;h2 id=&quot;the-performance-of-an-organisation-depends-on-the-quality-of-systems-not-of-individuals&quot;&gt;The performance of an organisation depends on the quality of systems, not of individuals.&lt;/h2&gt;

&lt;p&gt;The overhead of trying to micromanage every individual in an organisation outweighs the possible benefits. You simply can’t maintain it as the organisation grows and grows. The people are indispensable, but they come and go in a way that can’t be controlled. What can be controlled is the systems that the organisation runs on.&lt;/p&gt;

&lt;p&gt;When an organisation improves its systems, the benefit is increased productivity. But it’s not just increased productivity right now, with the current teams and employees. It’s a benefit for the people there now, and those that are still to come, whether in six months or six years. Spend the initial time up front setting up a system that fosters growth, and you’ll save time and create value in the long run.&lt;/p&gt;

&lt;p&gt;Here are some system improvements that could be used to improve company-wide performance:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Allocate a self-education budget to each employee&lt;/li&gt;
  &lt;li&gt;Issue a training manual to each new hire&lt;/li&gt;
  &lt;li&gt;Organise office space with focus and productivity in mind (i.e. avoid open plan offices)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;problems-faced-by-an-organisation-can-most-likely-be-solved-by-a-system&quot;&gt;Problems faced by an organisation can most likely be solved by a system.&lt;/h2&gt;

&lt;p&gt;It can be surprising to realise that most problems can be tied back to a system. Sometimes the system doesn’t exist yet. That’s the problem. Here are some examples of problems that might not necessarily look like system problems at the first glance, as well as a possible solution that takes the system into account:&lt;/p&gt;

&lt;h4 id=&quot;a-high-frequency-of-software-defects&quot;&gt;A high frequency of software defects&lt;/h4&gt;
&lt;p&gt;Are there adequate QA processes? Could a safer programming language or framework be justified?&lt;/p&gt;

&lt;h4 id=&quot;underskilled-developers&quot;&gt;Underskilled developers&lt;/h4&gt;
&lt;p&gt;Try arranging weekly lightning talks related to the development that you’re doing. Chances are, there are senior developers that would love the experience and junior developers that would love to learn.&lt;/p&gt;

&lt;h4 id=&quot;the-same-bugs-occurring-repeatedly&quot;&gt;The same bugs occurring repeatedly&lt;/h4&gt;
&lt;p&gt;You fix it one day, and then it’s back the next. A company policy of writing a quick internal knowledge base article describing the cause, symptoms, and solution of the bug might help. (Two software bugs are rarely the same, and I can see this technique working better for something like tech support. However, if sharing your knowledge is what it takes to prevent yet another off-by-one error, then so be it.)&lt;/p&gt;

&lt;h2 id=&quot;boundaries-are-flexible&quot;&gt;Boundaries are flexible.&lt;/h2&gt;

&lt;p&gt;Not all problems fall within the bounds of your system. How then are we meant to apply systems thinking? It’s still possible by &lt;em&gt;expanding the system&lt;/em&gt;. One example is an app development shop that constantly deals with clients bringing in new requirements at the last minute. How can we prevent this? The client is external to the system. Changing our internal operating procedures won’t help here.&lt;/p&gt;

&lt;p&gt;One approach is to expand the system to include the client as an internal element, not an external problem. Include them as part of your internal processes. Let them be a part of designing the end product. Ask for their feedback often. (Sounds a lot like Agile, doesn’t it?)&lt;/p&gt;

&lt;h2 id=&quot;fix-the-problem-not-the-symptom&quot;&gt;Fix the problem, not the symptom.&lt;/h2&gt;

&lt;p&gt;If you have an aching back, a painkiller is a great remedy. Really does the trick, right? The pain goes away in no time. The problem is when the pain comes back the next day. And next month. And again, and again.&lt;/p&gt;

&lt;p&gt;We know not to only focus on symptoms. Get a bed that’s better suited for your back. Go for walks and get some exercise. Change sitting positions often.&lt;/p&gt;

&lt;p&gt;The same thing can happen with software projects. When one is falling behind, we double down, add more manpower, and put our effort into shipping on time. Sometimes, it even works. Why, though, does it keep happening with all the subsequent projects?&lt;/p&gt;

&lt;p&gt;Our focus shouldn’t be on the currently failing project. It’s just a symptom of a wider cause - a failing system. The problem doesn’t lie in the current project that’s executing, the problem lies in the system of how you execute software projects. Step back to see the wider system and its purpose, and you can apply a solution that’ll work for the current problem, as well as the next one.&lt;/p&gt;

&lt;h1 id=&quot;a-final-thought&quot;&gt;A final thought&lt;/h1&gt;

&lt;p&gt;A surface level understanding and adoption of systems thinking provides a shift in perception that has proven beneficial to me. While you could do a series of lectures on the nuances and trade-offs against other methodologies, that’s not what I want from it. A wider understanding of my surroundings and what is under my control, and how to affect it, is enough for me.&lt;/p&gt;

&lt;p&gt;Steven Covey paints a picture of the difference between managers and leaders in his book, The Seven Habits of Highly Effective People:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Envision a group of producers cutting their way through the jungle with machetes. 
The managers are behind them, sharpening their machetes, writing policy and procedure manuals, holding muscle development programs, bringing in improved technologies, and setting up working schedules and compensation programs for machete wielders.
The leader is the one who climbs the tallest tree, surveys the entire situation, and yells, “Wrong jungle!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m certain that the leader in this story was a strong systems thinker.&lt;/p&gt;
</description>
          <pubDate>2017-09-20T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/systems-thinking/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/systems-thinking/</guid>
        </item>
      
    
      
        <item>
          <title>iOS: Animating your own toast view</title>
          <description>&lt;p&gt;A toast view is a small, short-lived popup provides a small bite of information (see what I did there?) to the user. It’s an Android paradigm, but if you’re working on an iOS app that has an Android component, the chances are high that you have been or will be asked to implement one at some point. So you might as well learn how to make one simply without having to pull in a 3rd-party dependency, right? Well, let’s get started then.&lt;/p&gt;

&lt;p&gt;I’ll focus on helping you get the basics of the animation down. The actual look of the view can be left to more talented designers than myself.&lt;/p&gt;

&lt;h1 id=&quot;animating-a-drop-down-view-from-the-navigation-bar&quot;&gt;Animating a drop down view from the navigation bar&lt;/h1&gt;

&lt;p&gt;We’re going to animate the toast coming down from the navigation bar, but the lessons learnt needn’t be tied to the exact implementation. Create your animations as you wish. This is the final result that we’re hoping to achieve:&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Toast animation from UINavigationBar&quot; src=&quot;https://www.thecodedself.com/assets/images/ToastAnimation/example.gif&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;animating-the-transform&quot;&gt;Animating the transform&lt;/h2&gt;
&lt;p&gt;It’s generally a bad idea to modify a view’s frame just for the purpose of animation. We’ll animate the &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiview/1622459-transform&quot;&gt;transform&lt;/a&gt; instead. The responsibility of a view’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frame&lt;/code&gt; is setting the view’s place in the view hierarchy. The responsibility of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transform&lt;/code&gt; is to add any modifications to how the view should look to the user. You can modify the view’s transform to rotate it, scale it, or reposition it. We’re going to use it to reposition the view on the screen and animate that change.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@IBAction private func startToastAnimation(_ sender: Any) {
    
    let toastView = createToastView()
    view.addSubview(toastView)
    animate(toastView: toastView)
}

private func createToastView() -&amp;gt; UIView {
    // 1.
    let toastViewHeight = CGFloat(80)
    let toastView = UIView(frame: CGRect(x: view.frame.origin.x,
                                         y: -toastViewHeight,
                                         width: view.frame.width,
                                         height: toastViewHeight))
    toastView.backgroundColor = .green
    return toastView
}

private func animate(toastView: UIView) {
    
    UIView.animate(withDuration: 1.0, animations: {
        // 2.
        toastView.transform = toastView.transform
            .translatedBy(x: 0, y: toastView.frame.height)
    }, completion: { _ in
        // 3.
        UIView.animate(withDuration: 1.0, delay: 1.0, animations: {
            toastView.transform = CGAffineTransform.identity
        }, completion: { _ in
            // 4.
            toastView.removeFromSuperview()
        })
    })
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;1&quot;&gt;1.&lt;/h3&gt;

&lt;p&gt;Firstly, create the toast view. We position it above the current view by setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; position of its frame to be the negative of the view’s height. This will put it behind the navigation bar where the user can’t see it. It’s sneakily hiding behind the scenes until we animate it in.&lt;/p&gt;

&lt;h3 id=&quot;2&quot;&gt;2.&lt;/h3&gt;

&lt;p&gt;Translate the view’s transform by its height. A &lt;em&gt;translation&lt;/em&gt; is a change in position, similar to how a &lt;em&gt;rotation&lt;/em&gt; is a change in angle and a &lt;em&gt;scale&lt;/em&gt; is a change in size. You can do translation, rotation, and scale animations using the following three methods on the transform property:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translatedBy(x:y:)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rotated(by:)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scaledBy(x:y:)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the first step, we positioned the toast to be above the view by exactly its height. By adding a transform to move it downwards by its full height, we’ll bring the toast into position and make it appear as if it’s dropping out from behind the navigation bar.&lt;/p&gt;

&lt;h3 id=&quot;3&quot;&gt;3.&lt;/h3&gt;

&lt;p&gt;Once the animation to the view’s transform is completed, reverse the animation. It’s incredibly easy to reverse any animation on a view’s transform - just set the transform back to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CGAffineTransform.identity&lt;/code&gt;. This is the default, unmodified transform that all views are created with. After playing around with scales, rotations, and translations, you can get a view back into its comfort zone by resetting the transform back to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CGAffineTransform.identity&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;4&quot;&gt;4.&lt;/h3&gt;

&lt;p&gt;Once the reversal of the animation is completed, remove the view from the hierarchy. Depending on exactly what you’re animating, this step may not be necessary. For a toast view however, the view is meant to be transient, so I figured it would be best to respect that mental model of a transient toast and remove it from the view.&lt;/p&gt;

&lt;h1 id=&quot;where-to-go-from-here&quot;&gt;Where to go from here?&lt;/h1&gt;

&lt;p&gt;Play around with the timing of your animations using &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewanimationoptions&quot;&gt;UIViewAnimationOptions&lt;/a&gt;. You can make an animation ease in or out, or set it to repeat and run in reverse.&lt;/p&gt;

&lt;p&gt;And, when you feel ready to continue your journey to animation wizardry, start exploring &lt;a href=&quot;https://developer.apple.com/documentation/uikit/uiviewpropertyanimator&quot;&gt;UIViewPropertyAnimator&lt;/a&gt;. You can easily and concisely customise your animation’s timing, dynamically change its direction, and even make it user-interactable.&lt;/p&gt;

&lt;p&gt;Have fun, and happy Swifting!&lt;/p&gt;
</description>
          <pubDate>2017-08-31T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/iOS-Toast-View-Animation/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/iOS-Toast-View-Animation/</guid>
        </item>
      
    
      
        <item>
          <title>iOS: Working with Images from a Server</title>
          <description>&lt;p&gt;If you’re a mobile app developer, at some point in time you’re going to need to interact with a backend. One of the tasks you might need to do is to retrieve and display images from a server, or submit an image to that server. What format should the image be in when you’re submitting it? How do you convert bytes received from a service call into an image?&lt;/p&gt;

&lt;p&gt;Let’s build the entire stack from the server to an iOS App to find out how.&lt;/p&gt;

&lt;h1 id=&quot;setting-up-a-backend&quot;&gt;Setting up a backend&lt;/h1&gt;

&lt;p&gt;We’ll start off by building a &lt;a href=&quot;https://github.com/IBM-Swift/Kitura&quot;&gt;Kitura&lt;/a&gt; server that provides a RESTful API to do two things:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Receive images from a client&lt;/li&gt;
  &lt;li&gt;Provide the most recent image that was received to a client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve put the finished server up &lt;a href=&quot;https://github.com/TheCodedSelf/SwiftImageServer&quot;&gt;on my Github&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;create-the-server-project&quot;&gt;Create the server project&lt;/h3&gt;

&lt;p&gt;Make a directory, and init a new executable Swift package.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir mkdir SwiftImageServer &amp;amp;&amp;amp; cd SwiftImageServer
swift package init --type executable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit your Package.swift file to specify that you require the Kitura package.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;PackageDescription&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SwiftImageServer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/IBM-Swift/Kitura.git&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;majorVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can run a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift package fetch&lt;/code&gt; and you should see SwiftPM cloning Kitura and everything that it requires.&lt;/p&gt;

&lt;p&gt;Spin up a xcodeproj with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift package generate-xcodeproj&lt;/code&gt; and let’s get coding!&lt;/p&gt;

&lt;h3 id=&quot;create-a-kitura-server&quot;&gt;Create a Kitura server&lt;/h3&gt;

&lt;p&gt;The backend is going to be super simple, so we’ll just be working in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.swift&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s start off by adding all the boilerplate that we need:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Kitura&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foundation&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a Router that we can use to create REST endpoints&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Specify that we want an HTTP server that we can reach with http://localhost:8090&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;Kitura&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addHTTPServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;onPort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8090&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;// Start the server&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;Kitura&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I love how easy it is to create something these days. Three lines of code and you have a server running. It’s a shame that it can’t do much. Let’s fix that.&lt;/p&gt;

&lt;h3 id=&quot;returning-an-image-from-a-get-endpoint&quot;&gt;Returning an image from a GET endpoint&lt;/h3&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;latestImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// http://localhost:8090/latestImage&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/latestImage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;latestImage&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preconditionFailed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No image is available&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Wait a second!&quot; src=&quot;https://media.giphy.com/media/l0G18gptStsYQrcL6/giphy.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You thought we were sending images, you say? That looks like a Data object, &lt;strong&gt;not&lt;/strong&gt; a UIImage? That’s where the fun comes in. You never send an image &lt;strong&gt;as an image&lt;/strong&gt;. All images are simply &lt;strong&gt;data&lt;/strong&gt; packaged in an easy to use format. When we’re sending images to and from our server, we need to package it as a Data object and send that instead. We’ll represent it as a UIImage in our iOS app.&lt;/p&gt;

&lt;p&gt;Notice the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;guard let image = latestImage&lt;/code&gt;. That’ll fail until we set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latestImage&lt;/code&gt; variable. Let’s build the endpoint that receives an image, so we can set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latestImage&lt;/code&gt; variable.&lt;/p&gt;

&lt;h3 id=&quot;submitting-images-to-a-post-endpoint&quot;&gt;Submitting images to a POST endpoint&lt;/h3&gt;

&lt;p&gt;Next, we’ll build the endpoint that will be used to submit images.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Create a POST endpoint: http://localhost:8090/image&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/image&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Read the body of the request into the data object&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;latestImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Image received&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;internalServerError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Something went wrong when reading the image data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ve created an endpoint that expects a POST request with a raw body of the image data. Remember, the server only knows Data, not UIImage, so the iOS app is going to have to convert the image to a Data object.&lt;/p&gt;

&lt;p&gt;That’s our entire server done!&lt;/p&gt;

&lt;h3 id=&quot;up-and-running&quot;&gt;Up and running&lt;/h3&gt;

&lt;p&gt;Here’s a link to the completed server: &lt;a href=&quot;https://github.com/TheCodedSelf/SwiftImageServer&quot;&gt;https://github.com/TheCodedSelf/SwiftImageServer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the executable target. That’s the one with the Matrix-style computer screen, not the yellow lunchbox.&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Kitura server executable target&quot; src=&quot;https://www.thecodedself.com/assets/images/SwiftImageServer/RunTarget.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Keep that running, and we’ll build the iOS app.&lt;/p&gt;

&lt;h1 id=&quot;the-client-app&quot;&gt;The client app&lt;/h1&gt;

&lt;p&gt;The complete example code for the iOS app is available &lt;a href=&quot;https://github.com/thecodedself/LatestImageRetriever&quot;&gt;on my Github&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;create-the-project&quot;&gt;Create the project&lt;/h3&gt;

&lt;p&gt;Create a new Single View iOS Application. We’re going to need to modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Info.plist&lt;/code&gt;. We need permission to access the Photo Library to pick an image. We also need to modify the App Transport Security settings to make HTTP network requests, as opposed to HTTPS (our local Kitura server is HTTP).&lt;/p&gt;

&lt;p&gt;Add the following to the project’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Info.plist&lt;/code&gt;:&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Our changes to Info.plist&quot; src=&quot;https://www.thecodedself.com/assets/images/SwiftImageServer/Photo Library Permission.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;submitting-images-to-the-server&quot;&gt;Submitting images to the server&lt;/h3&gt;

&lt;p&gt;We’re going to add a button that’ll allow us to select an image from the photo gallery and submit it to the server we built earlier.&lt;/p&gt;

&lt;p&gt;We’ll start off by adding a button to the view controller in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Main.storyboard&lt;/code&gt;:&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;The view with a Pick Image button&quot; src=&quot;https://www.thecodedself.com/assets/images/SwiftImageServer/Pick Image Screenshot.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, hook it up to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewController.swift&lt;/code&gt; and add the code to post it to our backend.&lt;/p&gt;

&lt;p&gt;Let’s connect an IBAction to the ‘Pick Image’ button where we pick an image using a UIImagePickerController.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;@IBAction&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pickImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImagePickerController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isSourceTypeAvailable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;photoLibrary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;imagePickerController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImagePickerController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;imagePickerController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sourceType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;photoLibrary&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;imagePickerController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;present&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imagePickerController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;completion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re setting the ViewController as the UIImagePickerController’s delegate. Add an extension that conforms to the delegate protocol that also handles any picked images. Setting the delegate also requires conformance to UINavigationControllerDelegate, so add that in as well.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ViewController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImagePickerControllerDelegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UINavigationControllerDelegate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;imagePickerController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;picker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImagePickerController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;didFinishPickingMediaWithInfo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UIImagePickerControllerOriginalImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UIImagePickerControllerEditedImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;picker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dismiss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;animated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can select an image, and we’re ready to handle it. Notice the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;submit(image:)&lt;/code&gt; function in the above example. We’ll create that function now, and submit the image to our server.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSessionConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:8090/image&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpMethod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;POST&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpBody&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImagePNGRepresentation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dataTask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dataTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Something went wrong: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Response: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;dataTask&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;receiving-an-image-from-the-server&quot;&gt;Receiving an image from the server&lt;/h3&gt;

&lt;p&gt;Now that we have the ability to submit images as Data objects, we need to build in the functionality to receive an image as Data and convert it to a plain old UIImage.&lt;/p&gt;

&lt;p&gt;Start by adding an image view and another button to the view controller in Main.storyboard:&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Button and image view for receiving image from our server&quot; src=&quot;https://www.thecodedself.com/assets/images/SwiftImageServer/Completed Storyboard.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When the user taps on the new button we’ll call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latestImage&lt;/code&gt; endpoint to retrieve the last image that was sent to our server as a Data object. We’ll then convert it to a UIImage and display it in the image view.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;@IBOutlet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;imageView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;@IBAction&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showLatestImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSessionConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:8090/latestImage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpMethod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;GET&quot;&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dataTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Something went wrong: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;imageData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imageView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imageData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking good. You completed ViewController should look like this one: &lt;a href=&quot;https://github.com/TheCodedSelf/LatestImageRetriever/blob/master/LatestImageRetriever/ViewController.swift&quot;&gt;https://github.com/TheCodedSelf/LatestImageRetriever/blob/master/LatestImageRetriever/ViewController.swift&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;a-finished-product&quot;&gt;A Finished Product&lt;/h1&gt;

&lt;p&gt;Here’s our app that has submitted an image to the server and pulled an image from the server to display.&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Finished Product&quot; src=&quot;https://www.thecodedself.com/assets/images/SwiftImageServer/FinishedProduct.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you tap on Pick Image, you’re presented with a UIIImagePickerController that allows you to select an image from the Photos Library, and submits it to our backend after converting it to a Data object. The Show Latest Image button does a GET request to our server to retrieve the last image that was sent, converts it to a UIImage, and then displays it in our UIImageView.&lt;/p&gt;

&lt;p&gt;You should now have a basic understanding of how to send objecs besides text to a server - and how to retrieve them. Congratulations!&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Congrats!&quot; src=&quot;https://media.giphy.com/media/Wrv5v6egIh7Ww/giphy.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Have fun, and happy Swifting!&lt;/p&gt;
</description>
          <pubDate>2017-07-04T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Swift-Send-Image-To-Server/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Swift-Send-Image-To-Server/</guid>
        </item>
      
    
      
        <item>
          <title>Vim and Swift: Development in a post-apocalyptic world</title>
          <description>&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/VimSwift/BunkerTerminal.png&quot; alt=&quot;Vim and Swift&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I don’t advocate using Vim seriously as your primary development environment. As powerful as it is, Vim remains a text editor, &lt;strong&gt;not an IDE&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I ran into some Xcode problems the other day where I lost syntax highlighting and code completion in Swift files. What should we do when Xcode just doesn’t work?&lt;/p&gt;

&lt;p&gt;I joked that at this point, it might be easier to just use Vim for my Swift development. 
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Well…
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Vim and Swift? Challenge Accepted.&quot; src=&quot;https://www.thecodedself.com/assets/images/VimSwift/challenge-accepted.jpeg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;It’s not hard to use an arbitrary text editor to write some code and then run it through a compiler. For this setup, we want something a little bit more pleasant to use. The passionate programmers that we are, we want to be able to work on non-trivial Swift projects, with or without Xcode, from the comfort of our own home or in a post-apocalyptic nuclear bunker (hey, let’s not rule anything out).&lt;/p&gt;

&lt;p&gt;We want:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Those sweet Vim keybindings&lt;/li&gt;
  &lt;li&gt;An easy way to compile and run code&lt;/li&gt;
  &lt;li&gt;Resilience against Xcode temper tantrums&lt;/li&gt;
  &lt;li&gt;Syntax highlighting that works. All. The. Time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll be using some Vim plugins. You’ll need some means of plugin management. I’ll be using &lt;a href=&quot;https://github.com/tpope/vim-pathogen&quot;&gt;Pathogen&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;syntastic&quot;&gt;Syntastic&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vim-syntastic/syntastic&quot;&gt;Syntastic&lt;/a&gt; provides syntax highlighting in Vim for many languages. It does this by associating &lt;em&gt;checkers&lt;/em&gt; with a particular language. When you save the file you’re working on, it runs the appropriate checkers. A checker is essentially an adapter between the world of Vim with Syntastic and your language with its compiler or linter. What we want to accomplish through Syntastic is to easily compile a project  when the current file is saved and surface any errors or warnings inside Vim.&lt;/p&gt;

&lt;p&gt;Using Pathogen, install Syntastic.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~/.vim/bundle &amp;amp;&amp;amp; \
git clone --depth=1 https://github.com/vim-syntastic/syntastic.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;swiftvim&quot;&gt;swift.vim&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/keith/swift.vim&quot;&gt;swift.vim&lt;/a&gt; has a SwiftPM checker that will compile a project and a &lt;a href=&quot;https://github.com/realm/SwiftLint&quot;&gt;SwiftLint&lt;/a&gt; checker to remind us that we occasionally have no idea what we’re doing.&lt;/p&gt;

&lt;p&gt;Install swift.vim:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~/.vim/bundle &amp;amp;&amp;amp; \
git clone --depth=1 https://github.com/keith/swift.vim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;swiftpm&quot;&gt;SwiftPM&lt;/h3&gt;

&lt;p&gt;Go to a Swift project containing a Package.swift (The manifest file for SwiftPM) and open a Swift file in Vim. Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:SyntasticInfo&lt;/code&gt; and you should see some output from Syntastic:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/VimSwift/SyntasticInfoSwift.png&quot; alt=&quot;Vim Syntastic :SyntasticInfo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The important tidbit here is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swiftpm&lt;/code&gt; checker is available and enabled. This means that when we save the file, it’ll run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift build&lt;/code&gt; to build the package.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/VimSwift/Syntastic SwiftPM Checker.png&quot; alt=&quot;Vim Syntastic Swift Package Manager checker&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;swiftlint&quot;&gt;SwiftLint&lt;/h3&gt;

&lt;p&gt;To get the SwiftLint checker working, we need to start off with: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew install swiftlint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to configure SwiftLint to your tastes, you’ll need to add a .swiftlint.yml file to your Swift project to get the syntax checker working. Or, if you’re happy with the global default, add this to your .vimrc:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let g:syntastic_swift_swiftlint_use_defaults = 1 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Adding that will let you have some awesome linting without needing to add a configuration file to every project.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/VimSwift/Syntastic SwiftLint Checker.png&quot; alt=&quot;Vim Swift SwiftLint checker&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you tried this in a project that has the SwiftPM checker enabled, you might run into a slight problem: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:SyntasticInfo&lt;/code&gt; notes both the SwiftPM checker and the SwiftLint checker as available, but neither are enabled. Add the following to your .vimrc to enable both:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let g:syntastic_swift_checkers = ['swiftlint', 'swiftpm'] 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;individual-swift-files&quot;&gt;Individual Swift Files&lt;/h3&gt;
&lt;p&gt;SwiftPM is great, but sometimes it’s a little bit much when I want to create a short script. I created a Syntastic checker that will work a single Swift file to run the script when you save it and show any errors inside Vim.&lt;/p&gt;

&lt;p&gt;Install &lt;a href=&quot;https://github.com/TheCodedSelf/syntastic-swift&quot;&gt;syntastic swift&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~/.vim/bundle &amp;amp;&amp;amp; \
git clone --depth=1 https://github.com/TheCodedSelf/syntastic-swift.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’re only working on a single Swift file, you can use this checker - no need to go through the hassle of setting up SwiftPM. Just remember to add the checker in your .vimrc if necessary:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let g:syntastic_swift_checkers = ['swiftlint', 'swiftpm'] 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately, while the checker will surface any errors in Vim, it doesn’t show any output from running the Swift script. I added a mapping to my .vimrc to sort this out:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nnoremap &amp;lt;leader&amp;gt;sb :!swift %&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By hitting my &lt;a href=&quot;http://learnvimscriptthehardway.stevelosh.com/chapters/06.html&quot;&gt;leader key&lt;/a&gt; followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sb&lt;/code&gt;, the current script will run and you’ll be able to see any output.&lt;/p&gt;

&lt;h2 id=&quot;moving-forward&quot;&gt;Moving Forward&lt;/h2&gt;
&lt;p&gt;You can compile SwiftPM projects, run Swift scripts, and use SwiftLint to patch up your mistakes, all while remaining in the warm embrace of Vim.&lt;/p&gt;

&lt;p style=&quot;text-align:center&quot;&gt;&lt;img alt=&quot;Impressive&quot; src=&quot;https://www.thecodedself.com/assets/images/VimSwift/impressive.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The next time you’re having troubles with Xcode, or if you just want to practice your &lt;em&gt;Vim-fu&lt;/em&gt;, why not take this a bit further?&lt;/p&gt;

&lt;p&gt;Have fun, and remember: learning is living.&lt;/p&gt;
</description>
          <pubDate>2017-06-22T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Vim-Swift/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Vim-Swift/</guid>
        </item>
      
    
      
        <item>
          <title>Your Other Job</title>
          <description>&lt;p&gt;You are the CEO of a company.&lt;/p&gt;

&lt;p&gt;There is no board of directors. The fate of the company lies solely on you.&lt;/p&gt;

&lt;p&gt;Every day, you make decisions that determine the success of the company. Some days you might make good decisions, and some days you won’t.&lt;/p&gt;

&lt;p&gt;You might have some trusted advisors that guide you in your role as CEO. But it’s not their job to lead the company to success, it’s yours. You can take their advice or you can ignore it, but it’s important for you to remember that it’s your choice, and your responsibility.&lt;/p&gt;

&lt;h2 id=&quot;the-company-is-yourself&quot;&gt;The company is &lt;em&gt;yourself&lt;/em&gt;.&lt;/h2&gt;

&lt;p&gt;Each of us make decisions throughout our lives that have the power to guide the direction that we take. You decide how to spend your spare time, what career path to follow, what projects to work on. You decide when to rest and when to keep working. Remember that each action that you take is tallied into whether or not the company becomes successful.&lt;/p&gt;
</description>
          <pubDate>2017-06-05T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Your-Other-Job/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Your-Other-Job/</guid>
        </item>
      
    
      
        <item>
          <title>Half-Baked Solutions to Common RxSwift Problems</title>
          <description>&lt;p&gt;I’ve been using &lt;a href=&quot;https://github.com/ReactiveX/RxSwift&quot;&gt;RxSwift&lt;/a&gt; in some of my latest iOS projects. While I feel that it’s provided elegant UI binding and a natural feel to asynchronous programming, I have to admit that it came with numerous growing pains. I struggled to find documented solutions to some of the challenges I was facing, as RxSwift is not as widely adopted as its more affluent Java and .Net counterparts. Here are some of those hurdles that I faced, along with my solutions.&lt;/p&gt;

&lt;h2 id=&quot;why-cant-i-access-the-tap-method-of-my-uibutton&quot;&gt;Why can’t I access the tap method of my UIButton?&lt;/h2&gt;

&lt;p&gt;One of the greatest benefits of Rx is its UI binding capabilities. So you must imagine how peeved off I was when I couldn’t do something as simple as bind some logic to taps on a UIButton. Luckily, the solution is just as simple as the problem.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import UIKit
import RxSwift
import RxCocoa

let button = UIButton()
button.rx.tap.bind {
    print(&quot;That wasn't too hard, was it?&quot;)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See that sneaky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import RxCocoa&lt;/code&gt; at the top there? RxSwift functionality relating to UIKit is found in the RxCocoa module. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rx&lt;/code&gt; property on UIButton that I’m using in the snippet comes from RxCocoa. You can find it on most UIKit objects. It’s what powers RxSwift’s interaction with UIButton, UITableView, UIImageView, and all of the other usual suspects. You can find an RxSwift extension on most UIKit objects - just look out for the object plus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Rx.swift&lt;/code&gt; - e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITableView+Rx.swift&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-combine-the-output-from-multiple-observables-into-one&quot;&gt;How do I combine the output from multiple observables into one?&lt;/h2&gt;

&lt;p&gt;If you have data from multiple sources, and want to treat them as one, you need to merge them.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let cars = Observable.from([&quot;Nissan&quot;, &quot;Ford&quot;, &quot;BMW&quot;])
let tanks = Observable.from([&quot;Tiger II&quot;, &quot;T-44&quot;, &quot;Panther&quot;])
let bikes = Observable.from([&quot;Ducati&quot;, &quot;Honda&quot;, &quot;Kawasaki&quot;])

let landVehicles = Observable.of(cars, tanks, bikes).merge()

landVehicles.subscribe(onNext: { print($0) })

/* Output:
Nissan
Ford
Tiger II
BMW
T-44
Ducati
Panther
Honda
Kawasaki
*/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First, we combine the three observables using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;of&lt;/code&gt;. You can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;of&lt;/code&gt; operator on any list of items to create an Observable from said items. Used here, it gives us an Observable of Observables.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;merge&lt;/code&gt; operator is used to flatten out an Observable of Observables. We use it to create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;landVehicles&lt;/code&gt; observable, which is an Observable of Strings.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-make-one-observable-depend-on-another&quot;&gt;How do I make one observable depend on another?&lt;/h2&gt;

&lt;p&gt;I have one observable that initiates a service call when I subscribe to it. However, I only want to execute that service call if my view passes validation successfully. I have another observable that returns an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt; event if validation fails. If the validation observable submits an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt; event, the service call observable should not execute.&lt;/p&gt;

&lt;p&gt;Here’s the solution that I came up with:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;func submit(number: Int) {
    let validateAndPerformServiceCallIfSuccessful =
        performValidation(numberThatShouldBeEven: number)
            .flatMap { () -&amp;gt; Observable&amp;lt;Void&amp;gt; in // 1
                print(&quot;Validated successfully&quot;)
                return performServiceCall() // 2
    }
    
    validateAndPerformServiceCallIfSuccessful.subscribe(onNext: { _ in
        print(&quot;Service call was a success!&quot;)
    }, onError: { _ in
        print(&quot;Something went wrong.&quot;)
    })
}

private func performValidation(numberThatShouldBeEven: Int) -&amp;gt; Observable&amp;lt;Void&amp;gt; {
    if numberThatShouldBeEven % 2 == 0 {
        print(&quot;Validation succeeded.&quot;)
            return Observable.just(())
    } else {
        print(&quot;Validation failed.&quot;)
        let error = NSError(domain: &quot;com.thecodedself.rxswift&quot;,
                            code: 0,
                            userInfo: nil)
        return Observable.error(error)
    }
}

private func performServiceCall() -&amp;gt; Observable&amp;lt;Void&amp;gt; {
    print(&quot;Performing service call&quot;)
    return Observable.just(()) 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If an even number is passed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;submit&lt;/code&gt; function, the service call is executed. If the validation fails, an error message is printed on the screen.&lt;/p&gt;

&lt;p&gt;Here’s an explanation of what’s happening:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; over the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;performValidation&lt;/code&gt; observable. When you flatmap an observable, any time the observable sends a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; event, your closure will execute and you’ll return another observable. If the observable that you’re flatmapping sends a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;completed&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt; event, the observable is finished executing - that means no service call.&lt;/li&gt;
  &lt;li&gt;Any time the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;performValidation&lt;/code&gt; observable sends a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; event, return the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;performServiceCall&lt;/code&gt; observable. What this means is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validateAndPerformServiceCallIfSuccessful&lt;/code&gt; observable will send an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;completed&lt;/code&gt; event if either performValidation or performServiceCall send an error or competed event. The meat of it lies in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; closure - if the performValidation observable sends a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; event, the performServiceCall observable gets to do its thing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern does seem complex, but it can be insanely powerful once you learn it and use it to your advantage.&lt;/p&gt;

&lt;h2 id=&quot;testing-with-rxswift-is-horrible-how-can-i-make-it-less-horrible&quot;&gt;Testing with RxSwift is horrible. How can I make it less horrible?&lt;/h2&gt;

&lt;p&gt;Well, that’s a very valid point. Testing against the RxSwift framework can be difficult on its own, involving asynchronicity and a lot of complex logic in your tests. Luckily, we have &lt;em&gt;RxBlocking&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;RxBlocking is a library in the same GitHub repository as RxSwift. If you’re using Cocoapods, just add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pod 'RxBlocking'&lt;/code&gt; to your test target.&lt;/p&gt;

&lt;p&gt;No dealing with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TestSchedulers&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XCTestExpectations&lt;/code&gt;. If you can work with an array, you can work with RxBlocking.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class FibonacciFinderTests: XCTest {
    
func testThatThreeFollowingFibonacciNumbersAreReturned() {
    let expectedNumbers = [13, 21, 34]
    
    guard let actualNumbers = try? FibonacciFinder().findThreeFollowing(number: 9)
        .toBlocking()
        .toArray() else {
            XCTFail()
            return
    }
    
    XCTAssertEqual(expectedNumbers, actualNumbers)
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above snippet tests the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findThreeFollowing&lt;/code&gt; function on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FibonacciFinder&lt;/code&gt; class, which, given a number, should return the first three numbers that follow it in the fibonacci sequence.&lt;/p&gt;

&lt;p&gt;Calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toBlocking&lt;/code&gt; on an observable returns a &lt;em&gt;Blocking Observable&lt;/em&gt;, which is an observable with added functionality to block your thread of execution so that you can test it without having to worry about asynchronicity. We then call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toArray&lt;/code&gt;, which handles subscribing to the observable and returning any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; events neatly packaged in an array for us for easy of testing. Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toArray&lt;/code&gt; can throw exceptions, which is why we have the try statement and a guard clause.&lt;/p&gt;

&lt;h1 id=&quot;still-a-lot-more-to-learn&quot;&gt;Still a lot more to learn&lt;/h1&gt;

&lt;p&gt;As I write more RxSwift code, and occasionally run into barriers, I learn a little bit more about the library and improve the quality and readability of my reactive solutions. It’s tough in the beginning, but as you get more comfortable, RxSwift starts to show its utility. Don’t be afraid to dive in and read the implementation code and try different things.&lt;/p&gt;

&lt;p&gt;Enjoy your Swifting!&lt;/p&gt;
</description>
          <pubDate>2017-05-23T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Half-Baked-Solutions-To-Common-RxSwift-Problems/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Half-Baked-Solutions-To-Common-RxSwift-Problems/</guid>
        </item>
      
    
      
        <item>
          <title>Lessons Learned From The Entelect Way</title>
          <description>&lt;p&gt;Software engineering and coding are two very different concepts. As a software engineer, I write code on a daily basis, but the value that a good software engineer provides to a business is so much more. This is emphasised by The Entelect Way.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-entelect-way&quot;&gt;What is The Entelect Way?&lt;/h2&gt;

&lt;p&gt;I’m a software engineer at &lt;a href=&quot;http://www.entelect.co.za/&quot;&gt;Entelect&lt;/a&gt;, a software engineering and solutions company based in South Africa. The Entelect Way is a set of guiding principles for software delivery that can be used to help guide your decisions, activities, and behaviour as a professional software engineer. The principles are broken down into the following areas of focus:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Agile Planning and Development&lt;/li&gt;
  &lt;li&gt;Software Engineering Quality Practices&lt;/li&gt;
  &lt;li&gt;Individual Growth&lt;/li&gt;
  &lt;li&gt;Team Engagement&lt;/li&gt;
  &lt;li&gt;Relationships&lt;/li&gt;
  &lt;li&gt;Value Adding Activities&lt;/li&gt;
  &lt;li&gt;First Class Service Delivery&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-workshop&quot;&gt;The Workshop&lt;/h2&gt;
&lt;p&gt;A few weeks ago, my team attended a workshop on The Entelect Way with a few teams based at other clients. We took a deeper look at each of the principles and were encouraged to find ways to apply these principles in our day to day activities.&lt;/p&gt;

&lt;h3 id=&quot;our-findings&quot;&gt;Our Findings&lt;/h3&gt;
&lt;p&gt;We were asked to discuss &lt;strong&gt;Value Adding Activities&lt;/strong&gt;. We chatted about each team’s strengths and weaknesses around the points raised during the workshop. I realized what our team does well - and where we need some major improvement. While we didn’t stay entirely on topic of Value Adding Activities, we did manage to learn a lot from each other that we then compiled into a list. Here’s the best picks across our three teams:&lt;/p&gt;

&lt;h3 id=&quot;focus-on-your-clients-why&quot;&gt;Focus on your client’s ‘why’&lt;/h3&gt;
&lt;p&gt;You can take action on your client’s &lt;em&gt;what&lt;/em&gt;, or you can take action on their &lt;em&gt;why&lt;/em&gt;. Try to find the why, and use that as your guide.&lt;/p&gt;

&lt;p&gt;Imagine you’re fetching data from a service and displaying that to the user. If someone asks you to attempt to make the service call three times in the case of failure before displaying an error message, they’re asking for the &lt;em&gt;what&lt;/em&gt;. The &lt;em&gt;why&lt;/em&gt; is likely to be something along the lines of “I don’t want the user to visually experience errors when the server goes down”. Now that you know what they hope to achieve, you know that your task is to build more resilience into the app and reduce downtime. You as a knowledge worker likely know the best approach to achieve this, and you can use your experience to solve the client’s actual need.&lt;/p&gt;

&lt;h3 id=&quot;communicate-constantly-to-understand-your-clients-intention&quot;&gt;Communicate constantly to understand your client’s intention&lt;/h3&gt;
&lt;p&gt;This is pretty much the crux of agile software development. How do you know that you’re building a product that will give the client the most possible value? You communicate. Constantly. Raise concerns. Show progress. Share ideas. If you open up that dialogue, your client will happily communicate back and share what they really had in mind. This level of communication will get you on the same wavelength.&lt;/p&gt;

&lt;h3 id=&quot;commit-to-your-own-work&quot;&gt;Commit to your own work&lt;/h3&gt;
&lt;p&gt;There’s nothing worse than giving an estimate and seeing it being ignored. When you’re asked to commit to goals that you don’t see as feasible, it leads to demotivation and shoddy results.&lt;/p&gt;

&lt;p&gt;Emphasize the importance of taking responsibility of your own estimates and commitments. Rather than being forced to take on work that you didn’t sign up for, you now have the motivation and autonomy of playing a pivotal role in reaching an objective that you helped to set.&lt;/p&gt;

&lt;h3 id=&quot;use-deadlines-to-your-advantage&quot;&gt;Use deadlines to your advantage&lt;/h3&gt;
&lt;p&gt;A deadline doesn’t need to be a negative thing. It defines the expectation that is laid on you and, when realistic, can be an effective measuring stick for you to gauge the value that you are providing to your company.&lt;/p&gt;

&lt;p&gt;By pacing yourself against a deadline, you’ll have an end goal that you work towards. The satisfaction from meeting a realistic deadline that you’ve committed to can be a great motivator towards reaching the next deadline.&lt;/p&gt;

&lt;h3 id=&quot;make-use-of-the-rhythm-of-sprints&quot;&gt;Make use of the rhythm of sprints&lt;/h3&gt;
&lt;p&gt;Sprints provide a good set routine for you to find time for other value-adding activities. By ringfencing a chunk of work to the boundaries of a sprint, you provide time for activities such as reducing tech debt, setting up build automation, and finding ways to improve the way your team works on a daily basis. Use the quiet time provided by the cadence of a sprint to focus on ways to improve.&lt;/p&gt;

&lt;h2 id=&quot;do-more-than-just-code&quot;&gt;Do more than just code&lt;/h2&gt;
&lt;p&gt;A set of principles like those found in The Entelect Way helps one to realize that there is more to software development than just writing code. There are a lot of areas of concern that we need to focus on before we can define ourselves as true professionals. Following some guidelines and making deliberate effort towards putting them into practice is how we can provide true value: whether for a client, for your company, or for yourself.&lt;/p&gt;
</description>
          <pubDate>2017-05-08T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Lessons-Learned-From-The-Entelect-Way/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Lessons-Learned-From-The-Entelect-Way/</guid>
        </item>
      
    
      
        <item>
          <title>Android Development Through the Eyes of an iOS Developer</title>
          <description>&lt;p&gt;I’ve recently dipped my toes into Android development to see the differences in environment and tooling as compared to iOS development. While I haven’t done much as of yet, I hope to ship some Android apps in the future alongside some iOS ones. I figured it was time to understand the platform so that I can better relate to the woes of Android development.&lt;/p&gt;

&lt;h3 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;Note that this is entirely opinion based, and these are only initial opinions. Understanding of any language or SDK fleshes out over time, and I’m looking forward to see how my understanding and opinions change as I write more and more Android code.&lt;/p&gt;

&lt;h2 id=&quot;the-findings&quot;&gt;The Findings&lt;/h2&gt;
&lt;p&gt;I expected to see much more boilerplate and repetitive code as opposed to iOS, where we have the ability for frameworks to be more powerful and simple at the same time by tapping into the Objective-C runtime. While this was true to some extent, I’d like to talk more about some of the other differences I noticed:&lt;/p&gt;

&lt;h3 id=&quot;ide&quot;&gt;IDE&lt;/h3&gt;
&lt;p&gt;If you’re ever used a Jetbrains IDE or plugin, you’ll love Android Studio. It’s such a pleasure having the platform’s standard IDE being one by Jetbrains. I’ve been burned by Xcode too many times, namely due to bugs and lack of refactoring tools, and I for one am quite pleased with Android Studio.&lt;/p&gt;

&lt;h3 id=&quot;activities-vs-viewcontrollers&quot;&gt;Activities vs ViewControllers&lt;/h3&gt;
&lt;p&gt;Where you’d use a UIViewController in iOS, you’re using Activities in Android. While passing data through Intents is not perfect in my eyes, I prefer it to using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prepareForSegue&lt;/code&gt; method on iOS to see if the segue identifier matches the one you expect and then configuring the destination view controller. However, if you don’t need to pass data around, I must say that handling all your segues in a Storyboard without writing any code is very convenient.&lt;/p&gt;

&lt;h3 id=&quot;supporting-different-platforms-and-devices&quot;&gt;Supporting different platforms and devices&lt;/h3&gt;
&lt;p&gt;I’m starting to see that we have it so easy on iOS when it comes to supporting other devices. There’s an almost unlimited number of hardware and screen size combinations for Android. Many iOS developers can name almost every possible device that their apps can run on out of the top of their heads, and that’s not something to take for granted. On Android I can see a need for a few if statements like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.HONEYCOMB)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On iOS, the amount of versioning checks is considerably less due to the practice of only supporting version N-1 (meaning today, I would support iOS 10 and iOS 9, but drop any support for iOS 8). This is a luxury that Android does not have.&lt;/p&gt;

&lt;h3 id=&quot;localization&quot;&gt;Localization&lt;/h3&gt;
&lt;p&gt;Android specifies string resources in XML. Specific locales are XML files with the ISO country code in the name. iOS has a similar structure but with a nasty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.strings&lt;/code&gt; file instead of XML where standard practice is to specify strings like the following:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;“home.loggedin.title” = “Hello, World!”;&lt;/code&gt;
or even worse:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;“Hello, World!” = “Hello, World!”;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In use:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;myLabel.text = NSLocalizedString(“Hello, World!&quot;, comment: “&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What I like about Android is that it’s strongly typed.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;textView.setText(R.string.hello_world);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;navigation&quot;&gt;Navigation&lt;/h3&gt;
&lt;p&gt;The first project that I built while trying to learn Android was an activity with a text field and a button.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AndroidForiOSDevelopers/Android First Activity.png&quot; alt=&quot;Android First Activity&quot; title=&quot;Android First Activity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you tapped on the button, you’d be presented with another activity with a label that contained the text from the previous activity’s text field.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AndroidForiOSDevelopers/Android Second Activity.png&quot; alt=&quot;Android Second Activity&quot; title=&quot;Android Second Activity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I was quite pleased with myself until I realized that I had forgotten to put in a navigation bar to get back to the first activity. Ugh, now I have to figure out how to embed everything in a navigation bar. How do you even make a navigation bar in Android? It took me a few seconds before I remembered that Android devices always have a back button. Lo and behold, a functional navigation hierarchy without implementing a UINavigationBar! Feel my power!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AndroidForiOSDevelopers/Feel My Power.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;dynamic-views&quot;&gt;Dynamic Views&lt;/h3&gt;
&lt;p&gt;Activities can contain Fragments, which is sort of like a ViewController containing multiple ViewControllers as children and receiving all lifecycle calls that the Activity receives. You can easily add Fragments to an Activity in XML or in code using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FragmentManager&lt;/code&gt; class.  No messing with Storyboards and Nibs and making sure that you correctly tie everything up!&lt;/p&gt;

&lt;p class=&quot;center&quot;&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/AndroidForiOSDevelopers/homer_simpson_woohoo-300x190.jpeg&quot; alt=&quot;Dynamic Views on Android&quot; title=&quot;Dynamic Views on Android&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The Android Developer training documentation shows how you can get the behavior of a UISplitViewController that shows two views on a tablet, but uses a navigation hierarchy to navigate between the two views on smaller devices:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://developer.android.com/images/training/basics/fragments-screen-mock.png&quot; alt=&quot;Android Fragment UISplitViewController comparison&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Except with Fragments, you’re not limited to that layout.&lt;/p&gt;

&lt;h3 id=&quot;storing-data&quot;&gt;Storing Data&lt;/h3&gt;
&lt;p&gt;You may whine about Core Data now, but there’s nothing in Android stopping you from executing arbitrary SQL queries. You have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SQLiteOpenHelper&lt;/code&gt; class to guide you but other than that it’s pretty much up to you to manage your database. At least we now have &lt;a href=&quot;https://realm.io/products/realm-mobile-database/&quot;&gt;Realm&lt;/a&gt; on both platforms to help us overcome the database nightmare.&lt;/p&gt;

&lt;h2 id=&quot;android-development-going-forward&quot;&gt;Android Development Going Forward&lt;/h2&gt;

&lt;p&gt;Why would an iOS developer want to learn Android development?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;They capture the majority of the market, especially in developing countries&lt;/li&gt;
  &lt;li&gt;Users expect apps to be available on both iOS and Android&lt;/li&gt;
  &lt;li&gt;It’s a natural way to expand your skill set: a new language and SDK, but still the same mobile paradigm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m excited to take on more Android development going forward.&lt;/p&gt;
</description>
          <pubDate>2017-03-16T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Android-Development-Through-the-Eyes-of-an-iOS-Developer/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Android-Development-Through-the-Eyes-of-an-iOS-Developer/</guid>
        </item>
      
    
      
        <item>
          <title>Using Multiple Author Identities With Git</title>
          <description>&lt;p&gt;How do you manage git credentials for different organizations? You may have some projects you work on at work that has a pre-push hook to ensure that your email is part of the correct domain. You might have your own personal projects, some of which might also use difference email addresses. Or, just maybe, you have a secret identity that you don’t want your other repositories to know about. How does one manage this schizophrenic multiple personality disorder that we call Version Control?&lt;/p&gt;

&lt;p&gt;If I commit with the wrong email at work, I won’t be allowed to push to our internal Bitbucket server. If I commit with the wrong email on one of my personal Github repositories, I end up with this ugly situation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/GitCommitEmails/Github_Commit_History.png&quot; alt=&quot;Github commit history&quot; title=&quot;Github commit history&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The commits that don’t have my image were made with my name but with an &lt;strong&gt;unknown email&lt;/strong&gt;. So GitHub doesn’t know that it was really me and does not link it to my Github identity. What I need to do is to tell git to use the email that Github expects.&lt;/p&gt;

&lt;h2 id=&quot;how-to-assume-multiple-identities&quot;&gt;How to assume multiple identities&lt;/h2&gt;
&lt;p&gt;Git commits have an author with a name and an email. Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git log&lt;/code&gt; in a repository you’ve committed to recently to see some of the metadata of your commits:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;commit bd294498cbd5c67b51096518ce62c9204068be2c
Author: Bruce Wayne &amp;lt;bruce.wayne@wayneenterprises.com&amp;gt;
Date:   Tue Feb 14 19:58:34 2017 +0200

    Plan attendance to charity events
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Git uses the user name and email set in your global .gitconfig file, located at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.gitconfig&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Users\MyUser\.gitconfig&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[user]&lt;/code&gt; block sets the author name and email address for all commits. You can set it by manually editing the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ vim ~/.gitconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[user]
        name = &quot;Bruce Wayne&quot;
        email = &quot;bruce.wayne@wayneenterprises.com&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Git also provides a command to update global settings.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git config --global user.name &quot;Bruce Wayne&quot;
$ git config --global user.email bruce.wayne@wayneenterprises.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This modifies the global .gitconfig for you.&lt;/p&gt;

&lt;h3 id=&quot;specifying-identities-at-the-repository-level&quot;&gt;Specifying identities at the repository level&lt;/h3&gt;
&lt;p&gt;So now that you’ve created your global identity, how about adding a different one for a particular repository? Each repository has its own config file in which you can override the global configurations - it’s located in the hidden .git folder. Take a look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/config&lt;/code&gt; inside your repository.&lt;/p&gt;

&lt;p&gt;To create your repository-specific secret identity, edit the file and add a user config to override the global one:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ vim ~/.gitconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or, you can run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git config&lt;/code&gt; command and specify the change as being local to the repository.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git config --local user.name &quot;Batman&quot;
$ git config --local user.email &quot;batman@justiceleague.com&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the configuration that you should end up with in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/config&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[user]
        name = &quot;Bruce Wayne&quot;
        email = &quot;bruce.wayne@wayneenterprises.com&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, you can use Git under your secret identity!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Author: Batman &amp;lt;batman@justiceleague.com&amp;gt;
Date:   Wed Feb 15 04:53:57 2017 +0200

    Create initial blueprints for Batcave
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;thats-too-late-for-me-ive-already-committed-with-the-wrong-author-email&quot;&gt;That’s too late for me, I’ve already committed with the wrong author email!&lt;/h2&gt;
&lt;p&gt;Sometimes you make a mistake, like this one here:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Author: Bruce Wayne &amp;lt;bruce.wayne@wayneenterprises.com&amp;gt;
Date:   Thurs Feb 16 19:21:35 2017 +0200

    Fight crime in downtown Gotham
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With a commit author like that, Batman’s secret identity is surely at risk of being compromised. Luckily, you still have the opportunity to modify this commit before you push it upstream.&lt;/p&gt;

&lt;h4 id=&quot;warning&quot;&gt;Warning&lt;/h4&gt;
&lt;p&gt;All of the suggestions listed below &lt;strong&gt;modify your git history&lt;/strong&gt;. This means that if you’ve already pushed your changes upstream, you’ll have to &lt;a href=&quot;http://movingfast.io/articles/git-force-pushing/&quot;&gt;force push&lt;/a&gt; your changes. Even worse, if the changes are upstream and another developer has been working on that branch with the commits that you’re about to change, things can get really tricky. The safest decision is to refrain from modifying commits that are already publicly visible to other developers.&lt;/p&gt;

&lt;h3 id=&quot;amend-the-latest-commit&quot;&gt;Amend the latest commit&lt;/h3&gt;
&lt;p&gt;If the commit that you need to change is the most recent commit, you can easily change it like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git commit --amend --author=&quot;Author Name &amp;lt;authoremail@example.com&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit --amend&lt;/code&gt; allows you to change the commit message if you choose to, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--author=&quot;Author Name &amp;lt;authoremail@example.com&amp;gt;&quot;&lt;/code&gt; part sets the author name and email to whatever you’ve specified.&lt;/p&gt;

&lt;p&gt;You can use it to modify the previous commit to the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Author: The Dark Knight &amp;lt;batman@justiceleague.com&amp;gt;
Date:   Thurs Feb 16 19:21:35 2017 +0200

    Fight crime in downtown Gotham
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even Batman needs a helping hand sometimes.&lt;/p&gt;
&lt;h3 id=&quot;interactive-rebase&quot;&gt;Interactive rebase&lt;/h3&gt;
&lt;p&gt;One of my favourite tricks, the interactive rebase, can be used to commits other than the most recent one. &lt;a href=&quot;http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html&quot;&gt;This tutorial&lt;/a&gt; should get you up to speed with how to do a rebase.&lt;/p&gt;

&lt;p&gt;To amend commit authors, we run an interactive rebase, specify to edit the commits that we want to change, and then run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit --amend --author&lt;/code&gt; command we used previously to edit the commit’s author.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git rebase -i head~4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ve started an interactive rebase. We’ll be presented with a text editor containing the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pick fe79802 Buy new batmobile
pick 04a7c9c Dent new batmobile
pick 2a826b2 Attend Policeman's Ball
pick 1d12e8c Defuse bomb before detonation

# Rebase 56d3e50..1d12e8c onto 56d3e50 (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like &quot;squash&quot;, but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We attended the Policeman’s Ball under Batman’s identity, but it should really be Bruce Wayne. On the third line, change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pick&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;edit&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;edit 2a826b2 Attend Policeman's Ball
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can amend the commit to set the correct author.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git commit --amend --author=&quot;Bruce Wayne &amp;lt;bruce.wayne@wayneenterprises.com&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When you’re done, run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase --continue&lt;/code&gt; to move to the next commit that you specified to edit, or to continue to the end of the rebasing session.&lt;/p&gt;

&lt;h3 id=&quot;bulk-change-commits&quot;&gt;Bulk change commits&lt;/h3&gt;
&lt;p&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git filter-branch&lt;/code&gt; command, which is way beyond the scope of this blog post, you can do all kinds of crazy things. One of the more reasonable usages is to inspect every commit in your repository, check if it matches a particular email address, and if so, change it to a new one.&lt;/p&gt;

&lt;p&gt;I’ve create a Gist on Github to do this: &lt;a href=&quot;https://gist.github.com/TheCodedSelf/25e6771efa181bad734295d7fe095550&quot;&gt;author-amend&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just save it in the root of your repository and execute it, or copy it and paste it in your terminal.&lt;/p&gt;

&lt;p&gt;Change the values of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OLD_EMAIL&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORRECT_NAME&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORRECT_EMAIL&lt;/code&gt; to suit your needs.&lt;/p&gt;

&lt;h2 id=&quot;changing-author-identities-is-not-that-hard&quot;&gt;Changing author identities is not that hard.&lt;/h2&gt;
&lt;p&gt;Once you’ve been introduced to the right commands, there’s always a way to coax git into suiting your needs. There’s no need to put up with incorrect names, and definitely no need to scrap the commit and start again.&lt;/p&gt;

&lt;p&gt;So, when something’s gone wrong: 
&lt;img src=&quot;https://media.giphy.com/media/l41lSR9xZubfd2Qve/giphy.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Remember, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit --amend&lt;/code&gt; is your friend.&lt;/p&gt;

&lt;p&gt;Thanks for taking the time to read this, and I hope you learned something that might prove helpful in the future. If you did, please take the time to share it on Facebook, Twitter, Reddit, or whatever it is that people are using these days.&lt;/p&gt;
</description>
          <pubDate>2017-02-15T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Using-Multiple-Author-Identities-With-Git/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Using-Multiple-Author-Identities-With-Git/</guid>
        </item>
      
    
      
        <item>
          <title>The Difference Between An Adapter And A Wrapper</title>
          <description>&lt;p&gt;The adapter pattern and wrappers each solve common but distinct problems. Their common usage and similarities in implementation, however, can lead to confusion. Both terms seem to be used interchangeably when in fact there are a few key differences. The adapter pattern and wrappers are two very useful tools and you can benefit from having them properly labeled in your toolbox.&lt;/p&gt;

&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Adapter:&lt;/strong&gt; An adapter allows code that has been designed for compatibility with one interface to be compatible with another. An adapter accomplishes this by transforming the input meant for Interface A into compatible input for Interface B. It is a bridge between two existing interfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrapper:&lt;/strong&gt; A wrapper encapsulates and hides the complexity of other code. The most common use of a wrapper is in the &lt;a href=&quot;https://en.wikipedia.org/wiki/Facade_pattern&quot;&gt;Facade pattern&lt;/a&gt;. Third-party code can be hard to use due to the fact that the exposed interface is made to accommodate many use cases. When you are only concerned about a subset of the features or the exposed interface, or you find that using the library is hard or tedious, then what you need is to wrap it in a simpler, more constrained interface.&lt;/p&gt;

&lt;h2 id=&quot;differences&quot;&gt;Differences&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Intention:&lt;/strong&gt; The end product may look similar but the intention is different. A wrapper as used in the Facade pattern is intended to simplify an interface to an external library. An adapter is intended to bridge the disconnect between one interface and another. You may look at a new library that you wish to use and write a wrapper to simplify and streamline its use. You may look at an interface, internal or external, that your existing code needs to conform to, and write an adapter to do that.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Composition:&lt;/strong&gt; A wrapper contains another object and wraps around it. It has the the sole responsibility of moving data to and from the wrapped object. An adapter doesn’t necessarily contain or simplify an object, although this can be a secondary benefit of using adapters. An adapter transforms input to make it match the input required by another interface. It adapts input to that other interface.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Problem space:&lt;/strong&gt; An adapter solves a problem of incompatibility, while a wrapper fulfills the need of a simplified and specific programming interface.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;p&gt;Imagine inserting a 2-prong plug into a 3-prong wall socket by using an adapter. That plug adapter is akin to the adapter pattern, whereas the actual plug is a wrapper around the live wires inside.&lt;/p&gt;

&lt;p&gt;The live wires have all of the functionality you need, but the &lt;strong&gt;wrapper&lt;/strong&gt; - the plug - simplifies things. It has all of the functionality with none of the danger.&lt;/p&gt;

&lt;p&gt;Your 2-prong plug isn’t compatible with the 3-prong wall socket, however. You need an &lt;strong&gt;adapter&lt;/strong&gt; to map the 2-prong plug’s interface to what is expected by the 3-prong socket’s interface.&lt;/p&gt;

&lt;h3 id=&quot;lets-see-some-code&quot;&gt;Let’s see some code!&lt;/h3&gt;
&lt;p&gt;Imagine a new feature of your app needs to integrate with social media to get some basic user info. A FacebookConnector class would be a wrapper around Facebook. It facilitates your connection to Facebook. Rather than talk to Facebook’s SDK which exposes many different use cases, you create a class that talks to the SDK for you, and only exposes what you need. I have a Facebook wrapper that I used for a Swift app &lt;a href=&quot;https://github.com/TheCodedSelf/iOS-Social-Integration-Example/blob/master/SocialIntegrationPOC/FacebookConnector.swift&quot;&gt;on my Github profile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What if you know that you need some particulars from social media - a user’s email, a full name, perhaps a profile picture or a personal description? You don’t know what particular social media that you’d like to integrate with. Quite frankly, you don’t care as long as you can get the info that you need. In this scenario, you’d make an ISocialIntegrator interface, defined as following in C#:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C#&quot;&gt;interface ISocialIntegrator
  {
  void Connect();
  string Email { get; }
  string FullName { get; }
  string Description { get; }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice how the actual social network is not mentioned. The interface is agnostic of whatever social network is being used under the hood.&lt;/p&gt;

&lt;p&gt;Now that you’ve defined the interface that the rest of your code will interact with, you can start developing against the interface without worrying about its actual implementation. After a two or three well-earned beers, once you make the choice of the particular social media that you’d like to use, you can create an adapter between your SocialIntegrator interface and the social media that you’ve chosen. You can create a FacebookAdapter, LinkedInAdapter, etc. which will conform to the SocialIntegrator interface and bridge the gap between the generic info that you need and the actual API of the social network that you’ve chosen.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Being cognizant of what problem you are trying to solve and what pattern you are using to solve that problem will help you to keep your code clean and focused on a singular purpose.&lt;/p&gt;

&lt;p&gt;Use wrappers to simplify code, encapsulate third-party dependencies, and eliminate repetition.&lt;/p&gt;

&lt;p&gt;Use the adapter pattern to allow yourself to swap out third-party dependencies at will by interacting with your own interface, and then making adapters that map from your own interface to the third party code.&lt;/p&gt;

</description>
          <pubDate>2017-01-30T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/The-Difference-Between-an-Adapter-and-a-Wrapper/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/The-Difference-Between-an-Adapter-and-a-Wrapper/</guid>
        </item>
      
    
      
        <item>
          <title>Server Side Swift With Kitura And Bluemix</title>
          <description>&lt;p&gt;IBM Bluemix is a cloud Platform as a Service solution that enables you to concentrate on writing your application while Bluemix handles most of the DevOps-y stuff like the networks, servers, storage, and software dependencies. It supports several programming languages, including Swift. It’s also easy to use - all you’ll need to manage your service is a web browser. You can even write your Swift code in your browser in the IBM Swift Sandbox.&lt;/p&gt;

&lt;p&gt;This tutorial will take you over the basics of getting started with Kitura and Bluemix. First, we’ll set up Bluemix so we can upload our app and spin up a server with minimal effort when we’re ready. Then we’ll work through Swift Package Manager and Kitura step by step. Once some familiarity has been established, we’ll build something useful and upload it to Bluemix. We’ll build a small service that takes a &lt;a href=&quot;https://en.wikipedia.org/wiki/Cron#CRON_expression&quot;&gt;cron expression&lt;/a&gt; and returns a human readable description of that expression, using the &lt;a href=&quot;https://github.com/TheCodedSelf/SwiftCron&quot;&gt;SwiftCron package&lt;/a&gt; from &lt;a href=&quot;https://swift.org/package-manager/&quot;&gt;Swift Package Manager&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;setting-up-ibm-bluemix&quot;&gt;Setting up IBM Bluemix&lt;/h4&gt;
&lt;p&gt;To get started, head over to &lt;a href=&quot;https://console.ng.bluemix.net/registration/&quot;&gt;IBM BlueMix&lt;/a&gt; and sign up for a free 30 day trial. When you sign in you’ll be asked to name your organization, which is essentially your team that you can add other people to, and choose its location. Just choose the location that’s closest to you - the options are limited to where Bluemix currently has infrastructure set up. You’ll then be asked to set up a space, which is how Bluemix organizes apps and services.&lt;/p&gt;

&lt;p&gt;You’ll then be navigated to the dashboard which is, understandably, empty. Click on Create App, and we’ll make things a little bit more lively.&lt;/p&gt;

&lt;p&gt;Bluemix is built off of Cloud Foundry, which is an open-source Platform as a Service(PaaS). Bluemix then provides boilerplate for a few popular web frameworks like Python’s Flask framework to get you started instantly. Unfortunately, a boilerplate offering doesn’t yet exist for Swift, so we’ll be scrolling down past these enticing options to the Cloud Foundry Apps section. Choose &lt;strong&gt;Runtime for Swift&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/1_Create_Cloud_Foundry_App.png&quot; alt=&quot;Create a Cloud Foundry App&quot; title=&quot;Create a Cloud Foundry App&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Set your app’s name. I chose SwiftCronServer, and left the host name as the same auto populated value.&lt;/p&gt;

&lt;p&gt;Only a few minutes in and we’re already cranking up a server.  Wasn’t that easy?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/2_Swift_Server_Starting.png&quot; alt=&quot;Swift Server Starting Up&quot; title=&quot;Swift Server Starting Up&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Go back to the dashboard and you should be able to see your new app.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/3_Bluemix_List_Of_Apps.png&quot; alt=&quot;Bluemix list of apps&quot; title=&quot;Bluemix list of apps&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click on it. Then, scroll down to the Continuous Delivery section and click on Enable.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/4_Bluemix_Enable_Continuous_Delivery.png&quot; alt=&quot;Bluemix enable continuous delivery&quot; title=&quot;Bluemix enable continuous delivery&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can deploy your code to Bluemix manually using a command-line interface, but it’s easier and more reliable to just push it upstream to Github and have it build automatically.&lt;/p&gt;

&lt;p&gt;On the Continuous Delivery Toolchain page, scroll down to configurable integrations. Link your GitHub account, and then click on Create.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/5_Continuous_Delivery_Configuration.png&quot; alt=&quot;Continuous delivery configuration&quot; title=&quot;Continuous delivery configuration&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;getting-comfy-with-spm-and-kitura&quot;&gt;Getting Comfy with SPM and Kitura&lt;/h4&gt;
&lt;p&gt;Now it’s time to get a Kitura project running locally. Create a new folder for your project.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir SwiftCronServer
cd SwiftCronServer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Both Kitura and the Cron library we’ll be using are available as packages through the Swift Package Manager, so we’ll create a new project using SPM with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift package init —type executable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are four options for the type specification: &lt;strong&gt;empty&lt;/strong&gt;, &lt;strong&gt;library&lt;/strong&gt;, &lt;strong&gt;executable&lt;/strong&gt;, and &lt;strong&gt;system-module&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;empty&lt;/strong&gt; has empty Sources and Tests folders, and a Package.swift with the package’s name set to ‘empty’&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;library&lt;/strong&gt; has a Sources folder with a swift file named after the folder it was created in (hereafter referred to as the package name) with a struct named after the package. It also has some boilerplate set up for testing and a Package.swift with the package name&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;executable&lt;/strong&gt; has a Sources folder containing a main.swift, an empty Tests folder,  and a Package.swift with the package name&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;system-module&lt;/strong&gt; creates a package.swift for you and a &lt;a href=&quot;http://clang.llvm.org/docs/Modules.html#module-maps&quot;&gt;Clang module map&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great! Now let’s add Kitura and SwiftCron as dependencies in the Package.swift. Change your Package.swift file to look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;import PackageDescription

let package = Package(
    name: &quot;SwiftCronServer&quot;,
    dependencies: [
        .Package(url: &quot;https://github.com/IBM-Swift/Kitura.git&quot;, majorVersion: 1, minor: 2),
        .Package(url: &quot;https://github.com/TheCodedSelf/SwiftCron.git&quot;, majorVersion: 0)
    ])
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift build&lt;/code&gt; and Swift Package Manager will clone the packages listed in the dependency array as well as any dependencies that those packages contain.&lt;/p&gt;

&lt;h6 id=&quot;note&quot;&gt;Note:&lt;/h6&gt;
&lt;p&gt;If you have troubles getting the right tagged version of the dependencies listed in Package.swift, try the following:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;If it’s your repository, make sure to push the tags of that dependency: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push —tag&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;If you’re certain the tag exists in the remote repository, but Swift Package Manager seems to be struggling to pick it up, delete the cloned repository to cause SPM to pull it again: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm -rf Packages/MyRepository-Version&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we can run our project by typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.build/debug/SwiftCronServer&lt;/code&gt; into the terminal:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/5.5_Swift_PM_Hello_World.png&quot; alt=&quot;Swift Package Manager Hello World&quot; title=&quot;Swift Package Manager Hello World&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve got a Hello World SPM executable running, we’ve got three steps remaining:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Make it into a Kitura app&lt;/li&gt;
  &lt;li&gt;Integrate SwiftCron to make it a ‘useful’ Kitura app&lt;/li&gt;
  &lt;li&gt;Put the app on Bluemix&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start off by replacing the contents of main.swift with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;import Kitura

let router = Router()

router.get(&quot;/&quot;) {
    request, response, next in
    response.send(&quot;Hello, World!&quot;)
    next()
}

Kitura.addHTTPServer(onPort: 8090, with: router)

Kitura.run()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can build and run the project again and open a web browser to &lt;a href=&quot;http://localhost:8090/&quot;&gt;http://localhost:8090/&lt;/a&gt; to see the results.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swift build&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.build/debug/SwiftCronServer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/5.6_Kitura_Hello_World.png&quot; alt=&quot;Kitura Hello World&quot; title=&quot;Kitura Hello World&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;building-something-useful&quot;&gt;Building something useful&lt;/h4&gt;

&lt;p&gt;Now we’ll start using SwiftCron. Update main.swift to look like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;import Kitura
import SwiftCron

let router = Router()

router.get(&quot;/:cron&quot;) {
    request, response, next in
    defer {
        next()
    }

    guard let cronString = request.parameters[&quot;cron&quot;],
        let cronExpression = SwiftCron.CronExpression(cronString: cronString) else {
            response.send(&quot;Invalid cron expression.&quot;)
            return
    }

    response.send(cronExpression.longDescription)
}

Kitura.addHTTPServer(onPort: 8090, with: router)

Kitura.run()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s talk about what we’re doing:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let router = Router()&lt;/code&gt;
Create a router object that we can configure with different paths.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;router.get(&quot;/:cron”)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Look out for GET requests to the root URL with a parameter named ‘cron’&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;defer {
        next()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; is a closure that tells Kitura to begin executing the next handler in the path if there are any. The defer block will always be executed at the end of the function regardless of the code path that is followed, making it a great place to put cleanup code.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;guard let cronString = request.parameters[&quot;cron&quot;],
        let cronExpression = SwiftCron.CronExpression(cronString: cronString) else {
            response.status(.badRequest).send(&quot;Invalid cron expression.&quot;)
            return
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Get the parameter that was passed into the get request, and create a cron expression with it. If the parameter doesn’t exist, or it’s invalid and a cron expression can’t be created, notify the user with a 400 response (bad request) and a description of the issue. Then return, firing off the defer block above.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;response.status(.OK).send(cronExpression.longDescription)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If everything is working, send a 200 response (OK) with the human readable description of the cron string that was passed in.&lt;/p&gt;

&lt;p&gt;Great! Build and run the project.
In your browser, try call your Kitura server specifying a cron expression, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0 12 * * * *&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://localhost:8090/0%2012%20*%20*%20*%20*&quot;&gt;http://localhost:8090/0%2012%20&lt;em&gt;%20&lt;/em&gt;%20&lt;em&gt;%20&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/5.7_Kitura_Cron_String.png&quot; alt=&quot;Kitura Cron String&quot; title=&quot;Kitura Cron String&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Try another: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;42 7 11 5 3 *&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://localhost:8090/42%207%2011%205%203%20*&quot;&gt;http://localhost:8090/42%207%2011%205%203%20*&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/5.8_Second_Kitura_Cron_Example.png&quot; alt=&quot;Kitura Cron Example&quot; title=&quot;Kitura Cron Example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that everything is working as expected, it’s time to move it off of localhost.&lt;/p&gt;

&lt;h4 id=&quot;putting-it-on-the-cloud&quot;&gt;Putting it on the cloud&lt;/h4&gt;

&lt;p&gt;Clone the Github repository that was created while integrating Bluemix and Github. If you look in the Sources directory, you’ll see that things are a bit more complex. The starter app follows best practices that we’ll be using. Take a look at main.swift and you’ll see that there is no configuration of routes. main.swift handles logging and starting the server - that’s all it does, just as it should be. All the hard work is done in the Controller class which exposes a port and a router object for main.swift to start the Kitura server.&lt;/p&gt;

&lt;p&gt;Add the SwiftCron package into the Package.swift: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.Package(url: &quot;https://github.com/TheCodedSelf/SwiftCron.git&quot;, majorVersion: 0&lt;/code&gt;. Now we’re able to duplicate the functionality that we had in the local project that we had running. In Controller.swift, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import SwiftCron&lt;/code&gt; add the following to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init()&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;router.get(&quot;/:cron&quot;, handler: getCron)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, in Controller.swift, create the getCron function with the same logic that we had in the local project. You’ll see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getHello&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getJSON&lt;/code&gt; functions as examples of what we’re trying to do.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Declare a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getCron&lt;/code&gt; function:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;public func getCron(request: RouterRequest, response: RouterResponse, next: @escaping () -&amp;gt; Void) throws {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Add a log message at the top of the function:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;Log.debug(&quot;GET - /:cron route handler…&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;And a response header:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;response.headers[&quot;Content-Type&quot;] = &quot;text/plain; charset=utf-8”
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;Implement the same functionality that you had in the local SwiftCronServer project so that you end up with the following request handler:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;public func getCron(request: RouterRequest, response: RouterResponse, next: @escaping () -&amp;gt; Void) throws {
    defer {
        next()
    }

    Log.debug(&quot;GET - /:cron route handler...&quot;)
    response.headers[&quot;Content-Type&quot;] = &quot;text/plain; charset=utf-8&quot;

    guard let cronString = request.parameters[&quot;cron&quot;],
        let cronExpression = SwiftCron.CronExpression(cronString: cronString) else {
            response.status(.badRequest).send(&quot;Invalid cron expression.&quot;)
            return
    }

    response.status(.OK).send(cronExpression.longDescription)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Great. Your Controller.swift should look this example on Github: &lt;a href=&quot;https://github.com/TheCodedSelf/SwiftCronServer-1482253378221/blob/0ef375dce8b18197faec29ebc9445b34cf354d90/Sources/Kitura-Starter/Controller.swift&quot;&gt;https://github.com/TheCodedSelf/SwiftCronServer-1482253378221/blob/0ef375dce8b18197faec29ebc9445b34cf354d90/Sources/Kitura-Starter/Controller.swift&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit your code and push it. Your continuous delivery toolchain should build the app automatically. If it has any issues, hit the ‘restart’ button under Actions on the right.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/6_Swift_Cron_Server_Running.png&quot; alt=&quot;SwiftCron server running&quot; title=&quot;SwiftCron server running&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note:
If you’re having any issues, such as the server crashing, you may want to tail the logs. The easiest way that I’ve found to do this is from the command line. Follow the ‘Getting Started’ instructions for deploying with the command line interface:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/7_Bluemix_Getting_Started.png&quot; alt=&quot;Bluemix Getting Started&quot; title=&quot;Bluemix Getting Started&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The most important steps to follow are the steps on the page to login to bluemix. Once you’ve got the CLI tools and you’ve logged in via the command line, do a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cf logs MyAppName&lt;/code&gt; to receive any logging emitted by Bluemix as well as your app.&lt;/p&gt;

&lt;p&gt;Now, access the route of your application. Mine was https://swiftcronserver.mybluemix.net/. Append a cron string to that URL to see your work in action (for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;30 * * * * *&lt;/code&gt; would be https://swiftcronserver.mybluemix.net/30%20&lt;em&gt;%20&lt;/em&gt;%20&lt;em&gt;%20&lt;/em&gt;%20*).&lt;/p&gt;

&lt;p&gt;Congratulations - A functioning and semi-useful Swift Server Side application.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.thecodedself.com/assets/images/KituraBluemixTutorial/8_Swift_Cron_Server.png&quot; alt=&quot;SwiftCron server running&quot; title=&quot;SwiftCron server running&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;summary&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;We’ve learnt the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How to use Swift Package Manager&lt;/li&gt;
  &lt;li&gt;Basics of Kitura&lt;/li&gt;
  &lt;li&gt;Using Bluemix to effortlessly deploy Swift Server Side applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully this knowledge will inspire you to use a new and exciting toolset to execute your next great idea. Have fun!&lt;/p&gt;

</description>
          <pubDate>2017-01-03T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/Server-Side-Swift-With-Kitura-And-Bluemix/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/Server-Side-Swift-With-Kitura-And-Bluemix/</guid>
        </item>
      
    
      
        <item>
          <title>A Caution On Superfluous Code</title>
          <description>&lt;blockquote&gt;
  &lt;p&gt;The line of code that the developer can write the fastest, the line of code that the developer can maintain the cheapest, and the line of code that never breaks for the user, is the line of code that the developer never had to write.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;- &lt;em&gt;Steve Jobs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Superfluous code is code that is written unnecessarily. It is code that has all the added complexity of valuable code, but it adds no value of its own. If you were to remove it, the product would behave exactly the same. I can think of a few causes of superfluous code:&lt;/p&gt;

&lt;h5 id=&quot;improper-understanding-of-the-toolset&quot;&gt;Improper understanding of the toolset&lt;/h5&gt;
&lt;p&gt;If a developer doesn’t properly understand the language or the library that is being used, how can he be certain that the code he writes is suited to the task at hand? Oftentimes code is written that duplicates functionality included in the standard library. Now the same functionality exists in two different places: in your code base, and in your library. It has to be maintained twice. And tested twice.&lt;/p&gt;

&lt;p&gt;For complex algorithms, you’re losing the benefit of years and years of bug fixes and performance improvements to the implementation that’s available to you through your toolset. Take the time to understand what is available to you. If it suits your needs, use it. Don’t write superfluous code when you can write no code and gain the same value from your platform’s SDKs. But, if you don’t know what is available to you, you’re doomed to repeat the bugs of the past.&lt;/p&gt;

&lt;p&gt;I recently came across the following Swift code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;import Foundation

class Foo {
    var isRegisteredForNotifications = false
    
    init() {
        registerForNotifications()
    }
    
    func registerForNotifications() {
        isRegisteredForNotifications = true
        NotificationCenter.default.addObserver(forName:Notification.Name(rawValue:&quot;MyNotification&quot;),
               object:nil, queue:nil,
               usingBlock:notificationWasFired)
    }
    
    func notificationWasFired(notification: Notification) {
        /*
        .
        .
        */
    }
    
    deinit {
        if isRegisteredForNotifications {
            NotificationCenter.removeObserver(self)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;NotificationCenter is a class in Swift’s Foundation library that implements the Observer pattern. You add an object as an observer for a particular notification and tell it what code to call when that notification is fired. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt; class is registering for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyNotification&lt;/code&gt; notification and asking NotificationCenter to call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;notificationWasFired&lt;/code&gt; when someone fires the notification.&lt;/p&gt;

&lt;p&gt;The developer added a flag to the class which he sets to true when the notification is registered, and he then removes the instance as an observer in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deinit&lt;/code&gt;, as one should. All good, but developers that have used NotificationCenter will know that removing an observer is a safe operation. For instance, one could do the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Swift&quot;&gt;NotificationCenter.removeObserver(self)
NotificationCenter.removeObserver(self)
NotificationCenter.removeObserver(self)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without any negative impact. It’s known that removing an observer is safe, even if the observer is not registered for any notifications. There’s no reason to include the overhead of the extra flag which has to be set, checked, and maintained.&lt;/p&gt;

&lt;h5 id=&quot;changing-requirements&quot;&gt;Changing requirements&lt;/h5&gt;
&lt;p&gt;Requirements change as businesses evolve. It’s one of the reasons our jobs are so hard. Sometimes, you write code that was useful yesterday but it has no functionality today. It may no longer be called anywhere. Or you may be calling a function whose result is no longer used. If the function’s return value is never accessed, and the function produces no other side effects, why keep it? If you need it later, your source control will remember it.&lt;/p&gt;

&lt;h5 id=&quot;false-sense-of-safety&quot;&gt;False sense of safety&lt;/h5&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;var factory = new WidgetFactory();
if (factory != null) {
	Console.WriteLine(factory.name);
} else {
	return;
}

var config = new WidgetConfiguration();
if (factory != null) {
	factory.createWidgetWithConfiguration(config);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Null checks are good. NullReferenceExceptions are bad. But is that second null check really necessary? If nothing is modifying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factory&lt;/code&gt;, don’t check it twice. And if your application is a tangled ball of threads, and you have no idea if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factory&lt;/code&gt; will still be a valid pointer at the time you need it, then maybe those race conditions are a more important problem to solve.&lt;/p&gt;

&lt;h5 id=&quot;premature-optimization&quot;&gt;Premature optimization&lt;/h5&gt;
&lt;p&gt;Writing more performant code usually leads to less readable code. That’s why you’ll hear the advice time and time again that you should only optimize parts of the application that has proven to be a problem through the inspection of metrics. Any optimization that is done without the inspection of current performance should be seen as superfluous, as it does not satisfy any requirement of the application.&lt;/p&gt;

&lt;h2 id=&quot;why-superfluous-code-is-a-problem&quot;&gt;Why superfluous code is a problem&lt;/h2&gt;
&lt;p&gt;When you come across code like this, whether it’s fresh code in a pull request, or in a legacy class that you’re factoring, it’s your duty to remove it. Why?&lt;/p&gt;

&lt;h5 id=&quot;it-breaks-convention&quot;&gt;It breaks convention.&lt;/h5&gt;
&lt;p&gt;There’s a superfluous null check before accessing variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt;. What about the other location where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; was accessed? What about when we access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt;? What about other classes that access objects of the same type as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt;? Was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; a special case? Or is this now best practice? &lt;strong&gt;Too many questions!&lt;/strong&gt; Luckily, you can remove all ambiguity by removing the superfluous code.&lt;/p&gt;

&lt;h5 id=&quot;extra-code-means-extra-capacity-for-bugs&quot;&gt;Extra code means extra capacity for bugs&lt;/h5&gt;
&lt;p&gt;We need to write code because that’s how we build shippable features. Code adds value but more code means more complexity and more places things can go wrong. If the code you’re writing doesn’t add value or perform a necessary function, it only serves to increase the capacity for bugs.&lt;/p&gt;

&lt;h5 id=&quot;the-code-that-isnt-written-has-100-test-coverage-now-and-into-the-future&quot;&gt;The code that isn’t written has 100% test coverage, now and into the future&lt;/h5&gt;
&lt;p&gt;Someone might argue that the code is safe from bugs if it’s covered by tests. But is the code covered by the right tests? Have all possible permutations been covered? What about future changes? You can’t know about future changes. There can’t be any guarantee that the code will be tested six months from now. But I can guarantee you that 100% of the code that I &lt;em&gt;didn’t&lt;/em&gt; write is still 100% tested.&lt;/p&gt;

&lt;h5 id=&quot;extra-code-means-extra-cognitive-load&quot;&gt;Extra code means extra cognitive load&lt;/h5&gt;
&lt;p&gt;Open a class in your project. Any class. Now select everything in the body of the class and delete it. It’s much easier to understand something that’s empty. As we add more functionality to the class, there’s more that a reader needs to take in to fully understand that class. We are increasing the cognitive load when we add to the class, but it’s a small price to pay for the obvious gain: a (hopefully) valuable product. However, when you add superfluous code, you’re increasing the cognitive load without adding value. The class is now harder to read while providing zero extra gain.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;More code means more complexity. More complexity means a heightened possibility for bugs, and more time to understand the intention of the code. Every time we add code we are making a tradeoff: more complexity for more value. I want the code that adds value. But if I’m making a tradeoff where I add complexity and gain no value, that’s not a deal that I want to be a part of.&lt;/p&gt;

&lt;h2 id=&quot;ps&quot;&gt;P.S.&lt;/h2&gt;
&lt;p&gt;Thank you for listening to my ramblings on my first ever blog post. Please leave a comment or send me a mail at thecodedself@gmail.com with any feedback you have!&lt;/p&gt;
</description>
          <pubDate>2016-12-15T00:00:00+00:00</pubDate>
          <link>https://www.thecodedself.com/A-Caution-On-Superfluous-Code/</link>
          <guid isPermaLink="true">https://www.thecodedself.com/A-Caution-On-Superfluous-Code/</guid>
        </item>
      
    
  </channel>
</rss>
