<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="http://5sw.de/feed.xml" rel="self" type="application/atom+xml" /><link href="http://5sw.de/" rel="alternate" type="text/html" /><updated>2025-12-03T21:56:53+01:00</updated><id>http://5sw.de/feed.xml</id><title type="html">5sw.de</title><entry><title type="html">Handling unknown enum cases</title><link href="http://5sw.de/2022/01/unknown-enum-cases/" rel="alternate" type="text/html" title="Handling unknown enum cases" /><published>2022-01-29T13:15:29+01:00</published><updated>2022-01-29T13:15:29+01:00</updated><id>http://5sw.de/2022/01/unknown-enum-cases</id><content type="html" xml:base="http://5sw.de/2022/01/unknown-enum-cases/"><![CDATA[<!-- wp:paragraph -->

<p>Even though they are <a href="/2022/01/enum-or-struct/">sometimes overused</a>, enums are still a great tool. Thanks to <code class="language-swift highlighter-rouge"><span class="kt">Codable</span></code> they can easily be decoded from JSON sent by your backend.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>This is great until you need to add a new case to the enum. Then you have to either deal with versioning your API or you need to tell your users to update the app. In some cases you have no choice, but in other cases it would be fine to just ignore the new value and fall back to some default behavior.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>Here are a few ways I used to realize such a scenario:</p>

<!-- /wp:paragraph -->

<!-- wp:heading -->

<h2 id="rawrepresentable-struct"><code class="language-swift highlighter-rouge"><span class="kt">RawRepresentable</span></code> struct</h2>

<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>The simplest way would be to replace enums with a <code class="language-swift highlighter-rouge"><span class="kt">RawRepresentable</span></code> struct:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">ItemType</span><span class="p">:</span> <span class="kt">RawRepresentable</span><span class="p">,</span> <span class="kt">Codable</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">rawValue</span><span class="p">:</span> <span class="kt">String</span>
    
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">house</span> <span class="o">=</span> <span class="kt">ItemType</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="s">"house"</span><span class="p">)</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">tree</span> <span class="o">=</span> <span class="kt">ItemType</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="s">"tree"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>In code this can be used just like an enum would, you’d only have to add a <code class="language-swift highlighter-rouge"><span class="k">default</span></code> case to every switch statement.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>This can lead to situations where a different subset of those cases is handled in different places. Sometimes that’s fine, but in other cases you want to ensure to handle all known cases everywhere. So you need an actual enum in order for the compiler to be able to do exhaustiveness checks.</p>

<!-- /wp:paragraph -->

<!-- wp:heading -->

<h2 id="enum-with-unknown-case">Enum with “Unknown” case</h2>

<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>To do this we simply can manually implement the decoding and map unknown values to a default case:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">ItemType</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="kt">Codable</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">house</span>
    <span class="k">case</span> <span class="n">tree</span>
    <span class="k">case</span> <span class="n">unknown</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">let</span> <span class="nv">string</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">String</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
        <span class="k">switch</span> <span class="n">string</span> <span class="p">{</span>
        <span class="k">case</span> <span class="s">"house"</span><span class="p">:</span> <span class="k">self</span> <span class="o">=</span> <span class="o">.</span><span class="n">house</span>
        <span class="k">case</span> <span class="s">"tree"</span><span class="p">:</span> <span class="k">self</span> <span class="o">=</span> <span class="o">.</span><span class="n">tree</span>
        <span class="k">default</span><span class="p">:</span> <span class="k">self</span> <span class="o">=</span> <span class="o">.</span><span class="n">unknown</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>Implementing this for many enums becomes pretty boring. Luckily we can share the implementation between all enums by writing a protocol with a default implementation:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">UnknownDecodable</span><span class="p">:</span> <span class="kt">Decodable</span><span class="p">,</span> <span class="kt">RawRepresentable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">unknown</span><span class="p">:</span> <span class="k">Self</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">UnknownDecodable</span> <span class="k">where</span> <span class="kt">RawValue</span><span class="p">:</span> <span class="kt">Decodable</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">let</span> <span class="nv">raw</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">RawValue</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
        <span class="k">self</span> <span class="o">=</span> <span class="kt">Self</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="n">raw</span><span class="p">)</span> <span class="p">??</span> <span class="o">.</span><span class="n">unknown</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>Using this we can define our enum like we would normally and get that behavior for free by just conforming to the <code class="language-swift highlighter-rouge"><span class="kt">UnknownDecodable</span></code> protocol. Note that our enum case <code class="language-swift highlighter-rouge"><span class="n">unknown</span></code> can fulfill the protocol requirement of <code class="language-swift highlighter-rouge"><span class="kd">static</span> <span class="k">var</span> <span class="nv">unknown</span><span class="p">:</span> <span class="k">Self</span></code>:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">ItemType</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">UnknownDecodable</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">house</span>
    <span class="k">case</span> <span class="n">tree</span>
    <span class="k">case</span> <span class="n">unknown</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:heading -->

<h2 id="decoding-unknown-cases-as-nil">Decoding unknown cases as <code class="language-swift highlighter-rouge"><span class="kc">nil</span></code></h2>

<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>A final solution I sometimes find useful is decoding the enum as optional and mapping unknown values to <code class="language-swift highlighter-rouge"><span class="kc">nil</span></code>. </p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>This is easy to do if we manually implement decoding for the struct that contains this enum. But this would lead to a lot of (possibly repeated) boilerplate code we don’t like to write. Instead we can use a <a href="https://www.avanderlee.com/swift/property-wrappers/">property wrapper</a>:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@propertyWrapper</span>
<span class="kd">struct</span> <span class="kt">DecodeUnknownAsNil</span> <span class="k">where</span> <span class="kt">Enum</span><span class="o">.</span><span class="kt">RawValue</span><span class="p">:</span> <span class="kt">Codable</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">wrappedValue</span><span class="p">:</span> <span class="kt">Enum</span><span class="p">?</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">DecodeUnknownAsNil</span> <span class="p">:</span> <span class="kt">Codable</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">let</span> <span class="nv">raw</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">Enum</span><span class="o">.</span><span class="kt">RawValue</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
        <span class="n">wrappedValue</span> <span class="o">=</span> <span class="kt">Enum</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="n">raw</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">encode</span><span class="p">(</span><span class="n">to</span> <span class="nv">encoder</span><span class="p">:</span> <span class="kt">Encoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">container</span> <span class="o">=</span> <span class="n">encoder</span><span class="o">.</span><span class="nf">singleValueContainer</span><span class="p">()</span>
        <span class="k">try</span> <span class="n">container</span><span class="o">.</span><span class="nf">encode</span><span class="p">(</span><span class="n">wrappedValue</span><span class="p">?</span><span class="o">.</span><span class="n">rawValue</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">KeyedDecodingContainer</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">decode</span><span class="p">(</span><span class="n">_</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">DecodeUnknownAsNil</span><span class="o">.</span><span class="k">Type</span><span class="p">,</span> <span class="n">forKey</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">Key</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">DecodeUnknownAsNil</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">try</span> <span class="nf">decodeIfPresent</span><span class="p">(</span><span class="n">type</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">??</span> <span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">wrappedValue</span><span class="p">:</span> <span class="kc">nil</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">DecodeUnknownAsNil</span><span class="p">:</span> <span class="kt">Equatable</span> <span class="k">where</span> <span class="kt">Enum</span><span class="p">:</span> <span class="kt">Equatable</span> <span class="p">{}</span>
<span class="kd">extension</span> <span class="kt">DecodeUnknownAsNil</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="k">where</span> <span class="kt">Enum</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>The extension on <code class="language-swift highlighter-rouge"><span class="kt">KeyedDecodingContainer</span></code> is necessary to handle missing or <code class="language-swift highlighter-rouge"><span class="n">null</span></code> values in the JSON.</p>

<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->

<h1 id="when-to-use-which">When to use which</h1>

<!-- /wp:heading -->

<!-- wp:paragraph -->

<p>I choose <a href="#rawrepresentable-struct">the <code class="language-swift highlighter-rouge"><span class="kt">RawRepresentable</span></code> struct</a> when I don’t need to make a decision based on that value. This could be for looking up some resource or other values in a dictionary.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p><a href="#decoding-unknown-cases-as-nil">The <code class="language-swift highlighter-rouge"><span class="kt">DecodeUnknownAsNil</span></code> property wrapper</a> is great if the enum value is optional anyways and you can handle the unknown case just as if there was no value at all.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>For most cases I would chose <a href="#enum-with-unknown-case">the <code class="language-swift highlighter-rouge"><span class="kt">UnknownDecodable</span></code> protocol</a> though. If I make my property optional I can distinguish between no value and an unknown value. And if the property is not optional I know the decoding will fail so I can catch bugs on the server side where required properties are missing.</p>

<!-- /wp:paragraph -->]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><category term="enum" /><category term="JSON" /><category term="Codable" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Enum or struct?</title><link href="http://5sw.de/2022/01/enum-or-struct/" rel="alternate" type="text/html" title="Enum or struct?" /><published>2022-01-23T11:01:40+01:00</published><updated>2022-01-23T11:01:40+01:00</updated><id>http://5sw.de/2022/01/enum-or-struct</id><content type="html" xml:base="http://5sw.de/2022/01/enum-or-struct/"><![CDATA[<!-- wp:paragraph -->

<p>I often see a pattern where there is an enum with a bunch of computed properties that return a different value for each case. In the rest of the code base then only those properties are used. Something like this:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">Style</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">headline</span>
    <span class="k">case</span> <span class="n">bodyText</span>
    <span class="k">case</span> <span class="n">emphasis</span>
    
    <span class="k">var</span> <span class="nv">isBold</span><span class="p">:</span> <span class="kt">Boolean</span> <span class="p">{</span>
        <span class="k">switch</span> <span class="k">self</span> <span class="p">{</span>
            <span class="k">case</span> <span class="o">.</span><span class="n">headLine</span><span class="p">,</span> <span class="o">.</span><span class="nv">emphasis</span><span class="p">:</span> <span class="k">return</span> <span class="kc">true</span>
            <span class="k">case</span> <span class="o">.</span><span class="nv">bodyText</span><span class="p">:</span> <span class="k">return</span> <span class="kc">false</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="k">var</span> <span class="nv">fontSize</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="p">{</span>
        <span class="k">switch</span> <span class="k">self</span> <span class="p">{</span>
            <span class="k">case</span> <span class="o">.</span><span class="nv">headline</span><span class="p">:</span> <span class="k">return</span> <span class="mi">20</span>
            <span class="k">case</span> <span class="o">.</span><span class="n">bodyText</span><span class="p">,</span> <span class="o">.</span><span class="nv">emphasis</span><span class="p">:</span> <span class="k">return</span> <span class="mi">16</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>This works, but quite often can be improved by using a struct instead of an enum. Define a struct which contains all your computed properties as stored properties and the define a global constant of this for each enum case:</p>

<!-- /wp:paragraph -->

<!-- wp:code -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Style</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">isBold</span><span class="p">:</span> <span class="kt">Bool</span>
    <span class="k">var</span> <span class="nv">fontSize</span><span class="p">:</span> <span class="kt">CGFloat</span>
    
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">headline</span> <span class="o">=</span> <span class="kt">Style</span><span class="p">(</span><span class="nv">isBold</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nv">fontSize</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">bodyText</span> <span class="o">=</span> <span class="kt">Style</span><span class="p">(</span><span class="nv">isBold</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nv">fontSize</span><span class="p">:</span> <span class="mi">16</span><span class="p">)</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">emphasis</span> <span class="o">=</span> <span class="kt">Style</span><span class="p">(</span><span class="nv">isBold</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nv">fontSize</span><span class="p">:</span> <span class="mi">16</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>This requires less code, it is easier to see and change the values for each case and you can add more cases without having to change the source code of the enum definition.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>This doesn’t work in every case though. Better stick to an enum if the identity of the cases is important, for example for control flow. Another issue is (JSON) decoding - the struct would require all the properties in the data.</p>

<!-- /wp:paragraph -->]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><category term="enum" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Automatic builders</title><link href="http://5sw.de/2021/07/automatic-builders/" rel="alternate" type="text/html" title="Automatic builders" /><published>2021-07-21T11:33:35+02:00</published><updated>2021-07-21T11:33:35+02:00</updated><id>http://5sw.de/2021/07/automatic-builders</id><content type="html" xml:base="http://5sw.de/2021/07/automatic-builders/"><![CDATA[<!-- wp:paragraph -->

<p>While investigating the new <a href="/2021/07/new-attributed-strings/"><code class="language-swift highlighter-rouge"><span class="kt">AttributedString</span></code> API</a> I realized you could use the same techniques to build a generic fluid builder interface for any type. This is what I came up with:</p>

<!-- /wp:paragraph -->

<!-- wp:html -->
<script src="https://gist.github.com/5sw/ead2b6015a5e14cb5f6b90002983e81b.js?file=configurator.swift"></script>

<!-- /wp:html -->

<!-- wp:paragraph -->

<p>And here is an example how you can use it:</p>

<!-- /wp:paragraph -->

<!-- wp:html -->
<script src="https://gist.github.com/5sw/ead2b6015a5e14cb5f6b90002983e81b.js?file=example.swift"></script>

<!-- /wp:html -->

<!-- wp:paragraph -->

<!-- /wp:paragraph -->]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">New attributed strings</title><link href="http://5sw.de/2021/07/new-attributed-strings/" rel="alternate" type="text/html" title="New attributed strings" /><published>2021-07-20T10:08:13+02:00</published><updated>2021-07-20T10:08:13+02:00</updated><id>http://5sw.de/2021/07/new-attributed-strings</id><content type="html" xml:base="http://5sw.de/2021/07/new-attributed-strings/"><![CDATA[<p>Finally we are going to get <a href="https://developer.apple.com/documentation/foundation/attributedstring/">attributed strings as a native Swift value type</a>. So lets see how we can update the example of my <a href="/2019/08/attributed-strings/">last article about attributed strings</a>:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">string</span> <span class="o">=</span> <span class="s">"Name (whatever)"</span>

<span class="k">var</span> <span class="nv">attributed</span> <span class="o">=</span> <span class="kt">AttributedString</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">nameEnd</span> <span class="o">=</span> <span class="n">attributed</span><span class="o">.</span><span class="nf">range</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="s">" ("</span><span class="p">)?</span><span class="o">.</span><span class="n">lowerBound</span> <span class="p">??</span> <span class="n">attributed</span><span class="o">.</span><span class="n">endIndex</span>

<span class="n">attributed</span><span class="p">[</span><span class="o">..&lt;</span><span class="n">nameEnd</span><span class="p">]</span><span class="o">.</span><span class="n">font</span> <span class="o">=</span> <span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="nf">bold</span><span class="p">()</span>
</code></pre></div></div>

<p>Pretty neat. No more <code class="language-swift highlighter-rouge"><span class="kt">NSRange</span></code> to deal with, and we can access the <code class="language-swift highlighter-rouge"><span class="n">font</span></code> attribute directly as a typed property. No more dealing with attribute values as <code class="language-swift highlighter-rouge"><span class="kt">Any</span></code>.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>Of course we still want to separate the <em>presentation</em> from the <em>meaning</em> of our strings. So we can take our semantic enum from last time. We need to define our attribute key again, but this time as a type conforming to the <code class="language-swift highlighter-rouge"><span class="kt">AttributedStringKey</span></code> protocol. This requires a type for our value and a name:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">Semantic</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">name</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">SemanticAttributeKey</span><span class="p">:</span> <span class="kt">AttributedStringKey</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">name</span> <span class="o">=</span> <span class="s">"semantic"</span>
    <span class="kd">typealias</span> <span class="kt">Value</span> <span class="o">=</span> <span class="kt">Semantic</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Note that all the requirements from this protocol are <code class="language-swift highlighter-rouge"><span class="kd">static</span></code>, so its best to define this as an otherwise empty <code class="language-swift highlighter-rouge"><span class="kd">enum</span></code> so we cannot create an instance of that type, which is never needed.</p>

<p>Next we create our attributed string and find the range we want to highlight. No need for <code class="language-swift highlighter-rouge"><span class="kt">NSRange</span></code> any more. Using a subscript we can then assign our name attribute to the part of our string we want to highlight in a type-safe way:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">attributed</span><span class="p">[</span><span class="o">..&lt;</span><span class="n">nameEnd</span><span class="p">][</span><span class="kt">SemanticAttributeKey</span><span class="o">.</span><span class="k">self</span><span class="p">]</span> <span class="o">=</span> <span class="o">.</span><span class="n">name</span>
</code></pre></div></div>

<p>To display the string we can simply replace our semantic attribute with a given font attribute. For this we prepare an <em><a href="https://developer.apple.com/documentation/foundation/attributecontainer/">attribute container</a></em> with our name attribute and another one with the font attribute as an replacement. Finally we create our string to display using the <code class="language-swift highlighter-rouge"><span class="nf">replacingAttributes</span><span class="p">(</span><span class="nv">_</span><span class="p">:</span><span class="nv">with</span><span class="p">:)</span></code> method:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">nameContainer</span> <span class="o">=</span> <span class="kt">AttributeContainer</span><span class="p">()</span>
<span class="n">nameContainer</span><span class="p">[</span><span class="kt">SemanticAttributeKey</span><span class="o">.</span><span class="k">self</span><span class="p">]</span> <span class="o">=</span> <span class="o">.</span><span class="n">name</span>

<span class="k">let</span> <span class="nv">boldContainer</span> <span class="o">=</span> <span class="kt">AttributeContainer</span><span class="o">.</span><span class="nf">font</span><span class="p">(</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="nf">bold</span><span class="p">())</span>

<span class="k">let</span> <span class="nv">displayString</span> <span class="o">=</span> <span class="n">attributed</span><span class="o">.</span><span class="nf">replacingAttributes</span><span class="p">(</span><span class="n">nameContainer</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="n">boldContainer</span><span class="p">)</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>Would be nice to directly have a property for our semantic attribute, just as <code class="language-swift highlighter-rouge"><span class="o">.</span><span class="n">font</span></code> provided by Apple. We could define a bunch of extensions on <code class="language-swift highlighter-rouge"><span class="kt">AttributedString</span></code>, <code class="language-swift highlighter-rouge"><span class="kt">AttributedSubstring</span></code>, <code class="language-swift highlighter-rouge"><span class="kt">AttributeContainer</span></code> and so on. But thanks to <code class="language-swift highlighter-rouge"><span class="kd">@dynamicMemberLookup</span></code> and key paths there is an easier way.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>First we need to define an <em>attribute scope</em>. That is a simple struct conforming to the <code class="language-swift highlighter-rouge"><span class="kt">AttributeScope</span></code> protocol inside an extension of <code class="language-swift highlighter-rouge"><span class="kt">AttributeScopes</span></code>. There we also need to define a property that returns the type of our scope. Inside of our scope we simply add a <code class="language-swift highlighter-rouge"><span class="kd">let</span></code> property for each of our attribute keys.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>We can even move our attribute key definitions inside the scope, as we won’t have to use the type name in subscripts any more.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>Finally we define an extension on <code class="language-swift highlighter-rouge"><span class="kt">AttributeDynamicLookup</span></code> which provides a <code class="language-swift highlighter-rouge"><span class="n">dynamicMember</span></code> subscript for a key path from our scope to any <code class="language-swift highlighter-rouge"><span class="kt">AttributedStringKey</span></code>.</p>

<!-- /wp:paragraph -->

<!-- wp:code {"language":"swift"} -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">AttributeScopes</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">myApp</span><span class="p">:</span> <span class="kt">MyAppAttributes</span><span class="o">.</span><span class="k">Type</span> <span class="p">{</span> <span class="kt">MyAppAttributes</span><span class="o">.</span><span class="k">self</span> <span class="p">}</span>

    <span class="kd">struct</span> <span class="kt">MyAppAttributes</span><span class="p">:</span> <span class="kt">AttributeScope</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">semantic</span><span class="p">:</span> <span class="kt">SemanticAttributeKey</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">AttributeDynamicLookup</span> <span class="p">{</span>
    <span class="nf">subscript</span><span class="p">(</span><span class="n">dynamicMember</span> <span class="nv">keyPath</span><span class="p">:</span> <span class="kt">KeyPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="p">{</span>
        <span class="k">self</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>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>Note that <code class="language-swift highlighter-rouge"><span class="kt">AttributeDynamicLookup</span></code> is an empty enum, so our subscript can never actually be called. Sadly this leads to some warnings about calling never-returning functions, at least with the current (at the time of writing this) Xcode 13 beta 3.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>With that in place we can directly access <code class="language-swift highlighter-rouge"><span class="o">.</span><span class="n">semantic</span></code> on attributed strings or our attribute containers:</p>

<!-- /wp:paragraph -->

<!-- wp:code {"language":"swift"} -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">attributed</span><span class="p">[</span><span class="o">..</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>If we have multiple semantic attributes we need to replace for display we don’t want to call <code class="language-swift highlighter-rouge"><span class="n">replaceAttributes</span></code> or <code class="language-swift highlighter-rouge"><span class="n">replacingAttributes</span></code> for each one to avoid unneccessary copies.</p>

<!-- /wp:paragraph -->

<!-- wp:paragraph -->

<p>If we only need to set a single attribute as a replacement we can use <code class="language-swift highlighter-rouge"><span class="n">transformingAttributes</span></code>:</p>

<!-- /wp:paragraph -->

<!-- wp:code {"language":"swift"} -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">displayString</span> <span class="o">=</span> <span class="n">attributed</span><span class="o">.</span><span class="nf">transformingAttributes</span><span class="p">(\</span><span class="o">.</span><span class="n">semantic</span><span class="p">)</span> <span class="p">{</span> <span class="n">semantic</span> <span class="k">in</span>
    <span class="k">if</span> <span class="n">semantic</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="o">.</span><span class="n">name</span> <span class="p">{</span>
        <span class="n">semantic</span><span class="o">.</span><span class="nf">replace</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="p">\</span><span class="o">.</span><span class="n">font</span><span class="p">,</span> <span class="nv">value</span><span class="p">:</span> <span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="nf">bold</span><span class="p">())</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>If we want to replace each semantic attribute with a set of different attributes (just as the <a href="https://5sw.de/2019/08/attributed-strings/#handyExtension">convenience initializer</a> from last time) we again need to write a custom method that loops through the attributes and sets the new attributes:</p>

<!-- /wp:paragraph -->

<!-- wp:code {"language":"swift"} -->

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">AttributedString</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">replaceAttributes</span><span class="p">(</span><span class="n">_</span> <span class="nv">keyPath</span><span class="p">:</span> <span class="kt">KeyPath</span><span class="p">,</span> <span class="nv">replacements</span><span class="p">:</span> <span class="p">[</span><span class="kt">T</span><span class="o">.</span><span class="kt">Value</span><span class="p">:</span> <span class="kt">AttributeContainer</span><span class="p">],</span> <span class="k">default</span> <span class="n">defaultContainer</span><span class="p">:</span> <span class="kt">AttributeContainer</span><span class="p">?</span> <span class="o">=</span> <span class="kc">nil</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">AttributedString</span> <span class="p">{</span>

        <span class="k">var</span> <span class="nv">result</span> <span class="o">=</span> <span class="k">self</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">range</span><span class="p">)</span> <span class="k">in</span> <span class="n">runs</span><span class="p">[</span><span class="n">keyPath</span><span class="p">]</span> <span class="p">{</span>
            <span class="k">if</span> <span class="k">let</span> <span class="nv">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">,</span> <span class="k">let</span> <span class="nv">attributes</span> <span class="o">=</span> <span class="n">replacements</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="p">??</span> <span class="n">defaultContainer</span> <span class="p">{</span>
                <span class="n">result</span><span class="p">[</span><span class="n">range</span><span class="p">]</span><span class="o">.</span><span class="nf">setAttributes</span><span class="p">(</span><span class="n">attributes</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="n">result</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">display</span> <span class="o">=</span> <span class="n">attributed</span><span class="o">.</span><span class="nf">replaceAttributes</span><span class="p">(</span>
    <span class="p">\</span><span class="o">.</span><span class="n">semantic</span><span class="p">,</span> 
    <span class="nv">replacements</span><span class="p">:</span> <span class="p">[</span>
        <span class="o">.</span><span class="nv">name</span><span class="p">:</span> <span class="kt">AttributeContainer</span><span class="p">()</span><span class="o">.</span><span class="nf">font</span><span class="p">(</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="nf">bold</span><span class="p">())</span>
    <span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>

<!-- /wp:code -->

<!-- wp:paragraph -->

<p>Of course this only scratches the surface. There is a ton more that <code class="language-swift highlighter-rouge"><span class="kt">AttributedString</span></code> can do. For me the most interesting part probably is the integrated markdown support. Just watch the <a href="https://developer.apple.com/videos/play/wwdc2021/10109/">What’s New in Foundation</a> talk from WWDC 2021.</p>

<!-- /wp:paragraph -->]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><category term="AttributedString" /><summary type="html"><![CDATA[Finally we are going to get attributed strings as a native Swift value type. So lets see how we can update the example of my last article about attributed strings:]]></summary></entry><entry><title type="html">Attributed Strings</title><link href="http://5sw.de/2019/08/attributed-strings/" rel="alternate" type="text/html" title="Attributed Strings" /><published>2019-08-20T19:49:59+02:00</published><updated>2019-08-20T19:49:59+02:00</updated><id>http://5sw.de/2019/08/attributed-strings</id><content type="html" xml:base="http://5sw.de/2019/08/attributed-strings/"><![CDATA[<p>I had to take a string like “Name (whatever)” and display it in a label. The Name part should be bold, and anything in parentheses should use the regular font.</p>

<p>Pretty simple, I just put the string in a NSAttributedString, find the opening parenthesis and add a bold font attribute to everything up to it. If I find no parenthesis I just bold the whole string:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">attributed</span> <span class="o">=</span> <span class="kt">NSMutableAttributedString</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">boldRange</span> <span class="o">=</span> <span class="kt">NSRange</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">startIndex</span> <span class="o">..&lt;</span> <span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="nf">range</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="s">" ("</span><span class="p">)?</span><span class="o">.</span><span class="n">lowerBound</span> <span class="p">??</span> <span class="n">string</span><span class="o">.</span><span class="n">endIndex</span><span class="p">),</span> <span class="nv">in</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span>
<span class="n">attributed</span><span class="o">.</span><span class="nf">addAttributes</span><span class="p">([</span><span class="o">.</span><span class="nv">font</span><span class="p">:</span> <span class="kt">UIFont</span><span class="o">.</span><span class="nf">systemFont</span><span class="p">(</span><span class="nv">ofSize</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="nv">weight</span><span class="p">:</span> <span class="o">.</span><span class="n">bold</span><span class="p">)],</span> <span class="nv">range</span><span class="p">:</span> <span class="n">boldRange</span><span class="p">)</span>
</code></pre></div></div>

<p>But where should I put this code? The part that specifies the font and other presentation specific things should belong to the view layer. Especially since it has to import UIKit to get UIFont. But parsing the string should go in the model layer. In other views I might want to display that string in a different way, so it makes sense to parse it once.</p>

<p>In this case I could split the string and store both parts separately. Another option is to store the range of the name in addition to the whole string. Both approaches are not very scalable. Once I have multiple ranges to highlight this gets too complicated. What I need is a data structure that can assign values to ranges in a string. There are tons of options how to implement this. But luckily I don’t have to since Foundation provides such a thing: <code class="language-swift highlighter-rouge"><span class="kt">NSAttributedString</span></code>.</p>

<p>First I define a key for a custom attribute and a type for that attribute:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">extension</span> <span class="kt">NSAttributedString</span><span class="o">.</span><span class="kt">Key</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">semantic</span> <span class="o">=</span> <span class="kt">NSAttributedString</span><span class="o">.</span><span class="kt">Key</span><span class="p">(</span><span class="nv">rawValue</span><span class="p">:</span> <span class="s">"de.5sw.semantic"</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">Semantic</span><span class="p">:</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">name</span>
<span class="p">}</span></code></pre></figure>

<p>Then I parse the string and add the custom semantic attribute:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift">    <span class="k">let</span> <span class="nv">attributed</span> <span class="o">=</span> <span class="kt">NSMutableAttributedString</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span>
    <span class="k">let</span> <span class="nv">nameRange</span> <span class="o">=</span> <span class="kt">NSRange</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">startIndex</span> <span class="o">..&lt;</span> <span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="nf">range</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="s">" ("</span><span class="p">)?</span><span class="o">.</span><span class="n">lowerBound</span> <span class="p">??</span> <span class="n">string</span><span class="o">.</span><span class="n">endIndex</span><span class="p">),</span> <span class="nv">in</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span>
    <span class="n">attributed</span><span class="o">.</span><span class="nf">addAttributes</span><span class="p">([</span><span class="o">.</span><span class="nv">semantic</span><span class="p">:</span> <span class="kt">Semantic</span><span class="o">.</span><span class="n">name</span><span class="p">],</span> <span class="nv">range</span><span class="p">:</span> <span class="n">nameRange</span><span class="p">)</span></code></pre></figure>

<p>The code is basically the same as before, but instead of adding the font attribute I add a custom attribute that specifies the <em>meaning</em> of this part of text.</p>

<p>In the view layer I then enumerate all the ranges with the semantic attribute and add the expected formatting:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="k">let</span> <span class="nv">displayString</span> <span class="o">=</span> <span class="kt">NSMutableAttributedString</span><span class="p">(</span><span class="nv">attributedString</span><span class="p">:</span> <span class="n">model</span><span class="o">.</span><span class="n">parsedString</span><span class="p">)</span>
<span class="n">displayString</span><span class="o">.</span><span class="nf">beginEditing</span><span class="p">()</span>
<span class="n">displayString</span><span class="o">.</span><span class="nf">enumerateAttribute</span><span class="p">(</span><span class="o">.</span><span class="n">semantic</span><span class="p">,</span> <span class="nv">in</span><span class="p">:</span> <span class="kt">NSRange</span><span class="p">(</span><span class="nv">location</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">length</span><span class="p">:</span> <span class="n">displayString</span><span class="o">.</span><span class="n">length</span><span class="p">),</span> <span class="nv">options</span><span class="p">:</span> <span class="o">.</span><span class="n">longestEffectiveRangeNotRequired</span><span class="p">)</span> <span class="p">{</span> <span class="n">value</span><span class="p">,</span> <span class="n">range</span><span class="p">,</span> <span class="n">_</span> <span class="k">in</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nv">semantic</span> <span class="o">=</span> <span class="n">value</span> <span class="k">as?</span> <span class="kt">Semantic</span><span class="p">,</span> <span class="n">semantic</span> <span class="o">==</span> <span class="kt">Semantic</span><span class="o">.</span><span class="n">name</span> <span class="p">{</span>
        <span class="n">displayString</span><span class="o">.</span><span class="nf">setAttributes</span><span class="p">([</span><span class="o">.</span><span class="nv">font</span><span class="p">:</span> <span class="kt">UIFont</span><span class="o">.</span><span class="nf">systemFont</span><span class="p">(</span><span class="nv">ofSize</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="nv">weight</span><span class="p">:</span> <span class="o">.</span><span class="n">bold</span><span class="p">)],</span> <span class="nv">range</span><span class="p">:</span> <span class="n">range</span><span class="p">)</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">displayString</span><span class="o">.</span><span class="nf">removeAttribute</span><span class="p">(</span><span class="o">.</span><span class="n">semantic</span><span class="p">,</span> <span class="nv">range</span><span class="p">:</span> <span class="n">range</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="n">displayString</span><span class="o">.</span><span class="nf">endEditing</span><span class="p">()</span></code></pre></figure>

<p>I like this code, now I have a clear separation between the <em>meaning</em> of my data and the way it should be presented.</p>

<p>And since I don’t want to repeat this everywhere I need to style an attributed string I encapsulated this in a handy little extension that uses a dictionary to map my custom attribute to actual styles:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">extension</span> <span class="kt">NSAttributedString</span> <span class="p">{</span>
    <span class="kd">convenience</span> <span class="nf">init</span><span class="p">(</span><span class="nv">attributedString</span><span class="p">:</span> <span class="kt">NSAttributedString</span><span class="p">,</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">NSAttributedString</span><span class="o">.</span><span class="kt">Key</span><span class="p">,</span> <span class="nv">attributes</span><span class="p">:</span> <span class="p">[</span><span class="kt">T</span><span class="p">:</span> <span class="p">[</span><span class="kt">NSAttributedString</span><span class="o">.</span><span class="kt">Key</span><span class="p">:</span> <span class="kt">Any</span><span class="p">]],</span> <span class="k">default</span><span class="p">:</span> <span class="p">[</span><span class="kt">NSAttributedString</span><span class="o">.</span><span class="kt">Key</span><span class="p">:</span> <span class="kt">Any</span><span class="p">]?</span> <span class="o">=</span> <span class="kc">nil</span><span class="p">)</span> <span class="p">{</span>

        <span class="k">let</span> <span class="nv">copy</span> <span class="o">=</span> <span class="kt">NSMutableAttributedString</span><span class="p">(</span><span class="nv">attributedString</span><span class="p">:</span> <span class="n">attributedString</span><span class="p">)</span>
        <span class="n">copy</span><span class="o">.</span><span class="nf">beginEditing</span><span class="p">()</span>
        <span class="n">copy</span><span class="o">.</span><span class="nf">enumerateAttribute</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nv">in</span><span class="p">:</span> <span class="kt">NSRange</span><span class="p">(</span><span class="nv">location</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">length</span><span class="p">:</span> <span class="n">copy</span><span class="o">.</span><span class="n">length</span><span class="p">),</span> <span class="nv">options</span><span class="p">:</span> <span class="o">.</span><span class="n">longestEffectiveRangeNotRequired</span><span class="p">)</span> <span class="p">{</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">range</span><span class="p">,</span> <span class="n">_</span> <span class="k">in</span>
            <span class="k">if</span> <span class="k">let</span> <span class="nv">value</span> <span class="o">=</span> <span class="n">attribute</span> <span class="k">as?</span> <span class="kt">T</span><span class="p">,</span> <span class="k">let</span> <span class="nv">newAttributes</span> <span class="o">=</span> <span class="n">attributes</span><span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="p">??</span> <span class="p">`</span><span class="nv">default</span><span class="p">`</span> <span class="p">{</span>
                <span class="n">copy</span><span class="o">.</span><span class="nf">setAttributes</span><span class="p">(</span><span class="n">newAttributes</span><span class="p">,</span> <span class="nv">range</span><span class="p">:</span> <span class="n">range</span><span class="p">)</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="n">copy</span><span class="o">.</span><span class="nf">removeAttribute</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nv">range</span><span class="p">:</span> <span class="n">range</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="n">copy</span><span class="o">.</span><span class="nf">endEditing</span><span class="p">()</span>

        <span class="k">self</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">attributedString</span><span class="p">:</span> <span class="n">copy</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></figure>]]></content><author><name></name></author><category term="Swift" /><summary type="html"><![CDATA[I had to take a string like “Name (whatever)” and display it in a label. The Name part should be bold, and anything in parentheses should use the regular font.]]></summary></entry><entry><title type="html">Factories and Protocol Composition DI</title><link href="http://5sw.de/2017/04/factories-and-protocol-composition-di/" rel="alternate" type="text/html" title="Factories and Protocol Composition DI" /><published>2017-04-23T11:37:24+02:00</published><updated>2017-04-23T11:37:24+02:00</updated><id>http://5sw.de/2017/04/factories-and-protocol-composition-di</id><content type="html" xml:base="http://5sw.de/2017/04/factories-and-protocol-composition-di/"><![CDATA[<p>Especially on iOS it’s often necessary to create new objects like new view controllers or such things. This often cannot be avoided. This usually is solved by having the object that creates new objects also require all the dependencies of the objects it wants to create. This of course is not a great thing as changes in one class can ripple through the whole project. The <a href="https://5sw.de/2017/04/protocol-composition-and-dependency-injection/">protocol composition approach</a> solves this by having the flow controllers take the whole AppDependency object so they can pass it on.</p>

<p>This solves the problem of having to change some classes when the dependencies of others changes. But it still is bad for testing as you can’t be sure which dependencies are actually needed, and you have no way to influence which class is instantiated. A common solution to this is injecting factory objects that hold all the necessary resources. This of course can result in rather verbose code if a whole new type is created. Luckily closures can also take the role of those factories.</p>

<p>While implementing this I realized that an extra object is not even necessary with the protocol composition DI. The AppDependency object itself can take the role of the factory:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">protocol</span> <span class="kt">MakesSomething</span> <span class="p">{</span>
 <span class="kd">func</span> <span class="nf">makeSomething</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Something</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">AppDependency</span><span class="p">:</span> <span class="kt">MakesSomething</span> <span class="p">{</span>
 <span class="kd">func</span> <span class="nf">makeSomething</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Something</span> <span class="p">{</span>
 <span class="k">return</span> <span class="kt">Something</span><span class="p">(</span><span class="nv">dependencies</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
 <span class="p">}</span>
<span class="p">}</span></code></pre></figure>

<p>That code is not so bad and we can avoid having dependencies on unneeded objects which is good for testing. Usage is like any other dependency:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">class</span> <span class="kt">MyClass</span> <span class="p">{</span>
 <span class="kd">typealias</span> <span class="kt">Dependencies</span> <span class="o">=</span> <span class="kt">MakesSomething</span> <span class="o">&amp;</span> <span class="kt">HasOtherThing</span>
 <span class="k">let</span> <span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span>
 
 <span class="nf">init</span><span class="p">(</span><span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span><span class="p">)</span> <span class="p">{</span>
 <span class="k">self</span><span class="o">.</span><span class="n">dependencies</span> <span class="o">=</span> <span class="n">dependencies</span>
 <span class="p">}</span>
 
 <span class="kd">func</span> <span class="nf">doWork</span><span class="p">()</span> <span class="p">{</span>
 <span class="k">let</span> <span class="nv">something</span> <span class="o">=</span> <span class="n">dependencies</span><span class="o">.</span><span class="nf">makeSomething</span><span class="p">()</span>
 <span class="n">something</span><span class="o">.</span><span class="nf">doWhateverItIsSomethingDoes</span><span class="p">()</span>
 <span class="p">}</span>
<span class="p">}</span></code></pre></figure>]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><category term="DI" /><summary type="html"><![CDATA[Especially on iOS it’s often necessary to create new objects like new view controllers or such things. This often cannot be avoided. This usually is solved by having the object that creates new objects also require all the dependencies of the objects it wants to create. This of course is not a great thing as changes in one class can ripple through the whole project. The protocol composition approach solves this by having the flow controllers take the whole AppDependency object so they can pass it on.]]></summary></entry><entry><title type="html">Protocol Composition and Dependency Injection</title><link href="http://5sw.de/2017/04/protocol-composition-and-dependency-injection/" rel="alternate" type="text/html" title="Protocol Composition and Dependency Injection" /><published>2017-04-17T15:03:12+02:00</published><updated>2017-04-17T15:03:12+02:00</updated><id>http://5sw.de/2017/04/protocol-composition-and-dependency-injection</id><content type="html" xml:base="http://5sw.de/2017/04/protocol-composition-and-dependency-injection/"><![CDATA[<p>I recently read the article “<a href="https://www.merowing.info/using-protocol-compositon-for-dependency-injection/">Using protocol composition for dependency injection</a>” by Krzysztof Zabłocki. I found this to be a rather interesting technique for doing DI, but when trying to implement it I found it somewhat limited:</p>

<ul>
  <li>It doesn’t really handle dependencies that have dependencies themselves.</li>
  <li>No support for lazy instantiation, everything needs to be instantiated up front.</li>
</ul>

<p>Lets look at simple and pretty common example of the object graph I wanted to create:</p>

<ul>
  <li>A view controller at the leaf level, which needs</li>
  <li>An object that provides business logic (like the Interactor from the VIPER pattern), which needs</li>
  <li>the data store (a NSPersistentContainer in my case).</li>
</ul>

<p>This can be translated pretty easily to this pattern:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">HasCoreData</span> <span class="p">{</span>
  <span class="k">var</span> <span class="nv">coreData</span><span class="p">:</span> <span class="kt">NSPersistentContainer</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">protocol</span> <span class="kt">HasListInteractor</span> <span class="p">{</span>
  <span class="k">var</span> <span class="nv">listInteractor</span><span class="p">:</span> <span class="kt">ListInteractor</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">AppDependencies</span><span class="p">:</span> <span class="kt">HasCoreData</span><span class="p">,</span> <span class="kt">HasListInteractor</span> <span class="p">{</span>
  <span class="k">let</span> <span class="nv">coreData</span><span class="p">:</span> <span class="kt">NSPersistentContainer</span>
  <span class="k">let</span> <span class="nv">listInteractor</span><span class="p">:</span> <span class="kt">ListInteractor</span>
<span class="p">}</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="kt">ListViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
  <span class="kd">typealias</span> <span class="kt">Dependencies</span> <span class="o">=</span> <span class="kt">HasListInteractor</span>
  <span class="k">let</span> <span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span>

  <span class="nf">init</span><span class="p">(</span><span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">self</span><span class="o">.</span><span class="n">dependencies</span> <span class="o">=</span> <span class="n">dependencies</span><span class="p">)</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="kt">ListInteractor</span> <span class="p">{</span>
  <span class="kd">typealias</span> <span class="kt">Dependencies</span> <span class="o">=</span> <span class="kt">HasCoreData</span>
  <span class="k">let</span> <span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span>

  <span class="nf">init</span><span class="p">(</span><span class="nv">dependencies</span><span class="p">:</span> <span class="kt">Dependencies</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">self</span><span class="o">.</span><span class="n">dependencies</span> <span class="o">=</span> <span class="n">dependencies</span><span class="p">)</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This all works fine until I try to fill in my AppDependencies struct - to create it I need an instance of my ListInteractor, and to create that I need the AppDependencies struct. So this is not going to work.</p>

<p>Instead I could create a second struct that only implements HasCoreData and use that to initialise the ListInteractor. This approach will work, but will quickly become messy and as hard to refactor as passing every dependency separately. It also won’t address the point of avoiding eager initialisation.</p>

<p>But there is a simple solution that addresses both problems:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">AppDependencies</span><span class="p">:</span> <span class="kt">HasCoreData</span><span class="p">,</span> <span class="kt">HasListInteractor</span> <span class="p">{</span>
  <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">coreData</span><span class="p">:</span> <span class="kt">NSPersistentContainer</span> <span class="o">=</span> <span class="kt">NSPersistentContainer</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"Whatever"</span><span class="p">)</span>
  <span class="kd">lazy</span> <span class="k">var</span> <span class="nv">listInteractor</span><span class="p">:</span> <span class="kt">ListInteractor</span> <span class="o">=</span> <span class="kt">ListInteractor</span><span class="p">(</span><span class="nv">dependencies</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>By making the AppDependencies a class instead of a struct we can use lazy properties to fulfil the protocol requirements. That way we can’t get into the catch-22 situation I described and we get lazy instantiation for free.</p>

<p>Of course there are some other drawbacks to consider:</p>

<ul>
  <li>Cyclic dependencies will cause infinite recursion</li>
  <li>Objects are created lazily, so if you need eager instantiation of some class you need to manually call the getter</li>
</ul>]]></content><author><name></name></author><category term="Swift" /><category term="Swift" /><category term="DI" /><summary type="html"><![CDATA[I recently read the article “Using protocol composition for dependency injection” by Krzysztof Zabłocki. I found this to be a rather interesting technique for doing DI, but when trying to implement it I found it somewhat limited:]]></summary></entry><entry><title type="html">Hello world!</title><link href="http://5sw.de/2017/04/hello-world/" rel="alternate" type="text/html" title="Hello world!" /><published>2017-04-17T11:07:59+02:00</published><updated>2017-04-17T11:07:59+02:00</updated><id>http://5sw.de/2017/04/hello-world</id><content type="html" xml:base="http://5sw.de/2017/04/hello-world/"><![CDATA[<p>Another attempt to write a blog. Lets see how it goes this time.</p>]]></content><author><name></name></author><category term="Uncategorized" /><summary type="html"><![CDATA[Another attempt to write a blog. Lets see how it goes this time.]]></summary></entry></feed>