<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator><link href="https://octotap.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://octotap.com/" rel="alternate" type="text/html" /><updated>2025-02-03T22:35:12+00:00</updated><id>https://octotap.com/feed.xml</id><title type="html">Octotap - Piotr Chojnowski</title><subtitle>Hello! I'm Piotr, an iOS developer. This is my articles blog for swift, iOS, UIKit, SwiftUI etc. </subtitle><author><name>Piotr Chojnowski</name><email></email></author><entry><title type="html">SwiftUI avoid custom binding for view performance</title><link href="https://octotap.com/2025/02/03/swiftui-avoid-custom-binding-view-performance/" rel="alternate" type="text/html" title="SwiftUI avoid custom binding for view performance" /><published>2025-02-03T22:00:00+00:00</published><updated>2025-02-03T22:00:00+00:00</updated><id>https://octotap.com/2025/02/03/swiftui-avoid-custom-binding-view-performance</id><content type="html" xml:base="https://octotap.com/2025/02/03/swiftui-avoid-custom-binding-view-performance/"><![CDATA[<h2 id="the-problem">The problem</h2>
<p>In SwiftUI, when the view is redrawn, the SwiftUI compares which of the bindings has changed.
As long as you use a keypath binding, the SwiftUI is able to compare the binding if it has changed or not.
<!--more--></p>

<h2 id="solution">Solution</h2>
<p>For view drawing performance boost, avoid making a custom bindings like the below one:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="k">var</span> <span class="nv">myString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">""</span> 
<span class="c1">//...</span>

<span class="k">let</span> <span class="nv">binding</span> <span class="o">=</span> <span class="kt">Binding</span> <span class="p">{</span>
                    <span class="n">myString</span>
                <span class="p">}</span> <span class="nv">set</span><span class="p">:</span> <span class="p">{</span>
                    <span class="n">myString</span> <span class="o">=</span> <span class="n">newValue</span>
                <span class="p">}</span>

<span class="kt">DatePicker</span><span class="p">(</span><span class="s">"Custom Date"</span><span class="p">,</span> <span class="nv">selection</span><span class="p">:</span> <span class="n">binding</span><span class="p">)</span>
</code></pre></div></div>

<p>That’s all for today!
Thanks for reading.</p>]]></content><author><name>Piotr Chojnowski</name></author><category term="notes" /><category term="swift" /><category term="ios" /><category term="swiftui" /><category term="notes" /><summary type="html"><![CDATA[The problem In SwiftUI, when the view is redrawn, the SwiftUI compares which of the bindings has changed. As long as you use a keypath binding, the SwiftUI is able to compare the binding if it has changed or not.]]></summary></entry><entry><title type="html">Git reflog</title><link href="https://octotap.com/2023/02/09/use-git-reflog/" rel="alternate" type="text/html" title="Git reflog" /><published>2023-02-09T08:00:00+00:00</published><updated>2023-02-09T08:00:00+00:00</updated><id>https://octotap.com/2023/02/09/use-git-reflog</id><content type="html" xml:base="https://octotap.com/2023/02/09/use-git-reflog/"><![CDATA[<p>When something goes terribly wrong, git reference log history comes to the rescue.
<!--more--></p>

<p>That’s probably not something new to an experienced developer like you, but still wanted to write quick article to share.</p>

<h3 id="merge-conflict">Merge conflict</h3>

<p>Sometimes when we are merging our branch to a main one, we can experience a merge conflict. Without going into the details, it’s basically a situation when we have changed the same line of code on our code branch as the other developer, but their change was merged into the main branch before we and now git cannot automatically resolve which one is the proper change.</p>

<h3 id="resolving-conflict">Resolving conflict</h3>
<p>In that case, we need to solve the merge conflict by our own. We can do it with various diffing tools or simply in our IDE. 
Now, let’s imagine that our branch is touching some multiple areas of code, we have gone through the changes, resolved each one of them, saved file and finally commit. Finished resolving the merge conflict, but we noticed issue. If we noticed that during the process, until finished, we can abort the merge by: <code class="language-plaintext highlighter-rouge">git merge --abort</code> or <code class="language-plaintext highlighter-rouge">git rebase --abort</code>, but in the case that I want to describe, we noticed the issue after we finished and closed the process.</p>

<h3 id="the-problem">The problem</h3>
<p>After our merge or a rebase and resolving merge conflicts, we have noticed, that we have picked bad changes during resolving the conflict and now our branch is merged or rebased with a totally bad code. Usually, the easiest thing to do is to get back to the changes before we even started a merge or a rebase. Luckily, there’s a tool in git for it!</p>

<h3 id="the-solution">The solution</h3>
<p>We can get back to the git state before our merging/rebasing process started, so we can try one more time to resolve the conflicts properly.</p>

<p>To do so, we need to open the terminal and type: <code class="language-plaintext highlighter-rouge">git reflog</code>, it should spit out something similar to this:</p>
<p align="center">
    <a href="/assets/images/git-reflog-command.png" target="_blank">
        <img src="/assets/images/git-reflog-command.png" alt="git reflog command output." />
    </a>
    <figcaption>git reflog command output.</figcaption>
</p>

<p>now, we need to find a place in the the reference log history, which reflects the state before our attempt to do a merge or a rebase.
After we find our desirable place in the ref log, we can do this by typing:
<code class="language-plaintext highlighter-rouge">git reset --hard HEAD@{5}</code> - HEAD@{5} is our desired place to revert back to.</p>

<blockquote>
  <p>hint: you may have to do it for your local branch and a branch that you were targeting for, for example: main.</p>
</blockquote>

<p>I hope that it helped. For me, it saved me 2 days of hard work😅</p>

<h5 id="thanks-for-reading-until-next-time">Thanks for reading, until next time!👋</h5>]]></content><author><name>Piotr Chojnowski</name></author><category term="git" /><category term="git" /><category term="blog" /><summary type="html"><![CDATA[When something goes terribly wrong, git reference log history comes to the rescue.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://octotap.com/assets/images/git-reflog-command.png" /><media:content medium="image" url="https://octotap.com/assets/images/git-reflog-command.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Data Flow in SwiftUI</title><link href="https://octotap.com/2023/02/06/Data-flow-in-swiftui/" rel="alternate" type="text/html" title="Data Flow in SwiftUI" /><published>2023-02-06T00:30:00+00:00</published><updated>2023-02-06T00:30:00+00:00</updated><id>https://octotap.com/2023/02/06/Data-flow-in-swiftui</id><content type="html" xml:base="https://octotap.com/2023/02/06/Data-flow-in-swiftui/"><![CDATA[<p>When Apple introduced SwiftUI in WWDC 2019, they took care how to onboard developers with the new technology in their ecosystem.
One of the important topics was how the data flows in the SwiftUI app, because it’s very different from a traditional UIKit app.
The main difference you ask?
<!--more--></p>
<ul>
  <li>being declarative.</li>
</ul>

<h3 id="the-framework">The framework</h3>
<blockquote>
  <p>SwiftUI is the shortest path to a great app […]</p>
</blockquote>

<p>Luca Bernardi @ WWDC19’</p>

<p>Yes, SwiftUI is an Apple’s declaritive approach syntax framework for building apps for iOS, tvOS, macOS and watchOS.
I won’t go into the details about the framework, how it’s built etc. so, if you want to read more about the framework itself go <a href="https://developer.apple.com/xcode/swiftui/" target="_blank">here</a>.</p>

<p>short example of a declaritive syntax SwiftUI view:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Person</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">avatar</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">var</span> <span class="nv">surname</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">var</span> <span class="nv">isFavourite</span><span class="p">:</span> <span class="kt">Bool</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">PersonView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@State</span> <span class="k">var</span> <span class="nv">person</span><span class="p">:</span> <span class="kt">Person</span>

    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">HStack</span> <span class="p">{</span>
            <span class="kt">Image</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">avatar</span><span class="p">)</span>
            <span class="kt">VStack</span><span class="p">(</span><span class="nv">alignment</span><span class="p">:</span> <span class="o">.</span><span class="n">leading</span><span class="p">)</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
                <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">surname</span><span class="p">)</span>
                    <span class="o">.</span><span class="nf">foregroundStyle</span><span class="p">(</span><span class="o">.</span><span class="n">secondary</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Looks pretty easy and fast to build a <code class="language-plaintext highlighter-rouge">PersonView</code> that has a model connected to it, without a <code class="language-plaintext highlighter-rouge">ViewController</code>, constraints for autolayout (or using a storyboard - I assume you don’t use it ;) ), <code class="language-plaintext highlighter-rouge">viewDidLoad</code>, custom passing a model to it and etc.</p>

<h3 id="data-flow">Data flow</h3>
<p>Let’s start with some basics about how the data is passed around in a SwiftUI view. One of the most important things is that the <code class="language-plaintext highlighter-rouge">View</code> should have single source of truth. Avoid duplication of view’s state.</p>

<h2 id="quick-cheat-sheet">Quick cheat sheet</h2>
<p align="center">
	<a href="/assets/images/dataflow-state-objects-diagram.png" target="_blank">
  		<img src="/assets/images/dataflow-state-objects-diagram.png" alt="Quick cheat sheet reference for SwiftUI objects." />
  	</a>
  	<figcaption>Quick cheat sheet reference for SwiftUI objects.</figcaption>
</p>

<h4 id="state">@State</h4>
<p>SwiftUI uses <a href="https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID617" target="_blank">property wrappers</a>, to augment the property behaviour when it’s read or written to. First of them is a local state of view:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@State</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"James"</span>
<span class="kd">@State</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">age</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">42</span>
</code></pre></div></div>

<p>Every time, the <code class="language-plaintext highlighter-rouge">@State</code> property changes, it notifies the view that is owning this source of truth and re-renders the view with the new data. It stores the value, tracks it and makes a dependency towards a view, so the framework knows when it changed and to what value, so it can trigger a view to re-build itself. The data is persisted between the view render passes.</p>

<blockquote>
  <p>Hint: it’s a good practise to mark the <code class="language-plaintext highlighter-rouge">@State</code> as a <code class="language-plaintext highlighter-rouge">private</code> property to enforce that the data is owned and managed by the view where it was created.</p>
</blockquote>

<h4 id="stateobject">@StateObject</h4>
<p>The <code class="language-plaintext highlighter-rouge">@StateObject</code> was introduced in WWDC 2020, to have an easy way to have a local state of view, but for a reference type. This is very analagic to the <code class="language-plaintext highlighter-rouge">@State</code> property wrapper. It makes the referenced object alive between render passes of the SwiftUI view, so it’s not deallocated when the view is re-rendered and the data of the state is persisted. The object that is referenced by <code class="language-plaintext highlighter-rouge">@StateObject</code> needs only to be implementing the protocol of <code class="language-plaintext highlighter-rouge">ObservableObject</code>. Let’s see a quick example:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@MainActor</span>
<span class="kd">class</span> <span class="kt">PersonAvatar</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">image</span><span class="p">:</span> <span class="kt">UIImage</span> <span class="o">=</span> <span class="kt">UIImage</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="s">"placeholder"</span><span class="p">)</span> <span class="p">??</span> <span class="kt">UIImage</span><span class="p">()</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">path</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"https://images.pexels.com/photos/774909/pexels-photo-774909.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=2"</span>
    
    <span class="kd">func</span> <span class="nf">fetchAvatar</span><span class="p">()</span> <span class="k">async</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="n">path</span><span class="p">)</span><span class="o">!</span>
        <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>
        <span class="k">let</span> <span class="p">(</span><span class="nv">data</span><span class="p">,</span> <span class="nv">_</span><span class="p">)</span> <span class="o">=</span> <span class="k">try!</span> <span class="k">await</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">image</span> <span class="o">=</span> <span class="kt">UIImage</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">)</span><span class="o">!</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">AvatarView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@StateObject</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">avatar</span> <span class="o">=</span> <span class="kt">PersonAvatar</span><span class="p">()</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">VStack</span> <span class="p">{</span>
            <span class="kt">Image</span><span class="p">(</span><span class="nv">uiImage</span><span class="p">:</span> <span class="n">avatar</span><span class="o">.</span><span class="n">image</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="o">.</span><span class="n">task</span> <span class="p">{</span>
            <span class="k">await</span> <span class="n">avatar</span><span class="o">.</span><span class="nf">fetchAvatar</span><span class="p">()</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>
<p>On the first run, the SwiftUI view will get rendered with image of a <code class="language-plaintext highlighter-rouge">placeholder</code> file and done. When the view is built, the asynchronous task starts and run in the background. When the task finishes it updates the <code class="language-plaintext highlighter-rouge">@Published var image: UIImage</code> with a jsut downloaded image and the SwiftUI view gets informed about the change through the publisher. Second render pass is being made with the same <code class="language-plaintext highlighter-rouge">PersonAvatar</code> object without instantiating a new one. Quite smart huh? Let’s move on.</p>

<blockquote>
  <p>Hint: The <code class="language-plaintext highlighter-rouge">@StateObject</code> defined in the view is it’s source of truth, please remember to not duplicate the same object in your view hierarchy in order to avoid multiple sources of truth.</p>
</blockquote>

<h4 id="binding">@Binding</h4>
<p>When we have a situation in which the source of truth is not owned by the view, we can use <code class="language-plaintext highlighter-rouge">@Binding</code> property wrapper.
We got the <code class="language-plaintext highlighter-rouge">PersonView</code> SwiftUI view example above. If we would like to have a subview where we can edit the name, surname or a favorite contact we should use <code class="language-plaintext highlighter-rouge">@Binding</code> property wrapper to update that model. Let’s see an example:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">EditPersonDetailsView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@Binding</span> <span class="k">var</span> <span class="nv">person</span><span class="p">:</span> <span class="kt">Person</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">VStack</span><span class="p">(</span><span class="nv">alignment</span><span class="p">:</span> <span class="o">.</span><span class="n">leading</span><span class="p">)</span> <span class="p">{</span>
            <span class="kt">TextField</span><span class="p">(</span><span class="s">"Name"</span><span class="p">,</span> <span class="nv">text</span><span class="p">:</span> <span class="err">$</span><span class="n">person</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
            <span class="kt">TextField</span><span class="p">(</span><span class="s">"Surname"</span><span class="p">,</span> <span class="nv">text</span><span class="p">:</span> <span class="err">$</span><span class="n">person</span><span class="o">.</span><span class="n">surname</span><span class="p">)</span>
            
            <span class="kt">Button</span> <span class="p">{</span>
                <span class="n">person</span><span class="o">.</span><span class="n">isFavourite</span><span class="o">.</span><span class="nf">toggle</span><span class="p">()</span>
            <span class="p">}</span> <span class="nv">label</span><span class="p">:</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"Favourite: </span><span class="se">\(</span><span class="n">person</span><span class="o">.</span><span class="n">isFavourite</span> <span class="p">?</span> <span class="s">"yes"</span> <span class="p">:</span> <span class="s">"no"</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>As you can see above, the SwiftUI view is able to modify the data model of a person, but it’s not owning it. There’s no initialization of the property, because it’s expected to be injected into the <code class="language-plaintext highlighter-rouge">EditPersonDetailsView</code> at view initialization phase. The <code class="language-plaintext highlighter-rouge">TextField</code>s will modify the name name surname and the button will update the boolean of the <code class="language-plaintext highlighter-rouge">isFavourite</code>. Assuming, that the <code class="language-plaintext highlighter-rouge">EditPersonDetailsView</code> was presented as a modal for example, when we will close it the <code class="language-plaintext highlighter-rouge">Person</code> data in the <code class="language-plaintext highlighter-rouge">PersonView</code> will be updated automatically for you. That’s the <code class="language-plaintext highlighter-rouge">@Binding</code> magic. It creates a two directional way of read/write the data from the model passed between two views.</p>

<h4 id="observedobject">@ObservedObject</h4>
<p>This property wrapper <code class="language-plaintext highlighter-rouge">@ObservedObject</code> can be used to observe (as the name suggests) an object that was created somewhere else in the view hierarchy or even outside and our view listens for changes or can introduce some changes into it. The main difference of <code class="language-plaintext highlighter-rouge">ObservedObject</code> and <code class="language-plaintext highlighter-rouge">@StateObject</code> is that the view doesn’t own the data/state when using the <code class="language-plaintext highlighter-rouge">@ObservedObject</code> property.</p>

<p>An example with a person model using reference type and a variant of the person’s detail view:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">PersonModel</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">avatar</span><span class="p">:</span> <span class="kt">String</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">surname</span><span class="p">:</span> <span class="kt">String</span>
    
    <span class="nf">init</span><span class="p">(</span><span class="nv">avatar</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">surname</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">avatar</span> <span class="o">=</span> <span class="n">avatar</span>
        <span class="k">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="k">self</span><span class="o">.</span><span class="n">surname</span> <span class="o">=</span> <span class="n">surname</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">PersonDetailViewObservedObject</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@ObservedObject</span> <span class="k">var</span> <span class="nv">person</span><span class="p">:</span> <span class="kt">PersonModel</span>

    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">HStack</span> <span class="p">{</span>
            <span class="kt">Image</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">avatar</span><span class="p">)</span>
            <span class="kt">VStack</span><span class="p">(</span><span class="nv">alignment</span><span class="p">:</span> <span class="o">.</span><span class="n">leading</span><span class="p">)</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
                <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">surname</span><span class="p">)</span>
                    <span class="o">.</span><span class="nf">foregroundStyle</span><span class="p">(</span><span class="o">.</span><span class="n">secondary</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Initializing the view somewhere in the view hierarchy requires passing the model into it:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">personModel</span><span class="p">:</span> <span class="kt">PersonModel</span> <span class="o">=</span> <span class="kt">PersonModel</span><span class="p">(</span><span class="nv">avatar</span><span class="p">:</span> <span class="s">"avatar.png"</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"James"</span><span class="p">,</span> <span class="nv">surname</span><span class="p">:</span> <span class="s">"Bond"</span><span class="p">)</span>
<span class="c1">// ...</span>
<span class="kt">PersonDetailViewObservedObject</span><span class="p">(</span><span class="nv">person</span><span class="p">:</span> <span class="n">personModel</span><span class="p">)</span>
</code></pre></div></div>

<h4 id="environmentobject">@EnvironmentObject</h4>
<p>This property wrapper is used, when we have some model of data that can or should be shared across many views within the view hierarchy. When injected on the high level of the view hierarchy, views that are lower in the hierarchy can easily access the shared passed model by simply using:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@EnvironmentObject</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">userAuth</span><span class="p">:</span> <span class="kt">UserAuth</span>
</code></pre></div></div>
<p>in the view that needs to access it. It’s just ‘that’ simple.</p>

<p>Here’s a nice visual explanation of the environment from the WWDC19’ by Raj Ramamurthy:</p>
<p align="center">
	<a href="/assets/images/data-flow-swiftui-rr-wwdc19-environment.png" target="_blank">
  		<img src="/assets/images/data-flow-swiftui-rr-wwdc19-environment.png" alt="Q@EnvironmentObject explanation slide from WWDC19' by Raj Ramamurthy." />
  	</a>
  	<figcaption>@EnvironmentObject explanation slide from WWDC19' by Raj Ramamurthy.</figcaption>
</p>

<p align="center">
	<a href="/assets/images/data-flow-swiftui-rr-wwdc19-environment2.png" target="_blank">
  		<img src="/assets/images/data-flow-swiftui-rr-wwdc19-environment2.png" alt="QEnvironmentObject injection view hierarchy example slide from WWDC19' by Raj Ramamurthy." />
  	</a>
  	<figcaption>@EnvironmentObject injection view hierarchy example slide from WWDC19' by Raj Ramamurthy.</figcaption>
</p>

<p>ok, now let’s see an example code below:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">UserAuth</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">isUserLoggedIn</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">false</span>
    
    <span class="kd">func</span> <span class="nf">login</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// some auth code</span>
        <span class="c1">//...</span>
        <span class="n">isUserLoggedIn</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="p">}</span>
    
    <span class="kd">func</span> <span class="nf">logout</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// drop auth keys</span>
        <span class="n">isUserLoggedIn</span> <span class="o">=</span> <span class="kc">false</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">PersonDetailViewEnv</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@Binding</span> <span class="k">var</span> <span class="nv">person</span><span class="p">:</span> <span class="kt">Person</span>
    <span class="kd">@EnvironmentObject</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">userAuth</span><span class="p">:</span> <span class="kt">UserAuth</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">openLogin</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// proceed to login screen</span>
    <span class="p">}</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">HStack</span> <span class="p">{</span>
            <span class="k">if</span> <span class="n">userAuth</span><span class="o">.</span><span class="n">isUserLoggedIn</span> <span class="p">{</span>
                <span class="kt">Image</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">avatar</span><span class="p">)</span>
                <span class="kt">VStack</span><span class="p">(</span><span class="nv">alignment</span><span class="p">:</span> <span class="o">.</span><span class="n">leading</span><span class="p">)</span> <span class="p">{</span>
                    <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
                    <span class="kt">Text</span><span class="p">(</span><span class="n">person</span><span class="o">.</span><span class="n">surname</span><span class="p">)</span>
                        <span class="o">.</span><span class="nf">foregroundStyle</span><span class="p">(</span><span class="o">.</span><span class="n">secondary</span><span class="p">)</span>
                <span class="p">}</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"You have to log in."</span><span class="p">)</span>
                <span class="kt">Button</span> <span class="p">{</span>
                    <span class="nf">openLogin</span><span class="p">()</span>
                <span class="p">}</span> <span class="nv">label</span><span class="p">:</span> <span class="p">{</span>
                    <span class="kt">Text</span><span class="p">(</span><span class="s">"login"</span><span class="p">)</span>
                <span class="p">}</span>

            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>What happens here is that, there is some <code class="language-plaintext highlighter-rouge">UserAuth</code> living in the app, that has an information about whether the user is logged in or not. It makes use of <code class="language-plaintext highlighter-rouge">@Published</code> property wrapper to notify all of the listening views for the state changes.</p>

<p>User authentication is something that should be shared in the app from the very first view in the app, so let’s put it in the <code class="language-plaintext highlighter-rouge">MainView</code>:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@main</span>
<span class="kd">struct</span> <span class="kt">PersonApp</span><span class="p">:</span> <span class="kt">App</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">userAuth</span> <span class="o">=</span> <span class="kt">UserAuth</span><span class="p">()</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">Scene</span> <span class="p">{</span>
        <span class="kt">WindowGroup</span> <span class="p">{</span>
            <span class="kt">MainView</span><span class="p">()</span>
                <span class="o">.</span><span class="nf">environmentObject</span><span class="p">(</span><span class="n">userAuth</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Let’s assume that in this case, the <code class="language-plaintext highlighter-rouge">MainView</code> view is containing the <code class="language-plaintext highlighter-rouge">PersonDetailViewEnv</code> view, so the <code class="language-plaintext highlighter-rouge">PersonDetailViewEnv</code> doesn’t need to be invoked with <code class="language-plaintext highlighter-rouge">.environmentObject(userAuth)</code> because it’s already in the same chain of the view hierarchy, so the environment object is alread in place, just the <code class="language-plaintext highlighter-rouge">PersonDetailViewEnv</code> needs to access it by:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@EnvironmentObject</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">userAuth</span><span class="p">:</span> <span class="kt">UserAuth</span>
</code></pre></div></div>

<p>And voila! That’s how passing the data through the <code class="language-plaintext highlighter-rouge">@EnvironmentObject</code> works.</p>

<p><br /></p>

<h5 id="thanks-for-reading-until-next-time">Thanks for reading, until next time!</h5>

<h4 id="resources">resources:</h4>
<ul>
  <li><a href="https://developer.apple.com/videos/play/wwdc2019/226">https://developer.apple.com/videos/play/wwdc2019/226</a></li>
  <li><a href="https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID617">https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID617</a></li>
</ul>]]></content><author><name>Piotr Chojnowski</name></author><category term="swiftui" /><category term="swift" /><category term="swiftui" /><category term="stateobject" /><category term="binding" /><category term="state" /><category term="observedobject" /><summary type="html"><![CDATA[When Apple introduced SwiftUI in WWDC 2019, they took care how to onboard developers with the new technology in their ecosystem. One of the important topics was how the data flows in the SwiftUI app, because it’s very different from a traditional UIKit app. The main difference you ask?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://octotap.com/assets/images/dataflow-state-objects-diagram.png" /><media:content medium="image" url="https://octotap.com/assets/images/dataflow-state-objects-diagram.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">UIStackView inside UIScrollView</title><link href="https://octotap.com/2019/08/03/uistackview-inside-uiscrollview/" rel="alternate" type="text/html" title="UIStackView inside UIScrollView" /><published>2019-08-03T19:00:00+00:00</published><updated>2019-08-03T19:00:00+00:00</updated><id>https://octotap.com/2019/08/03/uistackview-inside-uiscrollview</id><content type="html" xml:base="https://octotap.com/2019/08/03/uistackview-inside-uiscrollview/"><![CDATA[<p>I guess you might be wondering how to auto-layout properly <code class="language-plaintext highlighter-rouge">UIStackView</code> inside <code class="language-plaintext highlighter-rouge">UIScrollView</code>, since you are reading this post.
The thing about auto-layout trick is to setup auto-layout properly, so the <code class="language-plaintext highlighter-rouge">UIScrollView</code> will not show horizontal or vertical scrolls when not needed and it’s content size will be set properly.</p>

<p>In this short tutorial I will show you how to build simple UI with use of:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">UIStackView</code></li>
  <li><code class="language-plaintext highlighter-rouge">UIScrollView</code></li>
  <li>Programmatic Auto-Layout</li>
</ul>

<p>Ok, first things first. We are going to build a version of the app where we want to have a proper horizontal scrolling of contents of the stack view. I assume you created a <code class="language-plaintext highlighter-rouge">UIViewController</code> and the view is ready to work on.
If not, you can try out by making a new starter project in Xcode - Single View app.
Ok, first step, let’s add a <code class="language-plaintext highlighter-rouge">UIScrollView</code> and <code class="language-plaintext highlighter-rouge">UIStackView</code> object declarations by this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">scrollView</span><span class="p">:</span> <span class="kt">UIScrollView</span> <span class="o">=</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">scrollView</span> <span class="o">=</span> <span class="kt">UIScrollView</span><span class="p">()</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        <span class="k">return</span> <span class="n">scrollView</span>
    <span class="p">}()</span>

    <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">stackView</span><span class="p">:</span> <span class="kt">UIStackView</span> <span class="o">=</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">stackView</span> <span class="o">=</span> <span class="kt">UIStackView</span><span class="p">()</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">axis</span> <span class="o">=</span> <span class="o">.</span><span class="n">vertical</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">distribution</span> <span class="o">=</span> <span class="kt">UIStackView</span><span class="o">.</span><span class="kt">Distribution</span><span class="o">.</span><span class="n">equalSpacing</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">spacing</span> <span class="o">=</span> <span class="mi">30</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        <span class="k">return</span> <span class="n">stackView</span>
    <span class="p">}()</span>
</code></pre></div></div>

<p>Ok, now let’s build two methods that will create subviews, add them to the hierarchy and setup layout.
We want also the StackView to have a 20 points layout margins on the leading and trailing side, by adding:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">stackView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">stackView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
</code></pre></div></div>

<p>ok, to sum up, this part we should have something like this below.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">setupViews</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">lightGray</span>
        <span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">scrollView</span><span class="p">)</span>
        
        <span class="n">scrollView</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">stackView</span><span class="p">)</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">setupLayout</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        
        <span class="n">stackView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>

        <span class="n">stackView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="p">}</span>

</code></pre></div></div>

<p>We are adding here</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">stackView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
</code></pre></div></div>
<p>to tell the <code class="language-plaintext highlighter-rouge">UIScrollView</code> how to calculate it’s content size for vertical scrolling only. See reference provided by Apple: 
<a href="https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html">https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html</a></p>

<p>Now let’s add some labels by first, declaration of computed property and then the actual usage.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="k">var</span> <span class="nv">titleLabel</span><span class="p">:</span> <span class="kt">UILabel</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">label</span> <span class="o">=</span> <span class="kt">UILabel</span><span class="p">()</span>
        <span class="n">label</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        <span class="n">label</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"UIStackView inside UIScrollView."</span>
        <span class="n">label</span><span class="o">.</span><span class="n">font</span> <span class="o">=</span> <span class="kt">UIFont</span><span class="o">.</span><span class="nf">systemFont</span><span class="p">(</span><span class="nv">ofSize</span><span class="p">:</span> <span class="mi">24</span><span class="p">,</span> <span class="nv">weight</span><span class="p">:</span> <span class="o">.</span><span class="n">medium</span><span class="p">)</span>
        <span class="n">label</span><span class="o">.</span><span class="n">textColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">white</span>
        <span class="n">label</span><span class="o">.</span><span class="n">textAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="n">center</span>
        <span class="k">return</span> <span class="n">label</span>
    <span class="p">}</span>

<span class="c1">/// Update setupViews() method at the end by adding this:</span>
    <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
    <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
    <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
    <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
    <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
</code></pre></div></div>

<p>Ok, now let’s compile it and run!
Below is what you should get.</p>

<p align="center">
  <img src="/assets/images/stackViewInsideHorizontalIssue.gif" alt="UIStackView Inside UIScrollView swift iOS." />
  <figcaption>UIStackView Inside UIScrollView swift iOS.</figcaption>
</p>

<p>To avoid this issue, we have to provide a new content view and then add our <code class="language-plaintext highlighter-rouge">UIStackView</code> into it.</p>

<h2 id="fixing-the-issue">Fixing the issue</h2>
<p>First, create a new content view that will be holding the <code class="language-plaintext highlighter-rouge">UIStackView</code></p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">contentView</span><span class="p">:</span> <span class="kt">UIView</span> <span class="o">=</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">view</span> <span class="o">=</span> <span class="kt">UIView</span><span class="p">()</span>
        <span class="n">view</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        <span class="k">return</span> <span class="n">view</span>
    <span class="p">}()</span>
</code></pre></div></div>

<p>then, change the <code class="language-plaintext highlighter-rouge">setupViews</code> method to reflect adding the <code class="language-plaintext highlighter-rouge">contentView</code> into the <code class="language-plaintext highlighter-rouge">scrollView</code> and add <code class="language-plaintext highlighter-rouge">stackView</code> to <code class="language-plaintext highlighter-rouge">contentView</code> as a subview:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">setupViews</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">lightGray</span>
        <span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">scrollView</span><span class="p">)</span>
        
        <span class="n">scrollView</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">contentView</span><span class="p">)</span>
        
        <span class="n">contentView</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">stackView</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">simpleView</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
        <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>Now let’s update the <code class="language-plaintext highlighter-rouge">setupLayout</code> method to reflect the change in layouting.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">setupLayout</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        
        <span class="n">contentView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">contentView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">contentView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">contentView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        
        <span class="c1">// because: "Constraints between the height, width, or centers attach to the scroll view’s frame." -</span>
        <span class="c1">// https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html</span>
        <span class="n">contentView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">scrollView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        
        <span class="n">stackView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">contentView</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">contentView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">contentView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">20</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="n">stackView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">contentView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="p">}</span>
</code></pre></div></div>
<p>Now we should get this fixed:</p>

<p align="center">
  <img src="/assets/images/stackViewInsideHorizontalIssueFixed.gif" alt="UIStackView Inside UIScrollView horizontal scroll issue fixed" />
  <figcaption>UIStackView Inside UIScrollView horizontal scroll issue fixed.</figcaption>
</p>

<p>as you can see the margins now are correct and there is no possible scrolling, because the content does not need that! :)
Let’s try to add more labels by copying few more lines (just to fill empty space) in <code class="language-plaintext highlighter-rouge">setupViews</code> method:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">setupViews</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">scrollView</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">lightGray</span>
        <span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">scrollView</span><span class="p">)</span>
        
        <span class="n">scrollView</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">contentView</span><span class="p">)</span>
        
        <span class="n">contentView</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">stackView</span><span class="p">)</span>
        
        <span class="k">for</span> <span class="n">_</span> <span class="k">in</span> <span class="mi">0</span><span class="o">...</span><span class="mi">15</span> <span class="p">{</span>
            <span class="n">stackView</span><span class="o">.</span><span class="nf">addArrangedSubview</span><span class="p">(</span><span class="n">titleLabel</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>
<p>and here’s the final result!</p>

<p align="center">
  <img src="/assets/images/stackViewInsideHorizontalIssueFixedMoreContent.gif" alt="UUIStackView Inside UIScrollView horizontal scroll issue fixed with more content" />
  <figcaption>UIStackView Inside UIScrollView horizontal scroll issue fixed with more content.</figcaption>
</p>

<p>If you would like to see the full and finished code go to my Github repository: 
<a href="https://github.com/piotrchojnowski/StackScrollView">https://github.com/piotrchojnowski/StackScrollView</a></p>

<p>This post was also posted on Medium:
<a href="https://medium.com/@p.chojnowski/uistackview-inside-uiscrollview-uikit-28ef121a0fee">https://medium.com/@p.chojnowski/uistackview-inside-uiscrollview-uikit-28ef121a0fee</a></p>

<p>Thanks for reading!</p>]]></content><author><name>Piotr Chojnowski</name></author><category term="UIKit" /><category term="swift" /><category term="ios" /><category term="swift" /><category term="ios" /><category term="UIKit" /><category term="UIStackView" /><category term="UIScrollView" /><summary type="html"><![CDATA[I guess you might be wondering how to auto-layout properly UIStackView inside UIScrollView, since you are reading this post. The thing about auto-layout trick is to setup auto-layout properly, so the UIScrollView will not show horizontal or vertical scrolls when not needed and it’s content size will be set properly.]]></summary></entry><entry><title type="html">VIPER template</title><link href="https://octotap.com/2019/03/19/viper-template-repo/" rel="alternate" type="text/html" title="VIPER template" /><published>2019-03-19T19:00:00+00:00</published><updated>2019-03-19T19:00:00+00:00</updated><id>https://octotap.com/2019/03/19/viper-template-repo</id><content type="html" xml:base="https://octotap.com/2019/03/19/viper-template-repo/"><![CDATA[<p>Public repository with a VIPER template for Xcode.</p>

<p>I’m programming commercially since around 2011. Since then, I haven’t committed any line of code into a public repository.
I’m about to try to change that, however, I am hoping that I will have enough of my spare/free time to upkeep my public projects.</p>

<p>Recently, I have been listening to Swift by Sundell Podcasts (link: <a href="https://john-sundell.squarespace.com/podcast?format=rss">https://john-sundell.squarespace.com/podcast?format=rss</a>) and there is this motivation to try open source on very simple things in the beginning, like source code snippets, templates, try resolving beginner issues in some open project repositories. I am about to try that because I have implemented tons of source code in private/company repos and I have used a lot of open-source code. I think it would be good to give back something to the community.</p>

<p>github link to my Xcode VIPER template in Swift.</p>

<p><a href="https://github.com/piotrchojnowski/Xcode-Swift-Viper-Template">https://github.com/piotrchojnowski/Xcode-Swift-Viper-Template</a></p>]]></content><author><name>Piotr Chojnowski</name></author><category term="viper" /><category term="template" /><category term="xcode" /><category term="public" /><category term="repository" /><category term="viper" /><category term="swift" /><category term="xcode" /><category term="template" /><summary type="html"><![CDATA[Public repository with a VIPER template for Xcode.]]></summary></entry><entry><title type="html">Swift 2.1 – types, operators and collections</title><link href="https://octotap.com/2015/10/25/Swift-21-types-operators-collections/" rel="alternate" type="text/html" title="Swift 2.1 – types, operators and collections" /><published>2015-10-25T19:00:00+00:00</published><updated>2015-10-25T19:00:00+00:00</updated><id>https://octotap.com/2015/10/25/Swift-21-types-operators-collections</id><content type="html" xml:base="https://octotap.com/2015/10/25/Swift-21-types-operators-collections/"><![CDATA[<p>[archive]</p>

<p>Welcome on my first part of tutorials about the programming language Swift.
In this very first tutorial we will focus on types, operators and collections that are available in Swift. We will use currently newest Swift 2.1 version with Xcode 7.1.
To be able to run the code snippets that will be written further, you will need Xcode 7.1+ with Swift 2.1 compiler.
<!--more--></p>
<h5 id="note">NOTE:</h5>
<p>This tutorial is not intended for a very beginners. It’s intended for people that know about programming and have some experience in the programming concepts already.</p>

<h1 id="declarations-and-types">Declarations and Types</h1>
<p>When you want to define a variable in Swift you do it like that:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">myInteger</span> <span class="o">=</span> <span class="mi">10</span>
</code></pre></div></div>

<p>as you can see, there is no typing information. That’s because Swift can infer the type from the assigned value, which is here an integer. So it will be an implicit typing to:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">myInteger</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">10</span>
</code></pre></div></div>

<p>You can also declare the variable only and later assign a value to it. Swift will check, if you are using an uninitialised variable, so it will be a hard compiler error.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">myInteger</span><span class="p">:</span> <span class="kt">Int</span>

<span class="o">...</span>
<span class="n">myInteger</span> <span class="o">=</span> <span class="mi">10</span>
</code></pre></div></div>

<p>Another type of variable here is a constant. You define a constant with a let keyword. If you type a variable with var you can change the value later, if let you can’t.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">stringConstant</span> <span class="o">=</span>  <span class="s">"Hello World! :)"</span>
</code></pre></div></div>
<p>as well as the variable, you can declare a constant and assign a value for it later, but only for once. Once initialised, you can’t change it’s value. However, it’s a good practise to assign the value for constant in the declaration.</p>

<h1 id="basic-types">Basic Types</h1>
<p>In Swift there are some basic types that looks and works like basic C types, but with the difference here that they are actually first class objects.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Bool</span>
<span class="kt">String</span>
<span class="kt">Double</span>
<span class="kt">Float</span>
<span class="kt">UInt</span>
<span class="kt">Int</span>
</code></pre></div></div>

<p>They have methods that you can use, you can extend them if you want to and they have properties like min and max. In addition to Swift types, you have access to other types when you will import the <code class="language-plaintext highlighter-rouge">Foundation</code> library.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Int8</span><span class="p">,</span> <span class="kt">Int16</span><span class="p">,</span> <span class="kt">Int32</span><span class="p">,</span> <span class="kt">Int64</span>
<span class="kt">UInt8</span><span class="p">,</span> <span class="kt">UInt16</span><span class="p">,</span> <span class="kt">UInt32</span><span class="p">,</span> <span class="kt">UInt64</span>
<span class="kt">UTF8</span><span class="p">,</span> <span class="kt">UTF16</span><span class="p">,</span> <span class="kt">UTF32</span><span class="p">,</span> <span class="kt">UTF64</span>
<span class="kt">Float80</span>
</code></pre></div></div>
<p>Also, Swift supports a type aliasing, so you are able to define your own type that maybe more appropriate or more understandable in your source code</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">typealias</span> <span class="kt">Unsigned</span> <span class="o">=</span> <span class="kt">UInt64</span>
</code></pre></div></div>
<p>Another thing worth to mention here is the fact that Swift does not support implicit type conversion. Below is an example:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">myInteger</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">var</span> <span class="nv">myDouble</span><span class="p">:</span> <span class="kt">Double</span> <span class="o">=</span> <span class="mf">10.0</span>

<span class="k">var</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">myInteger</span> <span class="o">+</span> <span class="n">myDouble</span> <span class="c1">// this will result with a hard compiler error</span>

<span class="c1">// instead above you should perform:</span>
<span class="k">var</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">myInteger</span> <span class="o">+</span> <span class="kt">Int</span><span class="p">(</span><span class="n">myDouble</span><span class="p">)</span>
</code></pre></div></div>

<p>The result variable will be of Int type.</p>

<h1 id="string-type">String Type</h1>
<p>In Swift you can use both String type and the NSString type. To use NSString you have to import the Foundation library</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">Foundation</span>

<span class="k">let</span> <span class="nv">myString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"Hello"</span>
<span class="k">let</span> <span class="nv">myNSString</span><span class="p">:</span> <span class="kt">NSString</span> <span class="o">=</span> <span class="s">"World!"</span>
</code></pre></div></div>

<p>The difference in those two types are that the String type is bridged to the NSString type. String type is a kind of a subclass of the NSString. You will be able to assign a String to the NSString but you won’t be able to it the other way. However, you can assign a NSString instance to the String variable, but you need to do an explicit casting like this:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">Foundation</span>

<span class="k">let</span> <span class="nv">myString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"Hello"</span>
<span class="k">let</span> <span class="nv">myNSString</span><span class="p">:</span> <span class="kt">NSString</span> <span class="o">=</span> <span class="s">" World!"</span>
<span class="k">let</span> <span class="nv">castedString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="n">myNSString</span> <span class="k">as</span> <span class="kt">String</span>
<span class="k">let</span> <span class="nv">concatenatedString</span> <span class="o">=</span> <span class="n">myString</span> <span class="o">+</span> <span class="n">castedString</span> <span class="c1">// "Hello World!"</span>
</code></pre></div></div>

<p>Becasue the String is an object type, you can perform many operations on strings like below:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">myString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"Hello World! How Are you?"</span>
<span class="n">myString</span><span class="o">.</span><span class="nf">hasSuffix</span><span class="p">(</span><span class="s">"you?"</span><span class="p">)</span> <span class="c1">// will return true, if the string ends with "you?" string</span>
<span class="n">myString</span><span class="o">.</span><span class="nf">hasPrefix</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">)</span> <span class="c1">// will return true, if the string begins with "Hello" string</span>
<span class="n">myString</span><span class="o">.</span><span class="n">characters</span><span class="o">.</span><span class="n">count</span> <span class="c1">// will return the number of used characters</span>
</code></pre></div></div>

<p>there is a lot of methods to use and compare strings. One more thing about the string is that you can compare strings by ==, &lt;=, &gt;=, &lt;, &gt; operators, for example:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">myString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"Hello World! How Are you?"</span>
<span class="k">let</span> <span class="nv">myShortString</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"I am fine :)"</span>

<span class="n">myString</span> <span class="o">&gt;</span> <span class="n">myShortString</span> <span class="c1">// this will return true</span>
<span class="s">"100"</span> <span class="o">&lt;</span> <span class="s">"101"</span> <span class="c1">// will also return true :)</span>
</code></pre></div></div>
<p>More details at <a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html">https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html</a></p>

<h1 id="optionals">Optionals</h1>
<p>There are some situations when you are not sure, if your method is going to produce any value as a return value. It may return nothing, because the input value was bad, or there was some internal computation error that was not handled properly. In Swift you have a special type for that kind of situations – optionals! You define the optional type with providing the ? mark.
Let’s look at the example below:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">optionalInt</span><span class="p">:</span> <span class="kt">Int</span><span class="p">?</span>			<span class="c1">// implicit: var optionalInt: Int? = nil</span>
<span class="k">let</span> <span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"13"</span>
<span class="n">optionalInt</span> <span class="o">=</span> <span class="kt">Int</span><span class="p">(</span><span class="n">stringValue</span><span class="p">)</span>            <span class="c1">// Optional as the return value</span>

<span class="k">if</span> <span class="k">let</span> <span class="nv">value</span> <span class="o">=</span> <span class="n">optionalInt</span> <span class="p">{</span>               <span class="c1">// safely unwrap the optional value</span>
    <span class="nf">print</span><span class="p">(</span><span class="s">"String converted to: </span><span class="se">\(</span><span class="n">value</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>    <span class="c1">// this will print "String converted to: 13"</span>
<span class="p">}</span>

<span class="c1">// you can also check it like this </span>
<span class="k">if</span> <span class="n">optionalInt</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> <span class="c1">// check if there is a valid value</span>
    <span class="nf">print</span><span class="p">(</span><span class="s">"String converted to: </span><span class="se">\(</span><span class="n">optionalInt</span><span class="o">!</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>  <span class="c1">// unwrap the value explicitly (force unwrapping), this will print "String converted to: 13"</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We assigned an optional return value from method <code class="language-plaintext highlighter-rouge">Int()</code> to the optionalInt variable. The <code class="language-plaintext highlighter-rouge">Int()</code> method could return an optional that is empty inside, it has no value. Still, it’s a valid object but without a value inside of it.</p>

<h3 id="force-unwrapping">Force unwrapping</h3>
<p>if let statement checks what is the inside the optional variable, if there is a value it enters the inside body, if not nothing bad happens and the code from the if body is not executed.
If you would like to try unwrap the value from the optional you can with using the <code class="language-plaintext highlighter-rouge">!</code> mark, as below:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">optionalInt</span><span class="p">:</span> <span class="kt">Int</span><span class="p">?</span>
<span class="k">let</span> <span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">"13"</span>
<span class="n">optionalInt</span> <span class="o">=</span> <span class="kt">Int</span><span class="p">(</span><span class="n">stringValue</span><span class="p">)</span>            <span class="c1">// Optional as the return value</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"String converted to: </span><span class="se">\(</span><span class="n">optionalInt</span><span class="o">!</span><span class="se">)</span><span class="s">"</span><span class="p">)</span> <span class="c1">//this will print "String converted to: 13"</span>
</code></pre></div></div>
<p>But what if the <code class="language-plaintext highlighter-rouge">optionalValue</code> was empty? What would happen? It would crash spectacularly, resulting with the app crash. You cannot unwrap the value explicitly unless you are pretty sure that there is a valid value, not <code class="language-plaintext highlighter-rouge">nil</code>. However, it’s a good practise to perform checks like the one above (especially by the <code class="language-plaintext highlighter-rouge">if let</code> clause), as it results with higher code quality, security and of course stability.</p>

<p>Thank you for reading, that’s all for Today. There will be more in next days :)
I have attached a playground file for this topic here: <a href="https://github.com/piotrchojnowski/octotap-com-assets/tree/main/playgrounds/types_operators_collections.playground">types_operators_collections.playground</a></p>]]></content><author><name>Piotr Chojnowski</name></author><category term="swift" /><category term="archive" /><category term="swift" /><category term="swiftlang" /><category term="types" /><category term="optionals" /><summary type="html"><![CDATA[[archive] Welcome on my first part of tutorials about the programming language Swift. In this very first tutorial we will focus on types, operators and collections that are available in Swift. We will use currently newest Swift 2.1 version with Xcode 7.1. To be able to run the code snippets that will be written further, you will need Xcode 7.1+ with Swift 2.1 compiler.]]></summary></entry><entry><title type="html">Objective-C pitfalls</title><link href="https://octotap.com/2015/02/20/objective-c-pitfalls/" rel="alternate" type="text/html" title="Objective-C pitfalls" /><published>2015-02-20T19:00:00+00:00</published><updated>2015-02-20T19:00:00+00:00</updated><id>https://octotap.com/2015/02/20/objective-c-pitfalls</id><content type="html" xml:base="https://octotap.com/2015/02/20/objective-c-pitfalls/"><![CDATA[<p>Today I will describe some most common pitfalls in Objective-C that, a beginner developer can learn about and the advanced developer can refresh his information about it.</p>

<p>Ok, so without more time to introduce, let’s start.</p>

<h1 id="1-pitfall--overall-traps">#1 Pitfall – Overall traps</h1>
<p>What can possibly go wrong with the below code?</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">CGFloat</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="n">f</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="n">f</span> <span class="o">&lt;=</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="n">f</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So, minding that the compiler will evaluate this if statement to that:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">CGFloat</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">.</span><span class="mi">25</span><span class="n">f</span><span class="p">;</span>
<span class="k">if</span> <span class="p">((</span><span class="o">-</span><span class="mi">0</span><span class="p">.</span><span class="mi">5</span> <span class="o">&lt;=</span> <span class="n">x</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>it won’t enter the if statement with x = 0.25 value. It’s because of the fact, that the comparison result is an Int, so it wil be 0 or 1. With value of x = 0.25; it will look like this:</p>
<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">.</span><span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="2-pitfall--comparing-objects">#2 Pitfall – Comparing Objects</h1>

<p>In Objective-C we can compare objects in two ways:</p>
<ul>
  <li>compare by pointer</li>
  <li>compare by value</li>
</ul>

<p>Bearing that in mind, let’s take a look at below code example:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="n">object</span> <span class="o">==</span> <span class="n">_storedObject</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="s">@"No need to replace stored Object!"</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">([</span><span class="n">object</span> <span class="nf">isEqual</span><span class="p">:</span><span class="n">_storedObject</span><span class="p">])</span> <span class="p">{</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="s">@"No need to replace stored Object!"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In the first <code class="language-plaintext highlighter-rouge">if</code> statement we are comparing the object and the <code class="language-plaintext highlighter-rouge">_storedObject</code> by pointers. If the pointers are equal, then the <code class="language-plaintext highlighter-rouge">if</code> statement will evaluate to true value.</p>

<p>In the second <code class="language-plaintext highlighter-rouge">if</code> statement we are comparing both objects by their internal values. Let’s assume that the object and the <code class="language-plaintext highlighter-rouge">_storedObject</code> are both <code class="language-plaintext highlighter-rouge">NSString</code> instances and they were assigned with the same string:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">NSString</span> <span class="o">*</span><span class="n">object</span> <span class="o">=</span> <span class="s">@"The same string"</span><span class="p">;</span>
<span class="n">_storedObject</span> <span class="o">=</span> <span class="s">@"The same string"</span><span class="p">;</span>
</code></pre></div></div>

<p>The compiler will compare those objects in the <code class="language-plaintext highlighter-rouge">if</code> statement by checking if those two objects contain the same values, in our case – the same strings.</p>

<h1 id="3-pitfall--the-nil-value">#3 Pitfall – the nil value</h1>
<p>When using objects we have to keep in mind, that the pointer that it is pointing to may be <code class="language-plaintext highlighter-rouge">nil</code>. Let’s have a look at the below method:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">-</span> <span class="p">(</span><span class="n">BOOL</span><span class="p">)</span> <span class="nf">processValueForKey</span><span class="p">:(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">key</span> <span class="p">{</span>
    <span class="n">NSString</span> <span class="o">*</span><span class="n">myString</span> <span class="o">=</span> <span class="n">_dictionary</span><span class="p">[</span><span class="nf">key</span><span class="p">];</span>

    <span class="c1">// very long procedure</span>
    <span class="n">myString</span> <span class="o">=</span> <span class="p">[</span><span class="n">myString</span> <span class="nf">MD5</span><span class="p">];</span>
    <span class="p">...</span>
    <span class="k">return</span> <span class="n">success</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>What can possibly go wrong here?</p>

<p>Of course, it could be a situation when the dictionary does not contain such key, so it will return <code class="language-plaintext highlighter-rouge">nil</code>. With that <code class="language-plaintext highlighter-rouge">nil</code> value the whole long method will go further and take some time from the CPU. We can avoid such situation with creating an early return check, like this one:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">-</span> <span class="p">(</span><span class="n">BOOL</span><span class="p">)</span> <span class="nf">processValueForKey</span><span class="p">:(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">key</span> <span class="p">{</span>
     <span class="n">NSString</span> <span class="o">*</span><span class="n">myString</span> <span class="o">=</span> <span class="n">_dictionary</span><span class="p">[</span><span class="nf">key</span><span class="p">];</span>

     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">myString</span><span class="p">)</span> <span class="p">{</span>
         <span class="n">assert</span><span class="p">(</span><span class="n">myString</span> <span class="o">!=</span> <span class="nb">nil</span><span class="p">);</span> <span class="c1">// or return NO;</span>
     <span class="p">}</span>

     <span class="c1">// very long procedure</span>
     <span class="n">myString</span> <span class="o">=</span> <span class="p">[</span><span class="n">myString</span> <span class="nf">MD5</span><span class="p">];</span>
     <span class="p">...</span>
     <span class="k">return</span> <span class="n">success</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="4-pitfall--the-nil-comparisons">#4 Pitfall – the <code class="language-plaintext highlighter-rouge">nil</code> comparisons</h1>

<p>Imagine a code that tries to compare some objects and some of the variables are <code class="language-plaintext highlighter-rouge">nil</code>. Please look a minute at the example below:</p>
<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nb">nil</span> <span class="nf">isEqual</span><span class="p">:</span> <span class="err">@“</span><span class="n">string</span><span class="err">”</span><span class="p">]</span> <span class="c1">// returns 0</span>
<span class="p">[</span><span class="nb">nil</span> <span class="nf">isEqual</span><span class="p">:</span> <span class="nb">nil</span><span class="p">]</span> <span class="c1">// returns 0</span>
<span class="p">[</span><span class="s">@"string"</span> <span class="nf">isEqual</span><span class="p">:</span> <span class="nb">nil</span><span class="p">]</span> <span class="c1">// returns ?</span>
</code></pre></div></div>
<p>When comparing a <code class="language-plaintext highlighter-rouge">nil</code> value to a valid object it is good that the first two examples will return <code class="language-plaintext highlighter-rouge">0</code>. But how about the last one</p>
<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="s">@"string"</span> <span class="nf">isEqual</span><span class="p">:</span> <span class="nb">nil</span><span class="p">]</span>
</code></pre></div></div>

<p>It’s not clear how it will behave from a developers point of view. The isEqual: method is an Apple’s internal implementation, so it can throw an unhandled exception or it may crach or it may return simply 0. The message for that example is simple, when comparing objects like above, please DO CHECKS! :)</p>

<p>Ok, let’s take another example of nil comparisons. Please familiarize with a below code:</p>

<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// From Apple Documentation - NSComparisonResult</span>

<span class="k">enum</span> <span class="p">{</span>
 <span class="n">NSOrderedAscending</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
 <span class="n">NSOrderedSame</span><span class="p">,</span>
 <span class="n">NSOrderedDescending</span> 
<span class="p">};</span>
<span class="k">typedef</span> <span class="n">NSInteger</span> <span class="n">NSComparisonResult</span><span class="p">;</span>

<span class="c1">// How about these?</span>
<span class="p">[</span><span class="s">@"string"</span> <span class="nf">compare</span><span class="p">:</span><span class="s">@"string"</span><span class="p">];</span> <span class="c1">// 1</span>
<span class="p">[</span><span class="nb">nil</span> <span class="nf">compare</span><span class="p">:</span><span class="s">@"string"</span><span class="p">];</span>       <span class="c1">// 2</span>
<span class="p">[</span><span class="s">@"string"</span> <span class="nf">compare</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>       <span class="c1">// 3</span>
</code></pre></div></div>

<p>Do you know already what are going to be the return values for the examples in 1., 2. and 3. line ? Look at the solution:</p>
<div class="language-objc highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="s">@"string"</span> <span class="nf">compare</span><span class="p">:</span><span class="s">@"string"</span><span class="p">];</span> <span class="c1">//returns 0 == NSOrderedSame</span>
<span class="p">[</span><span class="nb">nil</span> <span class="nf">compare</span><span class="p">:</span><span class="s">@"string"</span><span class="p">];</span>       <span class="c1">//returns 0 == NSOrderedSame</span>
<span class="p">[</span><span class="s">@"string"</span> <span class="nf">compare</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>       <span class="c1">//returns 0 == NSOrderedSame</span>

<span class="c1">// WAT???</span>
</code></pre></div></div>
<p>Yes, I know some of you may get frustrated, why this language accepts this? The answer is simple, there are cons and pros of such <code class="language-plaintext highlighter-rouge">nil</code> value architecture and sending messages to the objects. Yet, the solution is very simple: we have to do <code class="language-plaintext highlighter-rouge">nil</code> checks, because it’s not safe – the algorithm may behave unstable.</p>]]></content><author><name>Piotr Chojnowski</name></author><category term="pitfalls" /><category term="code" /><category term="objective-c" /><category term="xcode" /><category term="ios" /><summary type="html"><![CDATA[Today I will describe some most common pitfalls in Objective-C that, a beginner developer can learn about and the advanced developer can refresh his information about it.]]></summary></entry></feed>