<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://kamwysocki.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://kamwysocki.com/" rel="alternate" type="text/html" /><updated>2026-05-04T20:40:11+00:00</updated><id>https://kamwysocki.com/feed.xml</id><title type="html">Kamil Wysocki</title><subtitle>A blog about technology and stuff related</subtitle><entry><title type="html">Swift: Decode different objects from JSON array</title><link href="https://kamwysocki.com/decode-dynamic-objects-from-array/" rel="alternate" type="text/html" title="Swift: Decode different objects from JSON array" /><published>2023-07-03T20:00:00+00:00</published><updated>2023-07-03T20:00:00+00:00</updated><id>https://kamwysocki.com/decode-dynamic-objects-from-array</id><content type="html" xml:base="https://kamwysocki.com/decode-dynamic-objects-from-array/"><![CDATA[<h1 id="decoding-different-objects-from-json-array-in-swift">Decoding different objects from JSON array in Swift</h1>

<h2 id="problem-decode-objects-from-an-array-with-different-objects">Problem: Decode objects from an array with different objects</h2>

<p><img src="/assets/posts/decode-different-objects/different_objects.png" alt="title image &gt;" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Car</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">manufacturer</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">let</span> <span class="nv">model</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">Person</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">let</span> <span class="nv">lastName</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">json</span> <span class="o">=</span> <span class="s">"""
{
    "</span><span class="n">information_array</span><span class="s">": [
        {
            "</span><span class="n">manufacturer</span><span class="s">": "</span><span class="kt">Audi</span><span class="s">",
            "</span><span class="n">model</span><span class="s">": "</span><span class="kt">A3</span><span class="s">"
        },
        {
            "</span><span class="n">name</span><span class="s">": "</span><span class="kt">John</span><span class="s">",
            "</span><span class="n">lastName</span><span class="s">": "</span><span class="kt">Doe</span><span class="s">"
        },
        {
            "</span><span class="n">weatherType</span><span class="s">": "</span><span class="n">windy</span><span class="s">",
            "</span><span class="n">degrees</span><span class="s">": "</span><span class="mi">10</span><span class="s">",
            "</span><span class="n">degreesType</span><span class="s">": "</span><span class="n">celcius</span><span class="s">"
        }
    ]
}
"""</span>
</code></pre></div></div>

<h2 id="solution">Solution</h2>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">OptionalDecodable</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">base</span><span class="p">:</span> <span class="kt">T</span><span class="p">?</span>

    <span class="nf">init</span><span class="p">(</span><span class="n">from</span> <span class="nv">decoder</span><span class="p">:</span> <span class="kt">Decoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">container</span> <span class="o">=</span> <span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">singleValueContainer</span><span class="p">()</span>
        <span class="k">self</span><span class="o">.</span><span class="n">base</span> <span class="o">=</span> <span class="k">try</span><span class="p">?</span> <span class="n">container</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Decoder</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="n">decodeObject</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">()</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">container</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">singleValueContainer</span><span class="p">()</span>
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">object</span> <span class="o">=</span> <span class="k">try</span> <span class="n">container</span><span class="o">.</span><span class="nf">decode</span><span class="p">([</span><span class="kt">OptionalDecodable</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">]</span><span class="o">.</span><span class="k">self</span><span class="p">)</span><span class="o">.</span><span class="nf">compactMap</span><span class="p">({</span> <span class="nv">$0</span><span class="o">.</span><span class="n">base</span> <span class="p">})</span><span class="o">.</span><span class="n">first</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">let</span> <span class="nv">context</span> <span class="o">=</span> <span class="kt">DecodingError</span><span class="o">.</span><span class="kt">Context</span><span class="p">(</span><span class="nv">codingPath</span><span class="p">:</span> <span class="n">container</span><span class="o">.</span><span class="n">codingPath</span><span class="p">,</span>
                                                <span class="nv">debugDescription</span><span class="p">:</span> <span class="s">"Value for type </span><span class="se">\(</span><span class="nf">type</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">)</span><span class="se">)</span><span class="s"> not found"</span><span class="p">)</span>
            <span class="k">throw</span> <span class="kt">DecodingError</span><span class="o">.</span><span class="nf">valueNotFound</span><span class="p">(</span><span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">object</span>
    <span class="p">}</span>
    
    <span class="kd">func</span> <span class="n">decodeObjects</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">()</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">T</span><span class="p">]</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">container</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">singleValueContainer</span><span class="p">()</span>
        <span class="k">let</span> <span class="nv">objects</span> <span class="o">=</span> <span class="k">try</span> <span class="n">container</span><span class="o">.</span><span class="nf">decode</span><span class="p">([</span><span class="kt">OptionalDecodable</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">]</span><span class="o">.</span><span class="k">self</span><span class="p">)</span><span class="o">.</span><span class="nf">compactMap</span><span class="p">({</span> <span class="nv">$0</span><span class="o">.</span><span class="n">base</span> <span class="p">})</span>
        <span class="k">return</span> <span class="n">objects</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContainerObject</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">car</span><span class="p">:</span> <span class="kt">Car</span>
    <span class="k">let</span> <span class="nv">person</span><span class="p">:</span> <span class="kt">Person</span>

    <span class="kd">enum</span> <span class="kt">CodingKeys</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="kt">CodingKey</span> <span class="p">{</span>
        <span class="k">case</span> <span class="n">infoArray</span> <span class="o">=</span> <span class="s">"information_array"</span>
    <span class="p">}</span>

    <span class="nf">init</span><span class="p">(</span><span class="n">from</span> <span class="nv">decoder</span><span class="p">:</span> <span class="kt">Decoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">container</span> <span class="o">=</span> <span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">container</span><span class="p">(</span><span class="nv">keyedBy</span><span class="p">:</span> <span class="kt">CodingKeys</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">arrayDecoder</span> <span class="o">=</span> <span class="k">try</span> <span class="n">container</span><span class="o">.</span><span class="nf">superDecoder</span><span class="p">(</span><span class="nv">forKey</span><span class="p">:</span> <span class="o">.</span><span class="n">infoArray</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">car</span> <span class="o">=</span> <span class="k">try</span> <span class="n">arrayDecoder</span><span class="o">.</span><span class="nf">decodeObject</span><span class="p">()</span>
        <span class="k">self</span><span class="o">.</span><span class="n">person</span> <span class="o">=</span> <span class="k">try</span> <span class="n">arrayDecoder</span><span class="o">.</span><span class="nf">decodeObject</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="iOS" /><category term="swift" /><category term="JSON" /><category term="decoding" /><category term="maping" /><summary type="html"><![CDATA[Decoding different objects from JSON array in Swift]]></summary></entry><entry><title type="html">What is new in Swift 4.2 - my summary</title><link href="https://kamwysocki.com/whats-new-in-swift42/" rel="alternate" type="text/html" title="What is new in Swift 4.2 - my summary" /><published>2018-06-06T20:00:00+00:00</published><updated>2018-06-06T20:00:00+00:00</updated><id>https://kamwysocki.com/whats-new-in-swift42</id><content type="html" xml:base="https://kamwysocki.com/whats-new-in-swift42/"><![CDATA[<p><img src="/assets/posts/whatisnewinswift-mysummary/swift_image.png" alt="" /></p>

<p>I just have watched the What’s new in Swift from WWDC 2018 and I thought it is a great motivation to write a blog post about this talk and summarize what I learned.</p>

<p>And here are some new Swift 4.2 features that I really liked.</p>

<p>Hope you will enjoy! 🤓</p>

<h2 id="se-0194-derived-collection-of-enum-cases">SE-0194 Derived Collection of Enum Cases</h2>

<p>In case we need to print all available enum values, we had to create some helper variable that includes all enum cases. For example, a static array called <code class="language-plaintext highlighter-rouge">allCases</code>. A big drawback in that approach is that we need to remember to update the <code class="language-plaintext highlighter-rouge">allCases</code> array every time when we modify enum cases.</p>

<p>Swift 4.1 approach:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">CarType</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">sedan</span>
    <span class="k">case</span> <span class="n">crossover</span>
    <span class="k">case</span> <span class="n">hothatch</span>
    <span class="k">case</span> <span class="n">muscle</span>
    <span class="k">case</span> <span class="n">miniVan</span>

    <span class="kd">static</span> <span class="k">var</span> <span class="nv">allCases</span> <span class="p">:</span> <span class="o">=</span> <span class="p">[</span><span class="o">.</span><span class="n">sedan</span><span class="p">,</span> <span class="o">.</span><span class="n">crossover</span><span class="p">,</span> <span class="o">.</span><span class="n">hothatch</span><span class="p">,</span> <span class="o">.</span><span class="n">muscle</span><span class="p">,</span> <span class="n">miniVan</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>in Swift 4.2 we can work with <code class="language-plaintext highlighter-rouge">CaseIterable</code> protocol which does all the work for us! Please take a look at the below example:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// CaseIterable protocol gave us a `allCases` variable, which is an array of all cases in the Enum.</span>

<span class="kd">enum</span> <span class="kt">CarType</span> <span class="p">:</span> <span class="kt">CaseIterable</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">sedan</span>
    <span class="k">case</span> <span class="n">crossover</span>
    <span class="k">case</span> <span class="n">hothatch</span>
    <span class="k">case</span> <span class="n">muscle</span>
    <span class="k">case</span> <span class="n">miniVan</span>

    <span class="c1">//there is no need to add `allCases` variable. `CaseIterable` protocol do the job!</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">type</span> <span class="k">in</span> <span class="kt">CarType</span><span class="o">.</span><span class="n">allCases</span> <span class="p">{</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">type</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="conditional-conformance">Conditional Conformance</h2>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">arrayOfArrays</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">],[</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">],[</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">]]</span>

<span class="n">arrayOfArrays</span><span class="o">.</span><span class="nf">contains</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span> <span class="c1">// return false in Swift 4.1</span>

<span class="n">arrayOfArrays</span><span class="o">.</span><span class="nf">contains</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span> <span class="c1">// now it returns True because of fact that the elements in the array conforms to Equatable protocol</span>
</code></pre></div></div>

<p>It will work with <code class="language-plaintext highlighter-rouge">Optional</code>, <code class="language-plaintext highlighter-rouge">Dictionary</code> types as well.
The conditional conformance works in the same way with <code class="language-plaintext highlighter-rouge">Hashable</code>, <code class="language-plaintext highlighter-rouge">Encodable</code> and <code class="language-plaintext highlighter-rouge">Decodable</code> protocols.
So for example, because <code class="language-plaintext highlighter-rouge">Int</code> is <code class="language-plaintext highlighter-rouge">Hashable</code>, which means in that case that <code class="language-plaintext highlighter-rouge">Int?</code> is <code class="language-plaintext highlighter-rouge">Hashable</code> too, and as a result the <code class="language-plaintext highlighter-rouge">[Int?]</code> is <code class="language-plaintext highlighter-rouge">Hashable</code> as well!</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">s</span><span class="p">:</span> <span class="kt">Set</span><span class="o">&lt;</span><span class="p">[</span><span class="kt">Int</span><span class="p">?]</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="kc">nil</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span><span class="p">]]</span>
<span class="n">s</span><span class="o">.</span><span class="nf">contains</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="kc">nil</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span> <span class="c1">// returns true</span>
</code></pre></div></div>

<h2 id="bool-toggle">Bool toggle</h2>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">isTheWeatherNice</span> <span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">true</span>
<span class="nf">print</span><span class="p">(</span><span class="n">isTheWeatherNice</span><span class="p">)</span> <span class="c1">// prints true</span>
<span class="c1">//now it's starts to rain</span>
<span class="n">isTheWeatherNice</span><span class="o">.</span><span class="nf">toggle</span><span class="p">()</span> <span class="c1">// it will change the bool value.</span>
<span class="nf">print</span><span class="p">(</span><span class="n">isTheWeatherNice</span><span class="p">)</span> <span class="c1">// prints false</span>
</code></pre></div></div>

<p>Small, but in my opinion -  very nice feature. I meet that extension for the first time while reading <a href="https://www.objc.io/blog/2018/01/16/toggle-extension-on-bool/">that objc.io blog posts</a>.</p>

<p>Now it’s built into Swift 4.2. 🎉</p>

<h2 id="hashable-protocol">Hashable protocol</h2>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">hash</span><span class="p">(</span><span class="n">into</span> <span class="nv">hasher</span><span class="p">:</span> <span class="k">inout</span> <span class="kt">Hasher</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In Swift 4.2 we don’t have to provide custom algorithms for <code class="language-plaintext highlighter-rouge">hashValue</code>. Now swift handles a hash method quality with run performance. 
Important thing is that the <code class="language-plaintext highlighter-rouge">hashValue</code> use the random per-process seed which is created at the every app starts.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">City</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">name</span> <span class="p">:</span> <span class="kt">String</span>
    <span class="k">let</span> <span class="nv">state</span> <span class="p">:</span> <span class="kt">String</span>
    <span class="k">let</span> <span class="nv">population</span> <span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
<span class="kd">extension</span> <span class="kt">City</span> <span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">hash</span><span class="p">(</span><span class="n">into</span> <span class="nv">hasher</span><span class="p">:</span> <span class="k">inout</span> <span class="kt">Hasher</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">name</span><span class="o">.</span><span class="nf">hash</span><span class="p">(</span><span class="nv">into</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">hasher</span><span class="p">)</span>
        <span class="n">state</span><span class="o">.</span><span class="nf">hash</span><span class="p">(</span><span class="nv">into</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">hasher</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="k">let</span> <span class="nv">warsaw</span> <span class="o">=</span> <span class="kt">City</span><span class="p">(</span><span class="nv">name</span> <span class="p">:</span> <span class="s">"Warsaw"</span><span class="p">,</span> <span class="nv">state</span><span class="p">:</span> <span class="s">"Mazowieckie"</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">warsaw</span><span class="o">.</span><span class="n">hashValue</span><span class="p">)</span> <span class="c1">// will print hash value, using the Swift algorithms from hash function.</span>
</code></pre></div></div>

<p>⚠️
In that approach, you should change the code that relates to the <code class="language-plaintext highlighter-rouge">hashValue</code> as a constant. In every application run, the hash value will be different.
⚠️</p>

<h2 id="se-0202-random-unification">SE-0202 Random Unification</h2>

<p>Swift 4.1 approach:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">randomIntFrom1to10</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="p">(</span><span class="nf">arc4random</span><span class="p">()</span> <span class="o">%</span> <span class="mi">10</span><span class="p">)</span> <span class="c1">// return random number is the 1...10</span>
</code></pre></div></div>

<p>But in Swift 4.2 there is no need to use <code class="language-plaintext highlighter-rouge">arc4random()</code> anymore. 🎉</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">randomIntFrom0To20</span> <span class="o">=</span> <span class="kt">Int</span><span class="o">.</span><span class="nf">random</span><span class="p">(</span><span class="nv">in</span><span class="p">:</span> <span class="mi">0</span> <span class="o">..&lt;</span> <span class="mi">20</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">randomFloat</span> <span class="o">=</span> <span class="kt">Float</span><span class="o">.</span><span class="nf">random</span><span class="p">(</span><span class="nv">in</span><span class="p">:</span> <span class="mi">0</span> <span class="o">..&lt;</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p>Super cool thing is that we can get a random value from Collection types like <code class="language-plaintext highlighter-rouge">Array</code> or <code class="language-plaintext highlighter-rouge">Dictionary</code>.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">names</span> <span class="o">=</span> <span class="p">[</span><span class="s">"John"</span><span class="p">,</span> <span class="s">"Paul"</span><span class="p">,</span> <span class="s">"Peter"</span><span class="p">,</span> <span class="s">"Tim"</span><span class="p">]</span>
<span class="n">names</span><span class="o">.</span><span class="nf">randomElement</span><span class="p">()</span><span class="o">!</span> 

<span class="k">let</span> <span class="nv">playerNumberToName</span> <span class="p">:</span> <span class="p">[</span><span class="kt">Int</span><span class="p">:</span> <span class="kt">String</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">9</span><span class="p">:</span> <span class="s">"Lewandowski"</span><span class="p">,</span> <span class="mi">7</span><span class="p">:</span> <span class="s">"Ronaldo"</span><span class="p">]</span>
<span class="n">playerNumberToName</span><span class="o">.</span><span class="nf">randomElement</span><span class="p">()</span><span class="o">!</span> 
</code></pre></div></div>
<p>As you might notice, the <code class="language-plaintext highlighter-rouge">randomElement</code> function returns an Optional, because of the case where we call this function on the empty collection.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">emptyCollection</span> <span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">emptyCollection</span><span class="o">.</span><span class="nf">randomElement</span><span class="p">()</span> <span class="c1">// retuns nil</span>
</code></pre></div></div>

<p>Another new function are <code class="language-plaintext highlighter-rouge">shuffle</code> or <code class="language-plaintext highlighter-rouge">shuffled</code> functions.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">names</span> <span class="o">=</span> <span class="p">[</span><span class="s">"John"</span><span class="p">,</span> <span class="s">"Paul"</span><span class="p">,</span> <span class="s">"Peter"</span><span class="p">,</span> <span class="s">"Tim"</span><span class="p">]</span>
<span class="k">let</span> <span class="nv">shuffledNames</span> <span class="o">=</span> <span class="n">names</span><span class="o">.</span><span class="nf">shuffled</span><span class="p">()</span> <span class="c1">// returns an array of names in shuffled order.</span>
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>

<p>It would be great to use those features in stable versions. My impressions from Xcode 10(beta) and Swift 4.2 was pretty amazing. I highly recommend you to watch What’s new in Swift talk from WWDC 2018</p>

<p>Below you can find a link to a GitHub gist with all features described above.</p>

<p><a href="https://gist.github.com/kamwysoc/e9322c84fd4fa051cb747ec08193dc0d">https://gist.github.com/kamwysoc/e9322c84fd4fa051cb747ec08193dc0d</a></p>

<h4 id="source">Source</h4>
<ul>
  <li>
    <p><a href="https://developer.apple.com/videos/play/wwdc2018/401/">https://developer.apple.com/videos/play/wwdc2018/401/</a></p>
  </li>
  <li>
    <p><a href="https://swift.org/documentation/">https://swift.org/documentation/</a></p>
  </li>
</ul>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="iOS" /><category term="Swift" /><category term="WWDC" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Implementing a simple pedometer using Swift</title><link href="https://kamwysocki.com/coremotion-pedometer-swift/" rel="alternate" type="text/html" title="Implementing a simple pedometer using Swift" /><published>2017-12-08T17:00:00+00:00</published><updated>2017-12-08T17:00:00+00:00</updated><id>https://kamwysocki.com/coremotion-pedometer-swift</id><content type="html" xml:base="https://kamwysocki.com/coremotion-pedometer-swift/"><![CDATA[<p><img src="/assets/posts/coremotion-pedometer-swift/footsteps.jpg" alt="footsteps image" /></p>

<p>Ok… but what the pedometer is? Here you have a wikipedia definition:</p>

<blockquote>
  <p>A pedometer is a device, usually portable and electronic or electromechanical, that counts each step a person takes by detecting the motion of the person’s hands or hips.</p>
</blockquote>

<p>and YES, you can create your own pedometer using iOS framework called CoreMotion.</p>

<p>CoreMotion is a well-known iOS framework. As we could read in <a href="https://developer.apple.com/documentation/coremotion">docs</a> it processes accelerometer, gyroscope, pedometer environment-related events.
In this post I want to focus on the pedometer events and how to handle them.</p>

<h2 id="overview">Overview</h2>

<h3 id="cmpedometer">CMPedometer</h3>

<p>In order to use CoreMotion pedometer, we need to take a closer look at <code class="language-plaintext highlighter-rouge">CMPedometer</code> class. It allows the user to retrieve some information about steps taken in the past, for example: How many steps I have done for last 3 days? Another usage of <code class="language-plaintext highlighter-rouge">CMPedometer</code> class is to get the live updates about steps taken already.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kd">open</span> <span class="kd">func</span> <span class="nf">queryPedometerData</span><span class="p">(</span><span class="n">from</span> <span class="nv">start</span><span class="p">:</span> <span class="kt">Date</span><span class="p">,</span> <span class="n">to</span> <span class="nv">end</span><span class="p">:</span> <span class="kt">Date</span><span class="p">,</span> <span class="n">withHandler</span> <span class="nv">handler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="kt">CoreMotion</span><span class="o">.</span><span class="kt">CMPedometerHandler</span><span class="p">)</span>

<span class="kd">open</span> <span class="kd">func</span> <span class="nf">startUpdates</span><span class="p">(</span><span class="n">from</span> <span class="nv">start</span><span class="p">:</span> <span class="kt">Date</span><span class="p">,</span> <span class="n">withHandler</span> <span class="nv">handler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="kt">CoreMotion</span><span class="o">.</span><span class="kt">CMPedometerHandler</span><span class="p">)</span>

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

<h3 id="cmpedometerdata">CMPedometerData</h3>

<p>Another class that should catch our attention is <code class="language-plaintext highlighter-rouge">CMPedometerData</code>. This class represents data that will be sent with every update in the above functions. It contains a lot of useful information like:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">numberOfSteps: NSNumber?</code></li>
  <li><code class="language-plaintext highlighter-rouge">distance: NSNumber?</code></li>
  <li><code class="language-plaintext highlighter-rouge">currentPace: NSNumber?</code></li>
  <li><code class="language-plaintext highlighter-rouge">floorsAscended: NSNumber?</code></li>
  <li><code class="language-plaintext highlighter-rouge">floorsDescended: NSNumber?</code></li>
</ul>

<h3 id="cmmotionactivitymanager">CMMotionActivityManager</h3>

<p>If we want to start counting steps, it will be good to know about what kind of activity our user is doing at the moment. Here with some help comes the <code class="language-plaintext highlighter-rouge">CMMotionActivityManager</code> class. Using th e instance of this class we are able to get updates about the user activity type. In order to do this we should call:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">open</span> <span class="kd">func</span> <span class="nf">startActivityUpdates</span><span class="p">(</span><span class="n">to</span> <span class="nv">queue</span><span class="p">:</span> <span class="kt">OperationQueue</span><span class="p">,</span> <span class="n">withHandler</span> <span class="nv">handler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="kt">CoreMotion</span><span class="o">.</span><span class="kt">CMMotionActivityHandler</span><span class="p">)</span>
</code></pre></div></div>

<p>and the result of that is getting updates with <code class="language-plaintext highlighter-rouge">CMMotionActivity</code> which represents  data for a single motion event update. This data is a pack of bool values:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">stationary: Bool</code></li>
  <li><code class="language-plaintext highlighter-rouge">walking: Bool</code></li>
  <li><code class="language-plaintext highlighter-rouge">running: Bool</code></li>
  <li><code class="language-plaintext highlighter-rouge">automotive: Bool</code></li>
  <li><code class="language-plaintext highlighter-rouge">cycling: Bool</code></li>
  <li><code class="language-plaintext highlighter-rouge">unknown: Bool</code></li>
</ul>

<h2 id="code-step-by-step">Code step by step…</h2>

<h3 id="1-add-nsmotionusagedescription-to-your-infoplist">1. Add <code class="language-plaintext highlighter-rouge">NSMotionUsageDescription</code> to your <code class="language-plaintext highlighter-rouge">info.plist</code></h3>

<p>As we can read in <a href="https://developer.apple.com/documentation/coremotion">Apple docs</a></p>

<blockquote>
  <p>Important
An iOS app linked on or after iOS 10.0 must include usage description keys in its Info.plist file for the types of data it needs. Failure to include these keys will cause the app to crash. To &gt;access motion and fitness data specifically, it must include NSMotionUsageDescription.</p>
</blockquote>

<p>So add to your <code class="language-plaintext highlighter-rouge">info.plist</code> <code class="language-plaintext highlighter-rouge">NSMotionUsageDescription</code> key modifying plain file:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;key&gt;</span>NSMotionUsageDescription<span class="nt">&lt;/key&gt;</span>
<span class="nt">&lt;string&gt;</span>In order to count steps I need an access to your pedometer<span class="nt">&lt;/string&gt;</span>
</code></pre></div></div>

<p>or adding new key via Xcode</p>

<p><img src="/assets/posts/coremotion-pedometer-swift/info-plist-motion-usage.png" alt="info plist motion usage description" /></p>

<h3 id="2-create-an-cmmotionactivitymanager-and-cmpedometer-instances">2. Create an <code class="language-plaintext highlighter-rouge">CMMotionActivityManager</code> and <code class="language-plaintext highlighter-rouge">CMPedometer</code> instances</h3>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="k">let</span> <span class="nv">activityManager</span> <span class="o">=</span> <span class="kt">CMMotionActivityManager</span><span class="p">()</span>
<span class="kd">private</span> <span class="k">let</span> <span class="nv">pedometer</span> <span class="o">=</span> <span class="kt">CMPedometer</span><span class="p">()</span>
</code></pre></div></div>

<h3 id="3-create-a-method-for-tracking-activity-events">3. Create a method for tracking activity events</h3>

<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">startTrackingActivityType</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">activityManager</span><span class="o">.</span><span class="nf">startActivityUpdates</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">OperationQueue</span><span class="o">.</span><span class="n">main</span><span class="p">)</span> <span class="p">{</span>
      <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="p">(</span><span class="nv">activity</span><span class="p">:</span> <span class="kt">CMMotionActivity</span><span class="p">?)</span> <span class="k">in</span>

      <span class="k">guard</span> <span class="k">let</span> <span class="nv">activity</span> <span class="o">=</span> <span class="n">activity</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
      <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="k">async</span> <span class="p">{</span>
          <span class="k">if</span> <span class="n">activity</span><span class="o">.</span><span class="n">walking</span> <span class="p">{</span>
              <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">activityTypeLabel</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"Walking"</span>
          <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">activity</span><span class="o">.</span><span class="n">stationary</span> <span class="p">{</span>
              <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">activityTypeLabel</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"Stationary"</span>
          <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">activity</span><span class="o">.</span><span class="n">running</span> <span class="p">{</span>
              <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">activityTypeLabel</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"Running"</span>
          <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">activity</span><span class="o">.</span><span class="n">automotive</span> <span class="p">{</span>
              <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">activityTypeLabel</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"Automotive"</span>
          <span class="p">}</span>
      <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="4-create-a-method-for-steps-counting-updates">4. Create a method for steps counting updates</h3>

<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">startCountingSteps</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">pedometer</span><span class="o">.</span><span class="nf">startUpdates</span><span class="p">(</span><span class="nv">from</span><span class="p">:</span> <span class="kt">Date</span><span class="p">())</span> <span class="p">{</span>
      <span class="p">[</span><span class="k">weak</span> <span class="k">self</span><span class="p">]</span> <span class="n">pedometerData</span><span class="p">,</span> <span class="n">error</span> <span class="k">in</span>
      <span class="k">guard</span> <span class="k">let</span> <span class="nv">pedometerData</span> <span class="o">=</span> <span class="n">pedometerData</span><span class="p">,</span> <span class="n">error</span> <span class="o">==</span> <span class="kc">nil</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>

      <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="k">async</span> <span class="p">{</span>
          <span class="k">self</span><span class="p">?</span><span class="o">.</span><span class="n">stepsCountLabel</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">pedometerData</span><span class="o">.</span><span class="n">numberOfSteps</span><span class="o">.</span><span class="n">stringValue</span>
      <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="5-start-getting-updates">5. Start getting updates</h3>

<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">startUpdating</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">if</span> <span class="kt">CMMotionActivityManager</span><span class="o">.</span><span class="nf">isActivityAvailable</span><span class="p">()</span> <span class="p">{</span>
      <span class="nf">startTrackingActivityType</span><span class="p">()</span>
  <span class="p">}</span>

  <span class="k">if</span> <span class="kt">CMPedometer</span><span class="o">.</span><span class="nf">isStepCountingAvailable</span><span class="p">()</span> <span class="p">{</span>
      <span class="nf">startCountingSteps</span><span class="p">()</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><img src="/assets/posts/coremotion-pedometer-swift/steps-demo.gif" alt="demo" /></p>

<h2 id="conclusion">Conclusion</h2>

<p>CoreMotion is a powerful framework and besides a pedometer it allows you to work with a plenty useful data from accelerometer and gyroscope as well
You can find an example project at <a href="https://github.com/bright/Pedometer-Swift">Github repository</a></p>

<p>Hope you like the post, feel free to share.</p>

<p>This post was primarly posted on my company <a href="https://brightinventions.pl/blog/coremotion-pedometer-swift/">blog</a></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="iOS" /><category term="Swift" /><category term="CoreMotion" /><category term="pedometer" /><category term="tutorial" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Design Patterns with Swift: Facade pattern</title><link href="https://kamwysocki.com/swift-facade-pattern/" rel="alternate" type="text/html" title="Design Patterns with Swift: Facade pattern" /><published>2017-11-16T00:40:00+00:00</published><updated>2017-11-16T00:40:00+00:00</updated><id>https://kamwysocki.com/swift-facade-pattern</id><content type="html" xml:base="https://kamwysocki.com/swift-facade-pattern/"><![CDATA[<p><img src="/assets/posts/swift-facade-pattern/facade.jpg" alt="facade image" /></p>

<h2 id="about-the-pattern">About the pattern</h2>

<p>Facade pattern is one of the Structural Patterns. The main aim of it is to hide the complexity of a system, class or logic and provide all functionalities behind a simple interface.
Commonly, Facade is implemented in a way that one class is related to other classes which represents a system logic. Please take a look at the diagram:</p>

<p><img src="/assets/posts/swift-facade-pattern/diagram.png" alt="diagram" /></p>

<p>As you can see, there is one class called <code class="language-plaintext highlighter-rouge">Facade</code> which separates the logic from <code class="language-plaintext highlighter-rouge">LogicA</code>, <code class="language-plaintext highlighter-rouge">LogicB</code>, <code class="language-plaintext highlighter-rouge">LogicC</code> classes. As a result our client only call the <code class="language-plaintext highlighter-rouge">Facade</code> class in order to execute some methods that are implemented in other classes.</p>

<h2 id="implementation">Implementation</h2>

<p>Let’s imagine a simple scenario. You have already created a great app called <code class="language-plaintext highlighter-rouge">Super-Photo</code>. One of the core features of your app is saving/converting assets/posts with <code class="language-plaintext highlighter-rouge">JPEG</code> or <code class="language-plaintext highlighter-rouge">PNG</code> extension. In order to do this you want to save <code class="language-plaintext highlighter-rouge">UIImage</code> representation in two ways. One is saving it as a <code class="language-plaintext highlighter-rouge">PNG</code> type, the second is saving it as a <code class="language-plaintext highlighter-rouge">JPEG</code> file type.</p>

<p>Fistly, in order to handle our image types and possible errors in our code - it will be nice to have two enums that will make our code cleaner and more readable.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">ImageSaverError</span><span class="p">:</span> <span class="kt">Error</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">couldNotCreateDestinationPath</span>
    <span class="k">case</span> <span class="n">couldNotCreateJPEGDataFromImage</span>
    <span class="k">case</span> <span class="n">couldNotCreatePNGDataFromImage</span>
    <span class="k">case</span> <span class="n">couldNotSaveImageInDestinationPath</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">ImageType</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">png</span>
    <span class="k">case</span> <span class="nf">jpeg</span><span class="p">(</span><span class="nv">compressionQuality</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>On the next step you will need to create a class that will handle a data providing for each photo extension:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">ImageDataProvider</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="n">from</span> <span class="nv">image</span><span class="p">:</span> <span class="kt">UIImage</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">ImageType</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span> <span class="p">{</span>
        <span class="k">switch</span> <span class="n">type</span> <span class="p">{</span>
        <span class="k">case</span> <span class="o">.</span><span class="nf">jpeg</span><span class="p">(</span><span class="k">let</span> <span class="nv">compressionQuality</span><span class="p">):</span>
            <span class="k">return</span> <span class="k">try</span> <span class="nf">jpegData</span><span class="p">(</span><span class="nv">from</span><span class="p">:</span> <span class="n">image</span><span class="p">,</span> <span class="nv">compressionQuality</span><span class="p">:</span> <span class="n">compressionQuality</span><span class="p">)</span>
        <span class="k">case</span> <span class="o">.</span><span class="nv">png</span><span class="p">:</span>
            <span class="k">return</span> <span class="k">try</span> <span class="nf">pngData</span><span class="p">(</span><span class="nv">from</span><span class="p">:</span> <span class="n">image</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">pngData</span><span class="p">(</span><span class="n">from</span> <span class="nv">image</span><span class="p">:</span> <span class="kt">UIImage</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span> <span class="p">{</span>
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">imageData</span> <span class="o">=</span> <span class="kt">UIImagePNGRepresentation</span><span class="p">(</span><span class="n">image</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">throw</span> <span class="kt">ImageSaverError</span><span class="o">.</span><span class="n">couldNotCreateJPEGDataFromImage</span> <span class="p">}</span>
        <span class="k">return</span> <span class="n">imageData</span>
    <span class="p">}</span>

    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">jpegData</span><span class="p">(</span><span class="n">from</span> <span class="nv">image</span><span class="p">:</span> <span class="kt">UIImage</span><span class="p">,</span> <span class="nv">compressionQuality</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span> <span class="p">{</span>
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">imageData</span> <span class="o">=</span> <span class="kt">UIImageJPEGRepresentation</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">compressionQuality</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">throw</span> <span class="kt">ImageSaverError</span><span class="o">.</span><span class="n">couldNotCreatePNGDataFromImage</span> <span class="p">}</span>
        <span class="k">return</span> <span class="n">imageData</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>As you’ve noticed, our <code class="language-plaintext highlighter-rouge">ImageDataProvider</code> takes <code class="language-plaintext highlighter-rouge">image</code> and <code class="language-plaintext highlighter-rouge">type</code> parameters and creates the image data with proper extension <code class="language-plaintext highlighter-rouge">JPEG</code> or <code class="language-plaintext highlighter-rouge">PNG</code>.</p>

<p>The last step is to create class which is needed to save <code class="language-plaintext highlighter-rouge">UIImage</code>. So let’s name it a <code class="language-plaintext highlighter-rouge">PathProvider</code>.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">PathProvider</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">createDestinationPath</span><span class="p">(</span><span class="nv">fileName</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">URL</span> <span class="p">{</span>
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">path</span> <span class="o">=</span> <span class="kt">FileManager</span><span class="o">.</span><span class="k">default</span><span class="o">.</span><span class="nf">urls</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="o">.</span><span class="n">documentDirectory</span><span class="p">,</span> <span class="nv">in</span><span class="p">:</span> <span class="o">.</span><span class="n">userDomainMask</span><span class="p">)</span><span class="o">.</span><span class="n">first</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="kt">ImageSaverError</span><span class="o">.</span><span class="n">couldNotCreateDestinationPath</span>
        <span class="p">}</span>
        <span class="k">let</span> <span class="nv">destinationPath</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">fileName</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">destinationPath</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Ok, so at the moment we have two classes with some logic inside. Now it’s time to create a facade for it!</p>

<p><img src="/assets/posts/swift-facade-pattern/do_this.gif" alt="let's do this" /></p>

<p>Create a class called <code class="language-plaintext highlighter-rouge">ImageSaverFacade</code> :</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">ImageSaverFacade</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">pathProvider</span> <span class="o">=</span> <span class="kt">PathProvider</span><span class="p">()</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">dataProvider</span> <span class="o">=</span> <span class="kt">ImageDataProvider</span><span class="p">()</span>

    <span class="kd">func</span> <span class="nf">save</span><span class="p">(</span><span class="nv">image</span><span class="p">:</span> <span class="kt">UIImage</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">ImageType</span><span class="p">,</span> <span class="nv">fileName</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">overwrite</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">destinationURL</span> <span class="o">=</span> <span class="k">try</span> <span class="n">pathProvider</span><span class="o">.</span><span class="nf">createDestinationPath</span><span class="p">(</span><span class="nv">fileName</span><span class="p">:</span> <span class="n">fileName</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">imageData</span> <span class="o">=</span> <span class="k">try</span> <span class="n">dataProvider</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">from</span><span class="p">:</span> <span class="n">image</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="n">type</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">writingOptions</span><span class="p">:</span> <span class="kt">Data</span><span class="o">.</span><span class="kt">WritingOptions</span> <span class="o">=</span> <span class="n">overwrite</span> <span class="p">?</span> <span class="p">(</span><span class="o">.</span><span class="n">atomic</span><span class="p">)</span> <span class="p">:</span> <span class="p">(</span><span class="o">.</span><span class="n">withoutOverwriting</span><span class="p">)</span>
        <span class="k">try</span> <span class="n">imageData</span><span class="o">.</span><span class="nf">write</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">destinationURL</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="n">writingOptions</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Our <code class="language-plaintext highlighter-rouge">ImageSaverFacade</code> class has two private objects of <code class="language-plaintext highlighter-rouge">PathProvider</code> and <code class="language-plaintext highlighter-rouge">ImageDataProvider</code> class. Because the client doesn’t need to know anything about logic inside, the only thing which <code class="language-plaintext highlighter-rouge">ImageSaverFacade</code> exposes to a public is one method:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">func save(image: UIImage, type: ImageType, fileName: String, overwrite: Bool) throws</code></li>
</ul>

<p>This method is the only thing that our client should care about.</p>

<p>Now let’s move on to the facade usage part:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">imageSaver</span> <span class="o">=</span> <span class="kt">ImageSaverFacade</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">image</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">"my_image"</span><span class="p">)</span><span class="o">!</span>
<span class="k">do</span> <span class="p">{</span>
    <span class="k">try</span> <span class="n">imageSaver</span><span class="o">.</span><span class="nf">save</span><span class="p">(</span><span class="nv">image</span><span class="p">:</span> <span class="n">image</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="o">.</span><span class="n">png</span><span class="p">,</span> <span class="nv">fileName</span><span class="p">:</span> <span class="s">"my_file_name"</span><span class="p">,</span> <span class="nv">overwrite</span><span class="p">:</span> <span class="kc">true</span><span class="p">)</span>
<span class="p">}</span> <span class="k">catch</span>  <span class="p">{</span>
    <span class="c1">//handle Error</span>
<span class="p">}</span>
<span class="c1">// or</span>
<span class="k">do</span> <span class="p">{</span>
    <span class="k">try</span> <span class="n">imageSaver</span><span class="o">.</span><span class="nf">save</span><span class="p">(</span><span class="nv">image</span><span class="p">:</span> <span class="n">image</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="o">.</span><span class="nf">jpeg</span><span class="p">(</span><span class="nv">compressionQuality</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">),</span> <span class="nv">fileName</span><span class="p">:</span> <span class="s">"my_file_name"</span><span class="p">,</span> <span class="nv">overwrite</span><span class="p">:</span> <span class="kc">false</span><span class="p">)</span>
<span class="p">}</span> <span class="k">catch</span>  <span class="p">{</span>
    <span class="c1">//handle Error</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>

<p>Please notice that our facade covers logic associated with <code class="language-plaintext highlighter-rouge">Data</code> providing and creating a valid <code class="language-plaintext highlighter-rouge">URL</code> for file destination. And because of that, it is super easy to save <code class="language-plaintext highlighter-rouge">UIImage</code> as <code class="language-plaintext highlighter-rouge">PNG</code> or <code class="language-plaintext highlighter-rouge">JPEG</code> using our <code class="language-plaintext highlighter-rouge">ImageSaverFacade</code>. Only thing to do is to pass the correct parameters to facade method.</p>

<p>Facade design pattern can be used in many cases. Facade creates for you a simple gateway to a complicated system. By using it you will definitely make your code simpler to understand and read.</p>

<p>This post was primarly posted on my company <a href="https://brightinventions.pl/blog/swift-facade-pattern/">blog</a></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="Swift" /><category term="iOS" /><category term="design patterns" /><category term="facade pattern" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">TeamCity for iOS project</title><link href="https://kamwysocki.com/teamcity-for-ios-project/" rel="alternate" type="text/html" title="TeamCity for iOS project" /><published>2017-11-11T00:40:00+00:00</published><updated>2017-11-11T00:40:00+00:00</updated><id>https://kamwysocki.com/teamcity-for-ios-project</id><content type="html" xml:base="https://kamwysocki.com/teamcity-for-ios-project/"><![CDATA[<p>Hi! Today’s topic will be about <a href="https://www.jetbrains.com/teamcity/">TeamCity</a> and how to provide continuous integration in your iOS project.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/title_image.jpg" alt="title image &gt;" /></p>

<h1 id="motivation">Motivation</h1>

<p>I have configured a TeamCity many times and for many projects. There are many advantages of using Continuous Integration system in your project development process. Also, there is a lot of alternatives to TeamCity like <a href="https://circleci.com/">CircleCI</a>, <a href="https://travis-ci.org/">TravisCI</a> and many more. But in this post I want to share with you TeamCity experience that I have gained at  <a href="https://brightinventions.pl">Bright Inventions</a>.</p>

<p>Every project that we start - we start from configuring Continuous Integration stuff and in our case we use TeamCity to handle that.</p>

<p>This post will be more like a tutorial that will guide you through all basic and most important steps in iOS project configuration. Also, I assume that you have already downloaded, and hosted your TeamCity service.</p>

<p>Hope you will like it!</p>

<h1 id="step-1-create-a-root-project">Step 1: Create a root project</h1>

<p>Firstly, you need to go to a page where your TeamCity is hosted. After loging-in, go to the Administration Page, click <code class="language-plaintext highlighter-rouge">Projects</code> tab in <code class="language-plaintext highlighter-rouge">Project-related Settings</code> section and click <code class="language-plaintext highlighter-rouge">Create project</code></p>

<p><img src="/assets/posts/teamcity-for-ios-project/create_project_step1.png" alt="project settings &lt;&gt;" /></p>

<p>after that you should a see configuration screen for Version Control that is used in your project.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/create_project.png" alt="create project version control" /></p>

<p>I prefer a way in which I will configure everything manually, but of course you can go with predefined sections like : <code class="language-plaintext highlighter-rouge">From GitHub</code>. <code class="language-plaintext highlighter-rouge">From Bitbucket Cloud</code> etc.
All you need to do in this step is to provide a Name of your project and then tap <code class="language-plaintext highlighter-rouge">Create</code></p>

<h1 id="step-2-add-vcs-root">Step 2: Add VCS root</h1>

<p>Of course, in order to build our project we need to provide sources to build.
Our TeamCity service should be able to fetch changes from the repository. If you’re using a GitHub, BitBucket or platforms similar to these, you have two ways:</p>

<ul>
  <li>Give credentials to account which has an access to the repository</li>
</ul>

<p>or</p>

<ul>
  <li>Generate a SSH key and use it to authorize TeamCity in GitHub/Bitbucket</li>
</ul>

<p>In this post I will show you how to configure it with uploading SSH key.</p>

<h3 id="generate-new-ssh-key">Generate new SSH key</h3>

<p><em>If you haven’t heard about generating SSH keys, or you don’t know what SSH keys really are, check <a href="https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/">this link</a></em></p>

<p>To generate new SSH keys you can use a terminal command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t rsa
</code></pre></div></div>

<p>next, provide a name for new key, and an optional passphrase, then in the directory in which you run <code class="language-plaintext highlighter-rouge">ssh-keygen -t rsa</code> command you should see two files. One is a public key with <code class="language-plaintext highlighter-rouge">.pub</code> extension, and the second - private one.
The public one will be used in your repository on github/bitbucket. The private key will be used in TeamCity service.</p>

<h3 id="use-generated-key-in-teamcity">Use generated key in TeamCity</h3>

<p>Go to an already created project, settings page and click <code class="language-plaintext highlighter-rouge">VCS SSH Keys</code> tab.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/ssh_section.png" alt="ssh section in TeamCity" /></p>

<p>Click on <code class="language-plaintext highlighter-rouge">Upload SSH Key</code>. After that you should see a pop-up window which allows you to upload the previously created SSH Key.
<em>Please keep in mind that you should upload a private part of your key, without <code class="language-plaintext highlighter-rouge">pub</code> extension</em>. If you choose correctly, click save and you should see a screen like this:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/ssh_uploaded_key.png" alt="uploaded ssh key" /></p>

<p>As you can see in <code class="language-plaintext highlighter-rouge">Usage</code> tab, the key is not used in the configuration yet.
In order to use it - you have to go through the next steps…</p>

<h3 id="configure-vcs-root">Configure VCS root</h3>

<p>Go to the already created project’s settings page. As you can notice in <code class="language-plaintext highlighter-rouge">SSH Keys</code> tab - appeared number ‘1’ - it means that we have one SSH key uploaded which is ready to use.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/vcs_root_section.png" alt="create project version control" /></p>

<p>Click on <code class="language-plaintext highlighter-rouge">VCS Roots</code> tab, and then <code class="language-plaintext highlighter-rouge">Create VC Root</code>.</p>

<p>In our case, in <code class="language-plaintext highlighter-rouge">Type of VCS</code> select <code class="language-plaintext highlighter-rouge">Git</code></p>

<p><img src="/assets/posts/teamcity-for-ios-project/type_of_vcs.png" alt="type of vcs" /></p>

<p>In <code class="language-plaintext highlighter-rouge">VCS root name</code> provide a name which will be:</p>

<blockquote>
  <p>A unique name to distinguish this VCS root from other roots.</p>
</blockquote>

<p>Next, in <code class="language-plaintext highlighter-rouge">Fetch URL</code> paste a link to your repository. <em>Please remember to paste here a SSH link type e.g <code class="language-plaintext highlighter-rouge">git@github.com:yournickname/yourrepositoryname.git</code></em></p>

<p><img src="/assets/posts/teamcity-for-ios-project/fetch_url.png" alt="fetch url in vcs config" /></p>

<p>Next, the most important thing, in <code class="language-plaintext highlighter-rouge">Authentication method</code> select <code class="language-plaintext highlighter-rouge">Uploaded Key</code> and choose a previously uploaded private ssh key for you repository.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/ssh_choose_uploaded_key.png" alt="fetch url in vcs config" /></p>

<p>Almost done. Now go to the end of the page and click <code class="language-plaintext highlighter-rouge">Test Connection</code>.</p>

<p>If you see screen like this:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/connection_failed.png" alt="fetch url in vcs config" /></p>

<p>it means that our public part of generated SSH key is not used in the repository, and that’s why you get <code class="language-plaintext highlighter-rouge">Auth failed</code> error. So, all you need to do is to add a public part of SSH Key in <code class="language-plaintext highlighter-rouge">Access keys</code> or <code class="language-plaintext highlighter-rouge">Deploy keys</code> in your repository.</p>

<p>Here you have links for Bitbucket and GitHub instructions how to do that:</p>

<p><a href="https://confluence.atlassian.com/bitbucket/use-access-keys-294486051.html">BitBucket - Use access keys</a></p>

<p><a href="https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys">GitHub - Deploy keys</a></p>

<p>If you have successfully uploaded public part of SSH Key, click <code class="language-plaintext highlighter-rouge">Test Connection</code> again, and I hope you will be able to see <code class="language-plaintext highlighter-rouge">Connection successful</code> alert. It means that TeamCity has an access to read your repository.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/connection_successful.png" alt="fetch url in vcs config" /></p>

<h1 id="step-3-create-build-configuration">Step 3: Create build configuration</h1>
<p>Ok, our VCS is configured. Now it’s time to create build configuration in TeamCity project. Build configuration is a kind of lane which specifies what type of build you provide in this lane.
It could be a lane for: compile your project and run unit tests or just compile a project or compile a project then create .ipa files and send it to iTunesConnect or even a separate lane for running UI tests.</p>

<p>Go to <code class="language-plaintext highlighter-rouge">General Settings</code> in you already created project and click <code class="language-plaintext highlighter-rouge">Create build configuration</code></p>

<p><img src="/assets/posts/teamcity-for-ios-project/create_build_configuration.png" alt="build configuration step 1" /></p>

<p>In next screen, once again, choose <code class="language-plaintext highlighter-rouge">Manually</code> option and name your new build configuration. In our case let’s name it <code class="language-plaintext highlighter-rouge">[Develop] Build &amp; Test</code>. The name is meaningful and means that our lane will build iOS project with develop configuration - <code class="language-plaintext highlighter-rouge">Develop</code> and also, provides an short information what this lane will do - <code class="language-plaintext highlighter-rouge">Build &amp; Test</code> which means that we compile our project and run unit tests.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_configuration_name.png" alt="build configuration step 2" /></p>

<p>Click <code class="language-plaintext highlighter-rouge">Create</code> and after that you should see:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/attach_vcs_root.png" alt="build configuration step 2" /></p>

<p>Here, select a previously created <code class="language-plaintext highlighter-rouge">VCS Root</code> and click <code class="language-plaintext highlighter-rouge">Attach</code>.</p>

<p>All done, our build configuration is connected with VCS.</p>

<h1 id="step-4-configure-build-steps-for-configuration">Step 4: Configure build steps for configuration</h1>

<p>Now it’s time to define  steps in our build configuration. What are the build steps? They are a sequence of instructions which TeamCity will run on our agent machine. Put it simply, it could be something like:</p>

<ol>
  <li>Fetch new changes from repo</li>
  <li>Install dependencies (cocoapods, bundle install and stuff like that)</li>
  <li>Compile project using script (xcodebuild, fastlane)</li>
</ol>

<p><em>Please remember that build steps depend on how you configure your iOS project. In my example I used <a href="https://fastlane.tools">Fastlane</a>, and <a href="http://bundler.io/">Bundler</a> to manage versions of gems installed in iOS project.</em></p>

<p>In order to create build steps go to <code class="language-plaintext highlighter-rouge">Build configuration Settings</code> and tap <code class="language-plaintext highlighter-rouge">Build Steps</code></p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_steps_1.png" alt="build configuration step 2" /></p>

<p>Click on <code class="language-plaintext highlighter-rouge">Add build step</code>, and on the next screen select a <code class="language-plaintext highlighter-rouge">Command line</code> runner type.
In <code class="language-plaintext highlighter-rouge">Step name</code> name your build step(in my case it will be <code class="language-plaintext highlighter-rouge">Install Dependencies</code>). In <code class="language-plaintext highlighter-rouge">Custom script</code> type a script that will be executed in this build step. Again, in my case it will be</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle install
</code></pre></div></div>

<p><img src="/assets/posts/teamcity-for-ios-project/command_line_build_step_configuration.png" alt="build configuration step 2" /></p>

<p>click <code class="language-plaintext highlighter-rouge">Save</code> and your first step is ready!</p>

<p>I also added another command line build step called <code class="language-plaintext highlighter-rouge">Build and tests</code> which will run command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec fastlane build_and_test
</code></pre></div></div>

<p><em><code class="language-plaintext highlighter-rouge">build_and_test</code> is the name of the lane in <code class="language-plaintext highlighter-rouge">Fastfile</code>. If you’re not familiar with Fastlane, please have a look at  this. It’s a great tool <a href="https://fastlane.tools">Fastlane</a></em></p>

<p>So, now we have all build steps created.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_steps_final.png" alt="build steps created" /></p>

<h1 id="step-5-triggers">Step 5: Triggers</h1>

<p>Have you ever wondered how TeamCity knows when to fetch new changes from the repository and build it? Triggers is an answer.</p>

<p>I prefer to use two types of triggers. One of these is called <code class="language-plaintext highlighter-rouge">VCS Trigger</code> which means that TeamCity checks automatically if something has changed in your repository and if this is a case  then it will start a build configuration which contains that type of trigger.
<code class="language-plaintext highlighter-rouge">VCS Trigger</code> is used in the configurations like <code class="language-plaintext highlighter-rouge">Compile &amp; Test</code> for example. Because we want to compile and run tests after every push to the repository.</p>

<p>The latter trigger, is called <code class="language-plaintext highlighter-rouge">Schedule Trigger</code>. It is a simple trigger which could say : <em>Run this configuration at every Monday at 7:00AM</em></p>

<p>Go to <code class="language-plaintext highlighter-rouge">Triggers</code> section in Build Configuration main page. Click <code class="language-plaintext highlighter-rouge">Add new trigger</code> and select <code class="language-plaintext highlighter-rouge">VCS Trigger</code> and simply click <code class="language-plaintext highlighter-rouge">Save</code></p>

<p><img src="/assets/posts/teamcity-for-ios-project/vcs_trigger.png" alt="vcs trigger" /></p>

<p><code class="language-plaintext highlighter-rouge">VCS Trigger</code> configured successfully, easy right?.</p>

<p>Next, do the same, <code class="language-plaintext highlighter-rouge">Add new trigger</code> -&gt; <code class="language-plaintext highlighter-rouge">Schedule Trigger</code> and choose options that will meet your requirements (in my case it is a daily trigger at 04:00 AM) and click <code class="language-plaintext highlighter-rouge">Save</code>.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/time_trigger.png" alt="time trigger" /></p>

<p>All triggers created!</p>

<h1 id="step-6-add-build-features">Step 6: Add Build Features</h1>

<p>Build features are cool stuff. For example, while using build features you can create a condition that checks which version of Ruby is installed, or you can create a condition that will check if there is some available space on your machine. It is super useful if you want to produce <code class="language-plaintext highlighter-rouge">.ipa</code> files and you know that you need at least 100MB free space. In this post I will show you how to configure two build features - one is <code class="language-plaintext highlighter-rouge">XML report processing</code> and the second one <code class="language-plaintext highlighter-rouge">Ruby environment configurator</code>.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">XML report processing</code></li>
</ul>

<p>Go to <code class="language-plaintext highlighter-rouge">Build Features</code> section in the build configuration main page, and click <code class="language-plaintext highlighter-rouge">Add build feature</code>. Choose <code class="language-plaintext highlighter-rouge">XML report processing</code>, select <code class="language-plaintext highlighter-rouge">Ant JUnit</code> and in <code class="language-plaintext highlighter-rouge">Monitoring rules</code> paste a path for <code class="language-plaintext highlighter-rouge">report.junit</code> file which is generated by Fastlane after <code class="language-plaintext highlighter-rouge">scan</code> action.
In <code class="language-plaintext highlighter-rouge">report.junit</code> you can find out how many tests have been run, how many tests failed, how many tests have been completed successfully.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/xml_reporting.png" alt="xml reporting" /></p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">Ruby environment configurator</code></li>
</ul>

<p>This time select <code class="language-plaintext highlighter-rouge">Ruby environment configurator</code> in <code class="language-plaintext highlighter-rouge">Add build feature</code> window. In <code class="language-plaintext highlighter-rouge">gemset</code> define which ruby version you need to have. In my case it was <code class="language-plaintext highlighter-rouge">ruby-2.3.3</code>.</p>

<p>This feature will check if this version of ruby is available on the agent machine and if not it will not start build configuration. It is an optional step, but sometimes it is incredibly useful - especially, if you use multiple ruby versions or someone else could change a global version of ruby on agent machine.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/ruby_feature.png" alt="xml reporting" /></p>

<h1 id="step-7-parameters">Step 7: Parameters</h1>

<p>There are 3 types of parameters for build configuration or even root project.</p>

<ul>
  <li>
    <p>Configuration Parameter</p>
  </li>
  <li>
    <p>System properties(system.)</p>
  </li>
  <li>
    <p>Environment Variables(env.)</p>
  </li>
</ul>

<p>In this post I will focus on <code class="language-plaintext highlighter-rouge">Environment variables</code>. That type of variables are created after build start(is ready?) and they can be accessed via Command line with <code class="language-plaintext highlighter-rouge">$</code> prefix. One example of Environment variable could be an XCode path. In order to compile our project we need XCode path which will be used by Fastlane tool. So in <code class="language-plaintext highlighter-rouge">Fastfile</code> I add line:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xcode_select ENV["XCODE_PATH"]
</code></pre></div></div>

<p>which means - select XCode from a path that you can find under <code class="language-plaintext highlighter-rouge">ENV["XCODE_PATH"]</code> variable.</p>

<p>On the build configuration main page select <code class="language-plaintext highlighter-rouge">Parameters</code> and click <code class="language-plaintext highlighter-rouge">Add new parameter</code>. In <code class="language-plaintext highlighter-rouge">Name</code> type <code class="language-plaintext highlighter-rouge">env.XCODE_PATH</code>, TeamCity should automatically change Kind to <code class="language-plaintext highlighter-rouge">Environment variable</code> and in the value provide a path to XCode.app on your agent machine.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/xcode_path.png" alt="xcode path" /></p>

<p>By using parameters you can pass many useful values such as your build number or the name of scheme that should be built and many more. I encourage you to check it out :)</p>

<h1 id="step-8-failure-conditions">Step 8: Failure Conditions</h1>

<p>Failure conditions should be used in a situation when you want to force your build to fail. A great example of that is a timeout. Let’s imagine that something bad happens on your agent machine and your build is hanging over 2 hours, when normally it takes a few minutes. Failure conditions come with help! You can set up here that if build lasts above <code class="language-plaintext highlighter-rouge">n</code> minutes then it should fail.</p>

<p>In the main page of build configuration go to <code class="language-plaintext highlighter-rouge">Failure Conditions</code> and on line <code class="language-plaintext highlighter-rouge">if runs longer than specified limit in minutes</code> put a value(in minutes). In my case it will be 60 minutes.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/failuire_condition.png" alt="failuire condition" /></p>

<h1 id="step-9-agent-machine">Step 9: Agent machine</h1>

<p>As you have probably noticed, I often mention <code class="language-plaintext highlighter-rouge">agent machine</code>. Agent, <strong>in iOS case</strong>, it is a computer(Macbook, MacMini, etc) with macOS system. Agent is connected via script to your TeamCity page. TeamCity can communicate with agent in order to use it to execute build steps from build configuration. The important thing is that your agent should be turned ON all the time to provide continuous integration.</p>

<p>Ok, but how to configure an Agent?</p>

<p>Go to <code class="language-plaintext highlighter-rouge">Agents</code> tab in TeamCity page. You can find it at the top.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/agents.png" alt="agent tab" /></p>

<p>In a newly created TeamCity there are no available agents yet. Let’s click on <code class="language-plaintext highlighter-rouge">Install Build Agents</code>.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/install_build_agent.png" alt="failure condition" /></p>

<p>I prefer a way of installing it via <code class="language-plaintext highlighter-rouge">Zip file distribution</code>. After you click on that your web browser will download all the files that are necessary to run agent.</p>

<p>Great instruction how to configure Mac agent you can find in  <a href="https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaZIPFile">TeamCity docs here</a>. Below are the steps from this documentation:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1.Make sure a JDK (JRE) 1.8 (versions 1.6-1.8 are supported, but 1.8 is recommended) is properly installed on the agent computer.

2.On the agent computer, make sure the JRE_HOME or JAVA_HOME environment variables are set (pointing to the installed JRE or JDK directory respectively).

3.In the TeamCity Web UI, navigate to the Agents tab.

4.Click the Install Build Agents link and select Zip file distribution to download the archive.

5.Unzip the downloaded file into the desired directory.

6.Navigate to the &lt;installation path&gt;\conf directory, locate the file called buildAgent.dist.properties and rename it to buildAgent.properties.

7.Edit the buildAgent.properties file to specify the TeamCity server URL and the name of the agent. Please refer to Build Agent Configuration section for details on agent configuration.

8.Under Linux, you may need to give execution permissions to the bin/agent.sh shell script.
</code></pre></div></div>

<p>After these steps you can start the agent via command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pathToDownloadedUnzippedBuildAgentFiles\bin\agent.sh start
</code></pre></div></div>

<p>The next thing to do  is to go to TeamCity page on <code class="language-plaintext highlighter-rouge">Agents</code> tab again. You will have to wait a bit, and after some time you should see one agent available under <code class="language-plaintext highlighter-rouge">Unauthorized</code> tab. Only thing to do is to <code class="language-plaintext highlighter-rouge">Authorize</code> agent. After this you will see you agent under <code class="language-plaintext highlighter-rouge">Connected</code> tab.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/agent_connected.png" alt="agent connected" /></p>

<h1 id="step-10-setup-agent-requirements-for-build-configuration">Step 10: Setup Agent requirements for build configuration</h1>

<p>The last thing…You need to specify now which agent should build your configuration. If  your TeamCity contains a projects for iOS and Android, probably it will have two agents - one for Android, and the second one for iOS. Of course, we don’t want to start our <strong>iOS build configuration</strong> on computer for Android project which probably will not have XCode, or even macOS. So, in order to provide a proper agent for you project you need to use <code class="language-plaintext highlighter-rouge">Agent requirements</code> for build configuration.</p>

<p>In the main page of build configuration go to <code class="language-plaintext highlighter-rouge">Agent requirements</code> tab and then:</p>

<ul>
  <li>Select <code class="language-plaintext highlighter-rouge">Add new requirement</code></li>
  <li>In <code class="language-plaintext highlighter-rouge">Parameter Name</code> type <code class="language-plaintext highlighter-rouge">teamcity.agent.jvm.os.name</code></li>
  <li>In <code class="language-plaintext highlighter-rouge">Condition</code> select  <code class="language-plaintext highlighter-rouge">equals</code></li>
  <li>In <code class="language-plaintext highlighter-rouge">Value</code> select  <code class="language-plaintext highlighter-rouge">Mac OS X</code></li>
  <li>Save</li>
</ul>

<p><img src="/assets/posts/teamcity-for-ios-project/agent_requirements.png" alt="agent connected" /></p>

<p>The requirement which we have already created means that agent OS name should be Mac OS X because we configure a project for iOS.</p>

<h1 id="step-11-ready-for-build---run-">Step 11: Ready for build - RUN! 🎉</h1>

<p>All configured, you’re ready to start your build via TeamCity. Go to main TeamCity page and tap <code class="language-plaintext highlighter-rouge">Run</code> on your freshly created build configuration.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/run_build.png" alt="start build" /></p>

<p>After that, you will be able to see build progress:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_running.png" alt="build running" /></p>

<p>If you want to see the progress in a current build, just click on <code class="language-plaintext highlighter-rouge">Running</code> label and go to the <code class="language-plaintext highlighter-rouge">Build log</code> section. It is very useful if some errors occurred while compiling.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_log.png" alt="build running" /></p>

<p>Finally, after all build steps you will be able to see:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/build_success.png" alt="build success" /></p>

<p>As you can see, <code class="language-plaintext highlighter-rouge">XML Processing Report</code> Build Feature provides a cool output about unit tests: <code class="language-plaintext highlighter-rouge">Test passed: 24</code>.</p>

<h1 id="step-12-artifacts">Step 12: Artifacts!</h1>

<p>Last optional step. I can imagine that you can find many cases that you want to compile a project, create a <code class="language-plaintext highlighter-rouge">.ipa</code> file and send it to the client. Artifacts are made for it.
To do this: Go to build configuration settings by clicking <code class="language-plaintext highlighter-rouge">Edit Settings</code>:</p>

<p><img src="/assets/posts/teamcity-for-ios-project/edit_settings.png" alt="build configuration settings" /></p>

<p>in <code class="language-plaintext highlighter-rouge">General Settings</code> under <code class="language-plaintext highlighter-rouge">Artifacts paths</code> type a path to <code class="language-plaintext highlighter-rouge">.ipa</code> file which will be generated by your build scripts. I recommend using Fastlane again. Fastlane action called <code class="language-plaintext highlighter-rouge">gym</code> will build your project and create <code class="language-plaintext highlighter-rouge">.ipa</code> file in the output directory. More about <code class="language-plaintext highlighter-rouge">gym</code> you can <a href="https://docs.fastlane.tools/actions/gym/">read here</a>.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/artifacts_path.png" alt="artifacts path" /></p>

<p>If you do this, after next build you will be able to download <code class="language-plaintext highlighter-rouge">.ipa</code> via <code class="language-plaintext highlighter-rouge">Artifacts</code> page on TeamCity.</p>

<p><img src="/assets/posts/teamcity-for-ios-project/artifacts.png" alt="artifacts published" /></p>

<h1 id="conclusion">Conclusion</h1>

<p>TeamCity is a great platform to provide Continuous Integration in your project. In combination with Fastlane it saves you  many hours of manual deploying, testing and compiling.</p>

<p>Also, if you will configure Artifacts in build configuration, you can easily send a link to your TeamCity page to your client, and give him instructions how to download the <code class="language-plaintext highlighter-rouge">.ipa</code> with a few clicks. So, you don’t have to worry about sending <code class="language-plaintext highlighter-rouge">.ipa</code> files every time you create a new file version.</p>

<p>Hope you like the post. Feel free to share :)</p>

<p>This post was primarly posted on my company <a href="https://brightinventions.pl/blog/teamcity-for-ios-project/">blog</a></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="Swift" /><category term="iOS" /><category term="Fastlane" /><category term="TeamCity" /><category term="continuous integration" /><summary type="html"><![CDATA[Hi! Today’s topic will be about TeamCity and how to provide continuous integration in your iOS project.]]></summary></entry><entry><title type="html">Slack + Fastlane = ❤️. Talk about one of puzzles of Continuous Integration.</title><link href="https://kamwysocki.com/slack-fastlane/" rel="alternate" type="text/html" title="Slack + Fastlane = ❤️. Talk about one of puzzles of Continuous Integration." /><published>2017-10-26T17:40:00+00:00</published><updated>2017-10-26T17:40:00+00:00</updated><id>https://kamwysocki.com/slack-fastlane</id><content type="html" xml:base="https://kamwysocki.com/slack-fastlane/"><![CDATA[<p><img src="/assets/posts/slack-fastlane/puzzle.jpg" alt="" /></p>

<p>Professional development process consists of many puzzles. Some of these puzzles can be: unit testing, choosing good architecture, clean code, continuous integration and many  more.
In this post I will focus on one of these puzzles - Continuous Integration(CI). An integral part of CI in iOS Development process is a great tool called <a href="https://fastlane.tools/">Fastlane</a>.
Fastlane is a powerful engine which handles a number of tasks like: dealing with code signing, creating <code class="language-plaintext highlighter-rouge">.ipa</code> files, generating screenshots to AppStore and much more. One of the cool feature of Fastlane is the Slack integration - and this is what I wanted to write about.</p>

<h1 id="-motivation-">💪 Motivation 💪</h1>

<p>At Bright Inventions, I’m working on a few projects. Every project that we start, we start with a few basic steps: create a new repository, basic application setup and most important… Continuous Integration path. On iOS applications, it starts with  installing the Fastlane, creating some lanes in Fastfile, then pushing changes to our new repository. Next step is configuring a new TeamCity(a service that we are using for CI) with a new agent machine for the project. And after that… our CI build service is ready to collect changes from the repository and trigger a build for our clients, or just build the application and run our unit/UI tests to check if everything works fine.</p>

<p>But what if something went wrong…</p>

<p><img src="/assets/posts/slack-fastlane/error.jpg" alt="" class="center-image" /></p>

<p>Let’s say that we were doing some code refactoring, we committed the changes and pushed into our repository. Next, our build system discovered that there were  available new commits - so it started to fetch and built them and ran unit tests. And here some tests failed.</p>

<p><img src="/assets/posts/slack-fastlane/test-failed.png" alt="" class="center-image" /></p>

<p>Of course, I don’t have constantly an opened browser to check on the Teamcity site if everything goes  well when I push something to the repository. I want to be informed if something goes wrong like - if  unit tests fails or timeout appears or compilation error happens. And here is the key word - INFORMED. How our build agent can inform us about an occurred error?</p>

<h3 id="emails">Emails</h3>

<p><img src="/assets/posts/slack-fastlane/email.jpeg" alt="" class="center-image" /></p>

<p>We use email service which is built-in into TeamCity. Every built lane has a rule which says ‘send email to all developers when something goes wrong and build fails’. This solution works fine and it’s commonly used in many projects and companies. But personally, I’m not 100% satisfied with it. If you work in several projects, you get more and more emails from clients, Jira, team etc. And let’s add to that getting new emails from our TeamCity service. Of course, I can create filters and group all the  stuff(which I do), but even then it’s too much for me. Besides, there is a new thing - if some builds fail - in most cases, it is important to <strong>fix it quick</strong>. So I prefer another - quicker in my opinion - way to be notified if something bad happens.</p>

<h1 id="️-fastlane--slack-️">❤️ Fastlane + Slack ❤️</h1>

<h2 id="1-create-your-fastfile-in-right-way">1. Create your Fastfile in right way</h2>

<p>Let’s consider a simple example. One lane which compiles the project and runs the unit tests:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>platform :ios do
    desc "Runs all the tests"
    lane :test do
        begin
            test_lane()
        rescue =&gt; exception
            on_error(exception)
        end
    end
end
</code></pre></div></div>

<p>As you can see the body of <code class="language-plaintext highlighter-rouge">:test</code> lane consists of <code class="language-plaintext highlighter-rouge">begin-rescue-end</code> structure. It is a ruby specific construction. In <code class="language-plaintext highlighter-rouge">begin</code> you put some code that may fail. After the <code class="language-plaintext highlighter-rouge">rescue =&gt; exception</code> line you put the code that should be executed if something goes wrong. In our case, it will be <code class="language-plaintext highlighter-rouge">on_error(exception)</code> function. So the Fastfile should look like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">platform</span> <span class="ss">:ios</span> <span class="k">do</span>
   <span class="n">desc</span> <span class="s2">"Runs all the tests"</span>
   <span class="n">lane</span> <span class="ss">:test</span> <span class="k">do</span>
       <span class="k">begin</span>
           <span class="n">test_lane</span><span class="p">()</span>
       <span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">exception</span>
           <span class="n">on_error</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
       <span class="k">end</span>
   <span class="k">end</span>
<span class="k">end</span>

<span class="c1">### Methods</span>

<span class="k">def</span> <span class="nf">test_lane</span>
   <span class="n">cocoapods</span>
   <span class="n">clear_derived_data</span>
   <span class="nb">scan</span><span class="p">(</span><span class="ss">scheme: </span><span class="s2">"YourProjectSchemeName"</span><span class="p">,</span> <span class="ss">configuration: </span><span class="s2">"Debug"</span><span class="p">)</span>
<span class="k">end</span>

<span class="k">def</span> <span class="nf">on_error</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
   <span class="n">slack</span><span class="p">(</span>
       <span class="ss">message: </span><span class="s2">"Some thing goes wrong"</span><span class="p">,</span>
       <span class="ss">success: </span><span class="kp">false</span><span class="p">,</span>
       <span class="ss">slack_url: </span><span class="s2">"https://your slack incoming webhook url"</span><span class="p">,</span>
       <span class="ss">attachment_properties: </span><span class="p">{</span>
           <span class="ss">fields: </span><span class="p">[</span>
               <span class="p">{</span>
                   <span class="ss">title: </span><span class="s2">"Build number"</span><span class="p">,</span>
                   <span class="ss">value: </span><span class="no">ENV</span><span class="p">[</span><span class="s2">"BUILD_NUMBER"</span><span class="p">],</span>
               <span class="p">},</span>
               <span class="p">{</span>
                   <span class="ss">title: </span><span class="s2">"Error message"</span><span class="p">,</span>
                   <span class="ss">value: </span><span class="n">exception</span><span class="p">.</span><span class="nf">to_s</span><span class="p">,</span>
                   <span class="ss">short: </span><span class="kp">false</span>
               <span class="p">}</span>
           <span class="p">]</span>
       <span class="p">}</span>
   <span class="p">)</span>
<span class="k">end</span>
</code></pre></div></div>

<h2 id="2-generate-slack-url">2. Generate slack URL</h2>

<p>As you probably have noticed <code class="language-plaintext highlighter-rouge">slack</code> method takes a <code class="language-plaintext highlighter-rouge">slack_url</code> parameter. But how can I get one?</p>

<h3 id="create-incoming-webhook">Create incoming webhook</h3>

<p>Go to <a href="https://my.slack.com/services/new/incoming-webhook/">slack incoming weebhook webiste</a>, log in, and after that you will be able too see screen like this:</p>

<p><img src="/assets/posts/slack-fastlane/webhook-slack-url.png" alt="" class="center-image" /></p>

<p>Choose your channel (for test purposes, I recommend choosing a direct message to yourself). Click <code class="language-plaintext highlighter-rouge">Add incoming WebHooks integration</code>.
Next step is to copy the Webhook URL and use it as <code class="language-plaintext highlighter-rouge">slack_url</code>.</p>

<p>Of course, after you learn how it works, you can generate a URL for specially created Channel in your slack team.</p>

<p><img src="/assets/posts/slack-fastlane/webhook-slack-url2.png" alt="" class="center-image" /></p>

<h2 id="3-build-slack-message-in-fastfile">3. Build Slack message in Fastfile</h2>

<p>First of all, <a href="https://docs.fastlane.tools/actions/slack/">here</a> you can find an official documentation for Slack action in Fastlane tool. In the below  section I’ll try to give you a closer look at that.</p>

<p>Code for that is really simple. Let’s create a simple <code class="language-plaintext highlighter-rouge">slack_message</code> lane to test how it works.
Put a new lane in you Fastfile, and then just run:</p>

<p><code class="language-plaintext highlighter-rouge">fastlane slack_message</code>,</p>

<p>or if you are using a bundler</p>

<p><code class="language-plaintext highlighter-rouge">bundle exec fastlane slack_message</code>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">platform</span> <span class="ss">:ios</span> <span class="k">do</span>
   <span class="n">desc</span> <span class="s2">"Runs all the tests"</span>
   <span class="n">lane</span> <span class="ss">:slack_message</span> <span class="k">do</span>
       <span class="n">slack</span><span class="p">(</span>
           <span class="ss">message: </span><span class="s2">"App successfully uploaded to iTunesConnect."</span><span class="p">,</span>
           <span class="ss">success: </span><span class="kp">true</span><span class="p">,</span>
           <span class="ss">slack_url: </span><span class="s2">"https://your slack incoming webhook url"</span>
       <span class="p">)</span>
   <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This is how our message looks like:</p>

<p><img src="/assets/posts/slack-fastlane/basic-message.png" alt="" class="center-image" /></p>

<p>As you can see by default you get some information about <code class="language-plaintext highlighter-rouge">Git Commit</code>, <code class="language-plaintext highlighter-rouge">Git Commit Hash</code>, <code class="language-plaintext highlighter-rouge">Lane</code>, <code class="language-plaintext highlighter-rouge">Result</code>, <code class="language-plaintext highlighter-rouge">Git Author</code>.</p>

<h1 id="-customizing-slack-message-">🔧 Customizing slack message 🔧</h1>

<h4 id="-message">👉 <code class="language-plaintext highlighter-rouge">message</code></h4>

<p>Simple key for creating a message which will be display in a first row in Slack message. This can be literally everything.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">message: "App Successfully uploaded to iTunesConnect"</code></li>
  <li><code class="language-plaintext highlighter-rouge">message: "All tests have been successful"</code></li>
  <li><code class="language-plaintext highlighter-rouge">message: "Something went wrong"</code> - My favorite error message 😉</li>
</ul>

<p>but try to make your Slack message useful. As you can see above in my <code class="language-plaintext highlighter-rouge">Fastfile</code> I use a <code class="language-plaintext highlighter-rouge">begin-rescue</code> construction in Ruby. It is very useful because you can use an exception passed as a parameter to and create some meaningful error message.</p>

<p>I assume that all of you use and know <a href="https://cocoapods.org/">CococaPods</a>. Let’s imagine situation that our <code class="language-plaintext highlighter-rouge">Podfile</code> has a typo</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">platform</span> <span class="ss">:ios</span><span class="p">,</span> <span class="s1">'10.0'</span>
<span class="n">inhibit_all_warnings!</span>

<span class="n">target</span> <span class="s1">'MyAppTarget'</span> <span class="k">do</span>
 <span class="n">use_frameworks!</span>

 <span class="c1"># Pods for MyApp</span>
 <span class="n">podd</span> <span class="s1">'SnapKit'</span> <span class="c1"># &lt;------- should fail because of `podd`</span>
 <span class="n">pod</span> <span class="s1">'Result'</span>
<span class="k">end</span>

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

<p>Now create a lane in our <code class="language-plaintext highlighter-rouge">Fastfile</code> that will install our CocoaPods, and build the project.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fastlane_version</span> <span class="s2">"2.54.1"</span>

<span class="n">default_platform</span> <span class="ss">:ios</span>

<span class="n">xcode_select</span> <span class="no">ENV</span><span class="p">[</span><span class="s2">"XCODE_PATH"</span><span class="p">]</span>

<span class="n">platform</span> <span class="ss">:ios</span> <span class="k">do</span>
   <span class="n">desc</span> <span class="s2">"Runs all the tests"</span>
   <span class="n">lane</span> <span class="ss">:build_and_test</span> <span class="k">do</span>
       <span class="k">begin</span>
           <span class="n">build_and_test_lane</span><span class="p">()</span>
       <span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">exception</span>
           <span class="n">on_error</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
       <span class="k">end</span>
   <span class="k">end</span>
<span class="k">end</span>

<span class="k">def</span> <span class="nf">build_and_test_lane</span>
   <span class="n">cocoapods</span>
   <span class="n">clear_derived_data</span>
   <span class="nb">scan</span><span class="p">(</span><span class="ss">scheme: </span><span class="s2">"MyAppScheme"</span><span class="p">,</span> <span class="ss">configuration: </span><span class="s2">"Debug"</span><span class="p">)</span>
<span class="k">end</span>

<span class="k">def</span> <span class="nf">on_error</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
       <span class="n">slack</span><span class="p">(</span>
           <span class="ss">message: </span><span class="s2">"Lane failed with exception : </span><span class="si">#{</span><span class="n">exception</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
           <span class="ss">success: </span><span class="kp">false</span><span class="p">,</span>
           <span class="ss">slack_url: </span><span class="s2">"https://slackurl"</span><span class="p">,</span>
       <span class="p">)</span>
<span class="k">end</span>
</code></pre></div></div>

<p>As you can see if something goes  wrong in <code class="language-plaintext highlighter-rouge">build_and_test_lane</code> method our script will get an <code class="language-plaintext highlighter-rouge">exception</code> and run the <code class="language-plaintext highlighter-rouge">on_error(exception)</code> method.
Let’s try it by…</p>

<p><code class="language-plaintext highlighter-rouge">fastlane build_and_test</code> or <code class="language-plaintext highlighter-rouge">bundle exec fastlane build_and_test</code></p>

<p>wait some time…. and…🔔 🔔</p>

<p><img src="/assets/posts/slack-fastlane/exception.png" alt="" class="center-image" /></p>

<p>Now our message is meaningful and we know that our <code class="language-plaintext highlighter-rouge">Podfile</code> has some errors.</p>

<h4 id="--deafult_payloads">👉  <code class="language-plaintext highlighter-rouge">deafult_payloads</code></h4>

<p>As we can read in the documentation:</p>

<blockquote>
  <p>Don’t add this key or pass nil if you want all the default payloads. The available default payloads are: <code class="language-plaintext highlighter-rouge">lane</code>, <code class="language-plaintext highlighter-rouge">test_result</code>, <code class="language-plaintext highlighter-rouge">git_branch</code>, <code class="language-plaintext highlighter-rouge">git_author</code>, <code class="language-plaintext highlighter-rouge">last_git_commit_message</code>, <code class="language-plaintext highlighter-rouge">last_git_commit_hash</code>.</p>
</blockquote>

<p>Personally, I think it is very important information, but if you want to customize the message by removing some of those - you can look at this example:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">slack</span><span class="p">(</span>
   <span class="ss">message: </span><span class="s2">"App successfully uploaded to iTunesConnect."</span><span class="p">,</span>
   <span class="ss">success: </span><span class="kp">true</span><span class="p">,</span>
   <span class="ss">slack_url: </span><span class="s2">"https://your slack incoming webhook url"</span><span class="p">,</span>
   <span class="ss">default_payloads: </span><span class="p">[</span><span class="ss">:git_branch</span><span class="p">,</span> <span class="ss">:last_git_commit_message</span><span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>

<p>Here is how a message with customized <code class="language-plaintext highlighter-rouge">default_payloads</code> looks like:</p>

<p><img src="/assets/posts/slack-fastlane/default-payload-message.png" alt="" class="center-image" /></p>

<h4 id="--success">👉  <code class="language-plaintext highlighter-rouge">success</code></h4>

<p>You can also define if that message will be successful or not. Among other cases, success messages can be used if your app is successfully uploaded to iTunesConnect.</p>

<p>Second option is to set <code class="language-plaintext highlighter-rouge">success</code> to <code class="language-plaintext highlighter-rouge">false</code>, and then a message will look a bit different:</p>

<p><img src="/assets/posts/slack-fastlane/message-fail.png" alt="" class="center-image" /></p>

<p>The red color suggests that something went wrong and you have to fix it, which is a great way to notify you about it.</p>

<h4 id="--attachment_properties">👉  <code class="language-plaintext highlighter-rouge">attachment_properties</code></h4>

<p>Here  a real customizing process begins. By using this property you can add any field to your Slack message. Let’s say that you want to add <code class="language-plaintext highlighter-rouge">BUILD_NUMBER</code> and <code class="language-plaintext highlighter-rouge">URL</code> to artifacts.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">slack</span><span class="p">(</span>
   <span class="ss">message: </span><span class="s2">"App successfully uploaded to iTunesConnect."</span><span class="p">,</span>
   <span class="ss">success: </span><span class="kp">true</span><span class="p">,</span>
   <span class="ss">slack_url: </span><span class="s2">"https://your slack incoming webhook url"</span><span class="p">,</span>
   <span class="ss">default_payloads: </span><span class="p">[</span><span class="ss">:git_branch</span><span class="p">,</span> <span class="ss">:last_git_commit_message</span><span class="p">],</span>
   <span class="ss">attachment_properties: </span><span class="p">{</span>
       <span class="ss">fields: </span><span class="p">[</span>
           <span class="p">{</span>
               <span class="ss">title: </span><span class="s2">"Build number"</span><span class="p">,</span>
               <span class="ss">value: </span><span class="no">ENV</span><span class="p">[</span><span class="s2">"BUILD_NUMBER"</span><span class="p">],</span>
           <span class="p">},</span>
           <span class="p">{</span>
               <span class="ss">title: </span><span class="s2">"Artifacts URL"</span><span class="p">,</span>
               <span class="ss">value: </span><span class="s2">"https://url-to-your-artifacts.com"</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><img src="/assets/posts/slack-fastlane/message-with-custom-fields.png" alt="" class="center-image" /></p>

<p>Another example… let’s modify our <code class="language-plaintext highlighter-rouge">on_error(exception)</code> method.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">on_error</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
       <span class="n">slack</span><span class="p">(</span>
           <span class="ss">message: </span><span class="s2">"Error occured!"</span><span class="p">,</span>
           <span class="ss">success: </span><span class="kp">false</span><span class="p">,</span>
           <span class="ss">slack_url: </span><span class="s2">"https://slackurl"</span><span class="p">,</span>
           <span class="ss">attachment_properties: </span><span class="p">{</span>
               <span class="ss">fields: </span><span class="p">[</span>
                   <span class="p">{</span>
                       <span class="ss">title: </span><span class="s2">"Error message"</span><span class="p">,</span>
                       <span class="ss">value: </span><span class="n">exception</span>
                   <span class="p">}</span>
               <span class="p">]</span>
           <span class="p">}</span>
       <span class="p">)</span>
<span class="k">end</span>
</code></pre></div></div>

<p>and here we’ve got a message 🔔🔔</p>

<p><img src="/assets/posts/slack-fastlane/exception2.png" alt="" class="center-image" /></p>

<p>As you can see, now the error message is custom field.</p>

<h4 id="--other-flags">👉  other flags…</h4>

<p>In this post I have focused, in my humble opinion, on the most important keys which allow you to configure  Slack message. The others are: <code class="language-plaintext highlighter-rouge">channel</code>, <code class="language-plaintext highlighter-rouge">message</code>, <code class="language-plaintext highlighter-rouge">use_webhook_configured_username_and_icon</code>, <code class="language-plaintext highlighter-rouge">icon_url</code>, <code class="language-plaintext highlighter-rouge">payload</code>. More information about these keys you can find on <a href="https://docs.fastlane.tools/actions/slack/">official documentation</a>.</p>

<h1 id="-conclusion-">🎉 Conclusion 🎉</h1>

<p>I ❤️  Fastlane tool. It helps all developers to save a lot of time during development process. I think  one of the puzzles of this process is Continuous Integration <strong><em>in the full sense of the word</em></strong>. How do I understand the Continuous Integration? As you can read about it on <a href="https://en.wikipedia.org/wiki/Continuous_integration">wikipedia</a></p>

<blockquote>
  <p>In software engineering, continuous integration (CI) is the practice of merging all developer working copies to a shared mainline several times a day.</p>
</blockquote>

<p>It is 100% true, but for me, it is also a state when I as a developer can be notified by CI agent about successes and errors without specially checking them before pushing changes to the repository. But don’t get me wrong. I don’t recommend committing and pushing without compiling(because our CI agent inform us when something fails). I’m talking about a situation when you have a number of projects that contain a number of tests (Yes, I assume you’re writing tests 😉). And I think you don’t want to run them every time before you push new changes to the repository. That’s why, you configure the whole CI stuff to avoid it. Let CI agent do it for you. In most cases all the tests will succeed 😉), so you can work continuously. But if somehow tests fail - let the CI agent ping you on a Slack 😉
Another thing is that, you can be informed about good things like: successfully uploaded <code class="language-plaintext highlighter-rouge">.ipa</code> to TestFlight.</p>

<p>Below you can find all links that were used in this post.</p>

<p>👉  <a href="https://cocoapods.org">CocoaPods</a></p>

<p>👉  <a href="https://fastlane.tools/">Fastlane</a></p>

<p>👉  <a href="https://api.slack.com/incoming-webhooks">Slack incoming webhooks</a></p>

<p>👉  <a href="https://docs.fastlane.tools/actions/slack/">Fastlane Slack action</a></p>

<p>👉  <a href="https://www.google.com/search?q=continuous+integration">Continuous Integration</a></p>

<p>👉  <a href="https://www.jetbrains.com/teamcity/">TeamCity</a></p>

<p>This post was primarly posted on my company <a href="https://brightinventions.pl/blog/slack-fastlane/">blog</a></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="swift" /><category term="ios" /><category term="fastlane" /><category term="slack" /><category term="continuous integration" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Design Patterns with Swift: Quick look at a Strategy Pattern</title><link href="https://kamwysocki.com/quick-look-on-a-strategy-pattern-using-swift/" rel="alternate" type="text/html" title="Design Patterns with Swift: Quick look at a Strategy Pattern" /><published>2017-10-09T17:40:00+00:00</published><updated>2017-10-09T17:40:00+00:00</updated><id>https://kamwysocki.com/quick-look-on-a-strategy-pattern-using-swift</id><content type="html" xml:base="https://kamwysocki.com/quick-look-on-a-strategy-pattern-using-swift/"><![CDATA[<p><img src="/assets/posts/quick-look-on-a-strategy-pattern-using-swift/strategy.jpg" alt="Image Title" /></p>

<p>Let’s take a quick look at one of the design patterns that should help us to write a good Object-Oriented code.
The basic assumption of Strategy Pattern is that you can define many implementations that will conform to the protocol.</p>

<p>Take a look at a simple example that can be used on iOS applications.</p>

<p>Firstly, create a <code class="language-plaintext highlighter-rouge">protocol</code> which contains a method. In our case it will be:</p>

<h2 id="define-protocol">Define protocol</h2>

<script src="https://gist.github.com/kamwysoc/51c2bef4373a063aeafc9d9cb605d9e9.js"></script>

<h2 id="create-strategies">Create strategies</h2>

<p>Ok, most of the iOS apps use an <code class="language-plaintext highlighter-rouge">UIImage</code> to represent images in applications. The <code class="language-plaintext highlighter-rouge">UIImage</code> instance can be used to produce two different data representations of image <code class="language-plaintext highlighter-rouge">UIImagePNGRepresentation</code> and  <code class="language-plaintext highlighter-rouge">UIImageJPEGRepresentation</code>. Let’s create classes that handle this stuff.</p>

<script src="https://gist.github.com/kamwysoc/69fbffb20630cd273ed84a5ee2149f90.js"></script>

<p>Now, as you can see - both classes conforms to the <code class="language-plaintext highlighter-rouge">ImageRepresentation</code> protocol but they differ in implementation. Each class represents a different <strong>strategy</strong>.</p>

<h2 id="create-client">Create client</h2>

<p>The last thing - creating a client that uses one of the <code class="language-plaintext highlighter-rouge">ImageRepresentation</code> strategies.</p>

<script src="https://gist.github.com/kamwysoc/5b44740021d9bba904cda4de47939e94.js"></script>

<h2 id="usage">Usage</h2>

<script src="https://gist.github.com/kamwysoc/48ee90472babb961ab789966d7e2ed7a.js"></script>

<h2 id="conclusions">Conclusions</h2>

<p>The cool thing about Strategy Pattern is that we can change our strategy at runtime.
While using the Strategy Pattern we definitely conform to “Open-Close” SOLID principle. Our client is open for extensions by changing the strategy without changing the client implementation(close for modification). Also, the <code class="language-plaintext highlighter-rouge">ImageRepresenter</code> with Strategy Pattern included will be easiest to test.</p>

<p>Let’s think how the above code could look like without Strategy Pattern:</p>

<h3 id="using-switch">Using Switch</h3>

<script src="https://gist.github.com/kamwysoc/5be7d283e6e08052683af1c79405ce91.js"></script>

<h3 id="or-using-multiple-functions">or using multiple functions</h3>

<script src="https://gist.github.com/kamwysoc/8c6b66a014629604963b05799ab2a980.js"></script>

<p>Both of these solutions definitely are not on the same line with CleanCode. Also, it might be hard to maintain that kind of code. The switch statement can grow with the next cases - what if we had to handle a 10, 20 or 100 strategies? The second one using multiple functions is also bad because we will continue duplicating the similar methods to handle each case. This few arguments should convince you to use Strategy Pattern. And last but not least, this two examples breakes the Open-Close principle.</p>

<p>This post was primarly posted on my company <a href="https://brightinventions.pl/blog/quick-look-on-a-strategy-pattern-using-swift/">blog</a></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="swift" /><category term="iOS" /><category term="programming" /><category term="design patterns" /><summary type="html"><![CDATA[Quick look at Strategy Pattern using Swift]]></summary></entry><entry><title type="html">3D Touch - Peak&amp;amp;Pop feature.</title><link href="https://kamwysocki.com/3dtouch-peak-and-pop/" rel="alternate" type="text/html" title="3D Touch - Peak&amp;amp;Pop feature." /><published>2016-12-11T17:40:00+00:00</published><updated>2016-12-11T17:40:00+00:00</updated><id>https://kamwysocki.com/3dtouch-peak-and-pop</id><content type="html" xml:base="https://kamwysocki.com/3dtouch-peak-and-pop/"><![CDATA[<p>In my previous post I wrote about adopting UIApplicationShortcutItems in your app. Now it’s time to implement Peak&amp;Pop - a feature provided by 3d Touch.</p>

<p><img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/pexels-photo-59672.jpeg" alt="" /></p>

<h2 id="get-started">Get started</h2>

<p>First of all we need to check if our device supports force touch events. Then if our device is familiar with force touch we can easily register our <code class="language-plaintext highlighter-rouge">UIViewController</code> for force touch events. Take a look at this snippet:</p>

<script src="https://gist.github.com/kamwysoc/a08f80ddcc3f064a881650cc2dafc1eb.js"></script>

<p>As you can see the above code uses the <code class="language-plaintext highlighter-rouge">traitCollection</code> property. It is available in every <code class="language-plaintext highlighter-rouge">UIViewController</code> and provides information about controller environment. In documentation we can read about it:</p>

<blockquote>
  <p>A trait collection encapsulates the system traits of an interface’s environment</p>
</blockquote>

<p>So when we access <code class="language-plaintext highlighter-rouge">traitCollection</code> and get information about <code class="language-plaintext highlighter-rouge">forceTouchCapability</code>. It will return one of these values:</p>

<script src="https://gist.github.com/kamwysoc/6f1cc95592658e495ef6a39b5e6df153.js"></script>

<p>Another method that needs some attention is <code class="language-plaintext highlighter-rouge">registerForPreviewing</code>. It register <code class="language-plaintext highlighter-rouge">UIViewController</code> for force touch events. Documentation:</p>

<blockquote>
  <p>Registers a view controller to participate with 3D Touch preview (peek) and commit (pop).</p>
</blockquote>

<p>There is also <code class="language-plaintext highlighter-rouge">unregisterForPreviewing(withContext previewing: UIViewControllerPreviewing)</code> function available. After unregistering, all features related to 3d Touch will be turned off for view controller that called <code class="language-plaintext highlighter-rouge">unregisterForPreviewing</code> method.</p>

<h2 id="all-registered-whats-next">All registered, what’s next?</h2>

<p>We should take a look on <code class="language-plaintext highlighter-rouge">UIViewControllerPreviewingDelegate</code> - this delegate class is responsible for handling events from 3d Touch in view controller that implements methods of this delegate.</p>

<p>There are two methods:</p>

<script src="https://gist.github.com/kamwysoc/aff420c55492b809990e170dedddaade.js"></script>

<p>First method is responsible for catching force-touch events. For example if you firmly press some view in <code class="language-plaintext highlighter-rouge">UIViewController</code>, that conform to <code class="language-plaintext highlighter-rouge">UIViewControllerPreviewingDelegate</code>, the method will be called once until you release your finger or press more strongly the view. As you can see this method returns an optional <code class="language-plaintext highlighter-rouge">UIViewController?</code>. The controller returned from this function is used for action called Peek. There is also a second parameter named <code class="language-plaintext highlighter-rouge">location</code> it will give you an information about at what <code class="language-plaintext highlighter-rouge">CGPoint</code> in ViewController’s view, the app received force touch. Here you can see what the Peak looks like:</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/peak.gif" />
</p>

<p>Second method is responsible for an event called Pop. When the 3d touch mechanism detects that you strongly pressed the <code class="language-plaintext highlighter-rouge">ViewController</code> that was returned from <code class="language-plaintext highlighter-rouge">viewControllerForLocation</code> method, it will call and pass that <code class="language-plaintext highlighter-rouge">UIViewController</code> as <code class="language-plaintext highlighter-rouge">viewControllerToCommit</code> to second
<code class="language-plaintext highlighter-rouge">previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController)</code> function.</p>

<blockquote>
  <p>Important thing is that when the <code class="language-plaintext highlighter-rouge">viewControllerForLocation</code> returns <code class="language-plaintext highlighter-rouge">nil</code> the second function <code class="language-plaintext highlighter-rouge">viewControllerToCommit</code> will be not called.</p>
</blockquote>

<p>In this method we can present <code class="language-plaintext highlighter-rouge">viewControllerToCommit</code> or do another actions e.g animate touched view.</p>

<h2 id="implementation">Implementation</h2>

<p>Let’s imagine that you have <code class="language-plaintext highlighter-rouge">UIViewController</code> that contains two <code class="language-plaintext highlighter-rouge">UIImageViews</code> with beautiful apple images inside.
For this controller we want to implement 3d Touch Peak&amp;Pop feature.</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/view_controller.png" />
</p>

<p>In <code class="language-plaintext highlighter-rouge">viewDidLoad()</code> function, register our controller for force touch events.</p>

<script src="https://gist.github.com/kamwysoc/ab027712bcc2355293a589326d53dcbf.js"></script>

<p>Create and add the <code class="language-plaintext highlighter-rouge">UIImageViews</code> to the array named <code class="language-plaintext highlighter-rouge">forceTouchableViews</code>. In my implementation I created <code class="language-plaintext highlighter-rouge">AppleImageView</code> class that inherits from <code class="language-plaintext highlighter-rouge">UIImageView</code> and have a <code class="language-plaintext highlighter-rouge">appleDescription</code> property.</p>

<script src="https://gist.github.com/kamwysoc/fee49ab346af7b034d944ee4a1185034.js"></script>

<p>You might be wondering why the <code class="language-plaintext highlighter-rouge">forceTouchableViews</code> is needed. But keep calm and continue reading, I will get back to it later :-).</p>

<p>Now let’s create an extension for our <code class="language-plaintext highlighter-rouge">UIViewController</code> that will conform to <code class="language-plaintext highlighter-rouge">UIViewControllerPreviewingDelegate</code></p>

<script src="https://gist.github.com/kamwysoc/9d61c4893dad27b18276311ccb3b0cb1.js"></script>

<blockquote>
  <p>For my purposes I created an Apple model class that holds name and image property. Also I created AppleDescriptionViewController which will be responsible for representing the <code class="language-plaintext highlighter-rouge">viewControllerToCommit</code> parameter.</p>
</blockquote>

<h2 id="about-the-code">About the code</h2>

<p>As you can see in <code class="language-plaintext highlighter-rouge">viewControllerForLocation</code> method, I iterate through my <code class="language-plaintext highlighter-rouge">forceTouchableViews</code> and check using <code class="language-plaintext highlighter-rouge">wasTouched(in: location)</code> function, if some of views was touched. If no view was touched the function will return nil.
Ok, but what that <code class="language-plaintext highlighter-rouge">wasTouched(in: location)</code> function does?</p>

<script src="https://gist.github.com/kamwysoc/c63284cf2b098fd0906c24583a718040.js"></script>

<p>It converts input point to location in superview(if exist) and then checks if that location is inside UIView’s bounds. If yes then it will return <code class="language-plaintext highlighter-rouge">true</code> and we can say that our view was touched.</p>

<p>If I determine that some of my apple image views was touched, then I create a <code class="language-plaintext highlighter-rouge">AppleDescriptionViewController</code> and return it.</p>

<p>The only thing just left is to press a little bit harder on our apple image view and we will get into last step. The body of that function is simple as follow:</p>

<script src="https://gist.github.com/kamwysoc/765e20cc3d9734e2edab387ea7b5d1a9.js"></script>

<h2 id="result">Result</h2>

<p align="center">
  <img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/result.gif" />
</p>

<p>pretty nice, huh?</p>

<h2 id="conclusion">Conclusion</h2>

<p>I don’t like the way to determine what view user touched. Checking a point and calculating location for that is not really nice. Maybe another, better way to implementing 3d touch mechanism for views could be: extending a <code class="language-plaintext highlighter-rouge">UIView</code> class by some property like <code class="language-plaintext highlighter-rouge">3dTouchGestureRecognizerDelegate</code> then implementing some methods like in <code class="language-plaintext highlighter-rouge">UIViewControllerPreviewingDelegate</code>. Then we don’t have to check whether view was touched, because on the delegate methods the touched view could be passed as method parameter. Something familiar to <code class="language-plaintext highlighter-rouge">gestureRecognizer</code>. Maybe in future iOS updates the API will be changed?
To sum up, <code class="language-plaintext highlighter-rouge">UIViewControllerPreviewing</code> allows us the create pretty nice features and I highly recommend to use that and make your application better!</p>

<p>The whole implementation with example app you can find in my <a href="https://github.com/kamwysoc/3dTouchPeak-Pop">GitHub repository</a> .</p>

<p>Thanks for reading, and see you soon!</p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="swift" /><category term="iOS" /><category term="programming" /><category term="3d touch" /><summary type="html"><![CDATA[3D Touch - Peak&Pop feature.]]></summary></entry><entry><title type="html">3D Touch - Adopting shortcut items to your app.</title><link href="https://kamwysocki.com/3dtouch-adopting-shortcut-items-to-your-app/" rel="alternate" type="text/html" title="3D Touch - Adopting shortcut items to your app." /><published>2016-11-27T08:30:00+00:00</published><updated>2016-11-27T08:30:00+00:00</updated><id>https://kamwysocki.com/3dtouch-adopting-shortcut-items-to-your-app</id><content type="html" xml:base="https://kamwysocki.com/3dtouch-adopting-shortcut-items-to-your-app/"><![CDATA[<p>With the beginning of the iPhone 6s, Apple has introduced a 3D Touch mechanism which is very cool thing. The 3D Touch is also available on
the newest iPhones 7. Nothing indicates that in the future Apple devices will run out of that feature so, here is a quick tutorial on how
to improve your app using the one of the three main features of 3D Touch.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/3dTouch/header.jpeg?raw=true" alt="" /></p>

<h1 id="modify-your-infoplist-file">Modify your Info.plist file</h1>

<ol>
  <li>
    <p>Add to your  <code class="language-plaintext highlighter-rouge">Info.plist</code> file a special key called <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItems</code>. It should be an array.</p>
  </li>
  <li>
    <p>Add items to <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItems</code> array. Items should be a dictionary type.</p>
  </li>
  <li>
    <p>Put info for each item.</p>
  </li>
</ol>

<p>There are few values to set here.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  - UIApplicationShortcutItemType (required)
  - UIApplicationShortcutItemTitle (required)
  - UIApplicationShortcutItemSubtitle
  - UIApplicationShortcutItemIconType
  - UIApplicationShortcutItemIconFile
  - UIApplicationShortcutItemUserInfo
</code></pre></div></div>

<p>I will focus on the values that I set in my example app. The <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItemType</code> is a string that delivers an information to your app about what type of shortcut was pressed.
  <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItemTitle</code> is what user sees when the shortcut is shown. <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItemIconType</code> is a string that inform application what kind of <strong><em>system</em></strong>  icon should be used for this shortcut.
  And the last one is <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItemIconFile</code> defining the icon name that should be shown when the shortcut appears(instead of system icon).</p>

<blockquote>
  <p>Important thing here is that you can use system <strong><em>or</em></strong> your custom icons. Apple recommends that the custom icon should be square, single color, and 35x35 points.</p>
</blockquote>

<p>More about <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItems</code> keys and description you can get from <a href="https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1">Apple documentation</a>.</p>

<p>The configured <code class="language-plaintext highlighter-rouge">Info.plist</code> could look like that:</p>

<p><img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/info-plist.png" alt="" /></p>

<p>and by code:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;key&gt;</span>UIApplicationShortcutItems<span class="nt">&lt;/key&gt;</span>
<span class="nt">&lt;array&gt;</span>
	<span class="nt">&lt;dict&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemType<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>app.some_another_action<span class="nt">&lt;/string&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemTitle<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>Title with custom icon<span class="nt">&lt;/string&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemIconFile<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>apple-35<span class="nt">&lt;/string&gt;</span>
	<span class="nt">&lt;/dict&gt;</span>
	<span class="nt">&lt;dict&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemType<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>app.some_action<span class="nt">&lt;/string&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemIconType<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>UIApplicationShortcutIconTypeAdd<span class="nt">&lt;/string&gt;</span>
		<span class="nt">&lt;key&gt;</span>UIApplicationShortcutItemTitle<span class="nt">&lt;/key&gt;</span>
		<span class="nt">&lt;string&gt;</span>Title with system icon<span class="nt">&lt;/string&gt;</span>
	<span class="nt">&lt;/dict&gt;</span>
<span class="nt">&lt;/array&gt;</span>
</code></pre></div></div>

<p><strong><em>Final result</em></strong></p>

<p>Below you can see the result of above implementation.</p>

<p><img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/custom_system_icon.gif" alt="" /></p>

<h1 id="application-shortcut-tap-handling">Application shortcut tap handling</h1>

<p>Ok, now move to <code class="language-plaintext highlighter-rouge">AppDelegate</code> class and let’s deal with the application’s shortcut tap events.</p>

<h4 id="1override-and-implement-uiapplicationdelegate-method">1.Override and implement <code class="language-plaintext highlighter-rouge">UIApplicationDelegate</code> method.</h4>

<p>Let’s focus on this method:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="n">_</span> <span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">performActionFor</span> <span class="nv">shortcutItem</span><span class="p">:</span> <span class="kt">UIApplicationShortcutItem</span><span class="p">,</span> <span class="nv">completionHandler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Swift</span><span class="o">.</span><span class="kt">Void</span><span class="p">)</span>
</code></pre></div></div>

<p>That method is called every time when the application shortcut is pressed. You don’t have to worry about your application state. If your app is in background mode it just wakes up your app and triggers <code class="language-plaintext highlighter-rouge">performActionFor</code> method. But if the application is terminated the app cycle will be <code class="language-plaintext highlighter-rouge">didLauchWithOptions</code> and then <code class="language-plaintext highlighter-rouge">performActionFor shortcutItem</code> will be called.
Of course, you can take the application shortcut in <code class="language-plaintext highlighter-rouge">didLauchWithOptions</code> method by:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="k">let</span> <span class="nv">shortcutItem</span> <span class="o">=</span> <span class="n">launchOptions</span><span class="p">?[</span><span class="kt">UIApplicationLaunchOptionsShortcutItemKey</span><span class="p">]</span> <span class="k">as?</span> <span class="kt">UIApplicationShortcutItem</span> <span class="p">{</span>
  <span class="c1">//deal with it here</span>
<span class="p">}</span>
</code></pre></div></div>

<p>before it triggers the <code class="language-plaintext highlighter-rouge">performActionFor</code> method.</p>

<h4 id="2handling-the-uiapplicationshortcutitem">2.Handling the <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItem</code></h4>

<p>It’s time to write some code here. So let’s assume that your <code class="language-plaintext highlighter-rouge">AppDelegate</code> class includes these two methods:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="n">_</span> <span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">performActionFor</span> <span class="nv">shortcutItem</span><span class="p">:</span> <span class="kt">UIApplicationShortcutItem</span><span class="p">,</span> <span class="nv">completionHandler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Swift</span><span class="o">.</span><span class="kt">Void</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">handleShortcut</span><span class="p">(</span><span class="n">shortcutItem</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">private</span> <span class="kd">func</span> <span class="nf">handleShortcut</span><span class="p">(</span><span class="n">_</span> <span class="nv">item</span><span class="p">:</span> <span class="kt">UIApplicationShortcutItem</span><span class="p">)</span> <span class="p">{</span>

<span class="p">}</span>
</code></pre></div></div>

<p>Did you remember the <code class="language-plaintext highlighter-rouge">UIApplicationShortcutItemType</code>? Value for this key is very useful to identify what application shortcut was tapped.
But on the <code class="language-plaintext highlighter-rouge">Info.plist</code> file it occurs as a <code class="language-plaintext highlighter-rouge">String</code> type and I strongly advise against comparing the string in their pure form.
Very helpful here might be <code class="language-plaintext highlighter-rouge">Enum</code> type. So create the enum.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">ApplicationShortcutTypes</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">redApple</span> <span class="o">=</span> <span class="s">"show-red-apple"</span>
    <span class="k">case</span> <span class="n">greenApple</span> <span class="o">=</span> <span class="s">"show-green-apple"</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I think comparing types using enum is a much better way to identify what type of shortcut was tapped.</p>

<p>Now get back to the <code class="language-plaintext highlighter-rouge">handleShortcut</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">handleShortcut</span><span class="p">(</span><span class="n">_</span> <span class="nv">item</span><span class="p">:</span> <span class="kt">UIApplicationShortcutItem</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">actionType</span> <span class="o">=</span> <span class="kt">ApplicationShortcutTypes</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="n">item</span><span class="o">.</span><span class="n">type</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span>
    <span class="p">}</span>
    <span class="k">switch</span> <span class="p">(</span><span class="n">actionType</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">case</span> <span class="o">.</span><span class="nv">greenApple</span><span class="p">:</span>
      <span class="nf">showGreenAppleViewController</span><span class="p">()</span>
    <span class="k">case</span> <span class="o">.</span><span class="nv">redApple</span><span class="p">:</span>
      <span class="nf">showRedAppleViewController</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The effect of implementation will look like this:</p>

<p><img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/working_app.gif" alt="" /></p>

<p>As you can see above I create two quick actions with custom icon, title and subtitle.</p>

<h1 id="dynamic-shortcut-items">Dynamic shortcut items</h1>

<p>It is worth to mention about dynamic shortcut items. Yes, UIApplicationShortcutItems are split between <code class="language-plaintext highlighter-rouge">static</code> and <code class="language-plaintext highlighter-rouge">dynamic</code>.</p>

<ul>
  <li>static - that items are placed in <code class="language-plaintext highlighter-rouge">info.plist</code></li>
  <li>dynamic - that items can be added and removed in code</li>
</ul>

<p>To add dynamic shortcut item you just have to add it to <code class="language-plaintext highlighter-rouge">shortcutItems</code> array.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>UIApplication.sharedApplication().shortcutItems?.append(UIMutableApplicationShortcutItem(type: "my-dynamic-shortcut", localizedTitle: "Dynamic shortcut"))
</code></pre></div></div>

<p>to remove:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="k">let</span> <span class="nv">shortcutItem</span> <span class="o">=</span> <span class="kt">UIApplication</span><span class="o">.</span><span class="nf">sharedApplication</span><span class="p">()</span><span class="o">.</span><span class="n">shortcutItems</span><span class="p">?</span><span class="o">.</span><span class="nf">filter</span><span class="p">({</span> <span class="nv">$0</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">"my-dynamic-shortcut"</span> <span class="p">})</span><span class="o">.</span><span class="n">first</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">index</span> <span class="o">=</span> <span class="kt">UIApplication</span><span class="o">.</span><span class="nf">sharedApplication</span><span class="p">()</span><span class="o">.</span><span class="n">shortcutItems</span><span class="p">?</span><span class="o">.</span><span class="nf">indexOf</span><span class="p">(</span><span class="n">shortcutItem</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">return</span>
    <span class="p">}</span>
    <span class="kt">UIApplication</span><span class="o">.</span><span class="nf">sharedApplication</span><span class="p">()</span><span class="o">.</span><span class="n">shortcutItems</span><span class="p">?</span><span class="o">.</span><span class="nf">removeAtIndex</span><span class="p">(</span><span class="n">index</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="conclusion">Conclusion</h1>

<p>The 3D Touch is powerful feature and makes iOS apps very nice to use. Interesting fact is that from the iOS 10 all apps available on AppStore have predefined <code class="language-plaintext highlighter-rouge">Share App</code> shortcut. It allows us to share the applications without opening them. In my future posts I will describe more features that 3d touch gives us. So, thanks for reading and see you next time!</p>

<p><img src="https://raw.githubusercontent.com/kamwysoc/kamwysoc.github.io/master/assets/posts/3dTouch/share_app.gif" alt="" /></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="swift" /><category term="iOS" /><category term="programming" /><category term="3d touch" /><summary type="html"><![CDATA[3D Touch - Adopting shortcut items to your app.]]></summary></entry><entry><title type="html">Make your development better. Use the proxy.</title><link href="https://kamwysocki.com/improve-your-development-using-charles/" rel="alternate" type="text/html" title="Make your development better. Use the proxy." /><published>2016-11-08T00:30:00+00:00</published><updated>2016-11-08T00:30:00+00:00</updated><id>https://kamwysocki.com/improve-your-development-using-charles</id><content type="html" xml:base="https://kamwysocki.com/improve-your-development-using-charles/"><![CDATA[<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/head.jpeg?raw=true" alt="" /></p>

<p>In this post, I would like to describe you to set up a proxy using Charles desktop app. I believe that many of you work with API or consume some REST Service. If haven’t heard about proxy yet I believe the knowledge from this post will be useful in your future development.
The following example concerns an iOS environment and configuring at the OSX system.</p>

<h1 id="what-the-proxy-is">What the proxy is?</h1>

<p>To tell you what the Proxy is I use the definition that I found in Charles <a href="https://www.charlesproxy.com/documentation/additional/http-proxy/">documentation</a></p>
<blockquote>
  <p>An HTTP Proxy is a server that receives requests from your web browser and then makes the request to the Internet on your behalf. It then returns the results to your browser.</p>
</blockquote>

<p>So the Charles app is kind of monitor that inspects your network traffic, does all requests on your behalf and returns response back to you.</p>

<h1 id="do-i-really-need-it">Do I really need it?</h1>

<p>Yes! It might help you when you’re creating an app that consumes some API. You’ll be able to look throught the request and response from the server. Also, Charles app allows you to set a break point for endpoint and gives you ability to edit a request or response body, so you can test a various scenarios for your app. Likewise you can see how many request your app really does.</p>

<h1 id="how-to-configure-charles">How to configure Charles?</h1>

<p>First, go to <a href="https://www.charlesproxy.com/download/">Charles website</a> and download the installation file. After the installation process you will see the main screen of the app. At start I recommend to select the <code class="language-plaintext highlighter-rouge">Sequence</code> tab on the top.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/main_screen.png?raw=true" alt="" /></p>

<p>After some time you should see all request that you do on your mac.
Now, we have two ways to configure the Charles. First way is to configure it for iOS Simulator. The second option is configure Charles for iOS device.</p>

<p><strong><em>iOS Simluator configuration</em></strong></p>

<p>Click on Help -&gt; SSL Proxying -&gt; Install Charles Root Certificate in iOS Simualator.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/install_on_ios.png?raw=true" alt="" /></p>

<p>You will see the prompt:</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/prompt.png?raw=true" alt="" /></p>

<p>Then click OK and for sure you should restart Simulator. After that steps Charles is configured and ready to work with your Simulator.</p>

<p><strong><em>iOS Device configuration</em></strong></p>

<p>On your device in Wi-Fi connection settings choose the same connection that your Mac using, tap on it. Then swipe down, and choose Proxy Setting to Manual.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/proxy_iphone.png?raw=true" alt="" /></p>

<p>In the IP field please put the same IP address that your Mac Wi-Fi uses. In the <code class="language-plaintext highlighter-rouge">port</code> field type <code class="language-plaintext highlighter-rouge">8888</code>.</p>

<p>To see IP-address of your Wi-Fi on your Mac:</p>

<p>Right-click with option button on your wifi icon on the Mac</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/wifi_mac.png?raw=true" alt="" /></p>

<p>Then on your iOS device go to <a href="http://www.charlesproxy.com/getssl/">http://www.charlesproxy.com/getssl/</a> and install the certificate. I recommend to do it via Safari because it redirects you from URL to Certificates Settings on iOS Device. Then just install the certificate.</p>

<p>After the installation process, you will be able to see all request from your iOS device in Charles app on your Mac.</p>

<h1 id="ok-all-configured-but-how-to-use-it">Ok, all configured but, how to use it?</h1>

<p>After the configuration flow, you will see the Charles main window, and your network data. For the purposes of this post I wrote a simple app that consume free rest API <code class="language-plaintext highlighter-rouge">https://www.freegeoip.net/</code>. This API gives us some geo-information about any domain. For example:
https://www.freegeoip.net/json/github.com returns geo-information about <code class="language-plaintext highlighter-rouge">github.com</code> site.</p>

<p>Now, let’s call <code class="language-plaintext highlighter-rouge">https://www.freegeoip.net/json/twitter.com</code> from iOS Simulator/iPhone. On Charles main window, we’re able too see the request was made and we received a response. There is no information about request parameters, response code, etc.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/call.png?raw=true" alt="" /></p>

<p>Let’s take a look on that.</p>

<p><strong><em>Overview tab</em></strong></p>

<p>In the <code class="language-plaintext highlighter-rouge">Overview</code> tab we can see information about Protocol used to this call, SSL, also you’re able too see the request time and size of request and response.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/overview.png?raw=true" alt="" /></p>

<p>Ok, let’s have look on the request and response</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/request_non_readable.png?raw=true" alt="" /></p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/response_non_readable.png?raw=true" alt="" /></p>

<p>Unfortunately, both are not readable for Charles. It’s all because the request is secure and uses the <code class="language-plaintext highlighter-rouge">https</code>. So, we need to inform Charles about that this domain is using the <code class="language-plaintext highlighter-rouge">SSL</code> to see the request details.</p>

<p><strong><em>Adding Proxy SSL</em></strong></p>

<p>There’re two ways to do that.</p>

<p>First you can click on the <code class="language-plaintext highlighter-rouge">Proxy settings</code>, then click <code class="language-plaintext highlighter-rouge">Add</code> the append host to the list. In the <code class="language-plaintext highlighter-rouge">Host</code> field type the host address of your server. In my example that would be <code class="language-plaintext highlighter-rouge">www.freegeoip.net</code>.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/add_proxy_settings.png?raw=true" alt="" /></p>

<p>In the port field type <code class="language-plaintext highlighter-rouge">443</code>. Why <code class="language-plaintext highlighter-rouge">443</code> ? Because the <code class="language-plaintext highlighter-rouge">443</code> is the default port HTTPS connections use.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/host_and_port.png?raw=true" alt="" /></p>

<p>Make sure that you have <code class="language-plaintext highlighter-rouge">Enable Proxy SSL</code> checkbox selected.
After adding the host it should look like that :</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/after_adding.png?raw=true" alt="" /></p>

<p>Second way is much simpler, just right-click on the request and select the <code class="language-plaintext highlighter-rouge">Enable SSL Proxying</code>.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/enable_proxy_settings.png?raw=true" alt="" /></p>

<p><strong><em>Request using SSL Proxying</em></strong></p>

<p>After adding the SSL Proxying for our host server, perform request again.</p>

<p><img src="/assets/posts/charles/ssl_request_screen.png" alt="" /></p>

<p>As you can see right now we’re able to see the <code class="language-plaintext highlighter-rouge">RC</code>(response code) of the request. Here it is 200(OK). Also we know that our request was <code class="language-plaintext highlighter-rouge">GET</code> type. Let’s take a look at the request and response body.</p>

<p>In the request body, we have some information about Request type, language, and encoding. Also, you can find here some information about Cookies.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/ssl_request_screen.png?raw=true" alt="" /></p>

<p>The response body becomes readable from Charles. After choosing the <code class="language-plaintext highlighter-rouge">JSON text</code> tab we can see formatted JSON string. All informations about the response are stored in the <code class="language-plaintext highlighter-rouge">RAW</code> tab. You can find here information about Response code, Content-Type, Server, encoding and many others.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/charles_tab.png?raw=true" alt="" /></p>

<p>And now the most important - response body:</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/response_body_ssl.png?raw=true" alt="" /></p>

<h1 id="debugging">Debugging</h1>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/havefun_mem.jpg?raw=true" alt="" /></p>

<p>The cool thing about Charles is that the app allows you to debug the requests/responses in the same way as XCode and many others IDEs breakpoints work. But here you put the breakepoint on the request, not on the line of code.</p>

<p>To set a breakpoint, just right-click on the line with the request that you want to debug and select <code class="language-plaintext highlighter-rouge">Breakpoints</code> option.</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/breakpoint.png?raw=true" alt="" /></p>

<p>Now, make the request again and you should see the Breakpoint-Window.</p>

<p>With the <code class="language-plaintext highlighter-rouge">Overview</code> and <code class="language-plaintext highlighter-rouge">Edit Request</code> tabs. Here you’re able to edit the request body, query string parameters, request method, cookies, headers or even choose the HTTP version. After editing the request just click <code class="language-plaintext highlighter-rouge">Execute</code> on the bottom.</p>

<p>After executing when the Charles receives the response we should see the Breakpoint-Window again and now we’re ready to edit the response!</p>

<p><img src="https://github.com/kamwysoc/kamwysoc.github.io/blob/master/assets/posts/charles/edit_response.png?raw=true" alt="" /></p>

<p>By editing the response I mean that you can edit Response Headers and Response Body. Also you can check the body and the overview of the request. After editing the response, just click the Execute button.
After that steps, the edited response goes to our device/simulator.</p>

<blockquote>
  <p>Note: Remember to set the breakpoint off, when you don’t need it anymore because if you don’t this the breakpoint will run every time that request was triggered.</p>
</blockquote>

<h1 id="conclusion">Conclusion</h1>

<p>Charles app is a great tool and has many many features. In my post I focused on the iOS environment, but you can also configure the proxy for your Android Emulator or Android device.
I described most common usages which I do with Charles app. To sum up I think that app should take a place in your development tools directory if you work with some web server.</p>

<p><em>This post is cross-posted with my company <a href="http://blog.brightinventions.pl/improve-your-development-using-charles/">blog</a></em></p>]]></content><author><name>kwysocki</name></author><category term="blog" /><category term="swift" /><category term="iOS" /><category term="programming" /><category term="proxy" /><summary type="html"><![CDATA[Make your development better. Use the proxy.]]></summary></entry></feed>