<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Stewart&apos;s Blog | CreaTECH Solutions</title>
    <link>https://www.createchsol.com/blog.html</link>
    <description>I am trying to write a new blog post every two weeks.  This is in addition to my weekly YouTube videos.  Let me know what you would like me to write about.</description>
    <language>en-us</language>
    <lastBuildDate>Wed, 09 Sep 2026 07:00:00 +0000</lastBuildDate>
    <atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="https://www.createchsol.com/feed.xml" rel="self" type="application/rss+xml" />
  <item>
    <title>Transition or ContentTransition</title>
    <link>https://www.createchsol.com/blog/2026-09-09-transition-or-contenttransition.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-09-09-transition-or-contenttransition.html</guid>
    <pubDate>Wed, 09 Sep 2026 07:00:00 +0000</pubDate>
    <description>SwiftUI transition vs contentTransition: What Actually Changes?</description>
                    <category>SwiftUI</category>
                <category>Technique</category>
    <content:encoded><![CDATA[<h1 id="swiftui-transition-vs-contenttransition-what-actually-changes">SwiftUI <code>transition</code> vs <code>contentTransition</code>: What Actually Changes?</h1>
<p>Learn when to use transition and contentTransition in SwiftUI by asking one question: is the view entering or leaving, or is its content changing in place?</p>
<p>SwiftUI has two modifiers with remarkably similar names:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.transition</span><span class="code-punctuation">(</span>...<span class="code-punctuation">)</span></span><span class="code-line"><span class="code-property">.contentTransition</span><span class="code-punctuation">(</span>...<span class="code-punctuation">)</span></span></code></pre>
<p>They both describe how a change should look, and both need an animation to bring that change to life. But they solve two different problems.</p>
<p>Here is the distinction to remember:</p>
<blockquote><p>Use <code>transition</code> when a view is inserted into or removed from the view hierarchy. Use <code>contentTransition</code> when a view stays in place but the content it displays changes.</p></blockquote>
<p>That is the entire idea. Let’s make it visible.</p>
<h2 id="the-difference-at-a-glance">The difference at a glance</h2>
<div class="markdown-table-wrapper">
<table>
<thead>
<tr><th scope="col">What changed?</th><th scope="col">Before</th><th scope="col">After</th><th scope="col">Modifier</th></tr>
</thead>
<tbody>
<tr><td>The view hierarchy</td><td>No <code>Text</code> view</td><td>A <code>Text</code> view exists</td><td><code>transition</code></td></tr>
<tr><td>The content of an existing view</td><td><code>Text("9")</code></td><td><code>Text("10")</code></td><td><code>contentTransition</code></td></tr>
</tbody>
</table>
</div>
<h2 id="transition-a-view-enters-or-leaves"><code>transition</code>: a view enters or leaves</h2>
<p>Consider a view controlled by an <code>if</code> statement:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">  <span class="code-type">Button</span><span class="code-punctuation">(</span>showMessage <span class="code-punctuation">?</span> <span class="code-string">"Remove View"</span> <span class="code-punctuation">:</span> <span class="code-string">"Insert View"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    withAnimation <span class="code-punctuation">{</span></span><span class="code-line">      showMessage<span class="code-property">.toggle</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line">  <span class="code-punctuation">}</span></span><span class="code-line">  <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.bordered</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">ZStack</span> <span class="code-punctuation">{</span></span><span class="code-line">      <span class="code-keyword">if</span> showMessage <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"I enter and leave"</span><span class="code-punctuation">)</span></span><span class="code-line">          <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.title3</span><span class="code-property">.bold</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">      <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-property">.frame</span><span class="code-punctuation">(</span>height<span class="code-punctuation">:</span> <span class="code-number">40</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>When <code>showMessage</code> becomes <code>false</code>, the <code>Text</code> view is removed. When it becomes <code>true</code>, the <code>Text</code> view is inserted again.</p>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 11.30.32.gif" alt="CleanShot 2026-08-03 at 11.30.32"></p>
<p>This can be visually improved by adding a transition to the view that is being inserted or removed</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">if</span> showMessage <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Hello, SwiftUI!"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.title</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.transition</span><span class="code-punctuation">(</span><span class="code-property">.slide</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The <code>.slide</code> transition describes how that insertion and removal should happen.</p>
<p>However, <strong>must also apply an animation to the state property that is triggering the animation</strong></p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Button</span><span class="code-punctuation">(</span>showMessage <span class="code-punctuation">?</span> <span class="code-string">"Remove View"</span> <span class="code-punctuation">:</span> <span class="code-string">"Insert View"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">  withAnimation <span class="code-punctuation">{</span></span><span class="code-line">    showMessage<span class="code-property">.toggle</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">  <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 11.40.40.gif" alt="CleanShot 2026-08-03 at 11.40.40"></p>
<p>There are several different transitions that you can apply</p>
<div class="markdown-table-wrapper">
<table>
<thead>
<tr><th scope="col">Transition</th><th scope="col">Effect</th></tr>
</thead>
<tbody>
<tr><td>Identity</td><td>No visual transition</td></tr>
<tr><td>Opacity</td><td>Fades in or out</td></tr>
<tr><td>Slide</td><td>Enters from leading; exits toward trailing</td></tr>
<tr><td>Move</td><td>Moves to and from one specified edge</td></tr>
<tr><td>Scale</td><td>Scales between nearly zero and full size</td></tr>
<tr><td>Custom scale</td><td>Uses a custom scale and anchor</td></tr>
<tr><td>Push</td><td>Pushes the new and old content from an edge</td></tr>
<tr><td>Offset</td><td>Moves by a specified distance</td></tr>
</tbody>
</table>
</div>
<p>Many of these transitions have additional parameters like edges, offsets and scales.</p>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 13.49.17.gif" alt="CleanShot 2026-08-03 at 13.49.17"></p>
<p>There are two additional transitions that are rather special</p>
<h3 id="blur-replacement-configurations">Blur-replacement configurations</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.transition</span><span class="code-punctuation">(</span><span class="code-property">.blurReplace</span></span><span class="code-line"><span class="code-property">.transition</span><span class="code-punctuation">(</span><span class="code-property">.blurReplace</span><span class="code-punctuation">(</span><span class="code-property">.downUp</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-property">.transition</span><span class="code-punctuation">(</span><span class="code-property">.blurReplace</span><span class="code-punctuation">(</span><span class="code-property">.upUp</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span></code></pre>
<p>The differences are very subtle</p>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 14.00.38.gif" alt="CleanShot 2026-08-03 at 14.00.38"></p>
<h3 id="combined-transitions">Combined Transitions</h3>
<p>You can also combine transitions like this</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.transition</span><span class="code-punctuation">(</span></span><span class="code-line is-highlighted">    <span class="code-property">.move</span><span class="code-punctuation">(</span>edge<span class="code-punctuation">:</span> <span class="code-property">.trailing</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.combined</span><span class="code-punctuation">(</span>with<span class="code-punctuation">:</span> <span class="code-property">.opacity</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">)</span></span></code></pre>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 14.59.50.gif" alt="CleanShot 2026-08-03 at 14.59.50"></p>
<p>In every case, the important fact is not that some state changed. It is that the state change caused the view to enter or leave the hierarchy and the trigger must be within an animation block</p>
<p>If you enjoy my videos, I have a YouTube video on this topic as well</p>
<blockquote><p><strong>Mastering SwiftUI Transitions – Custom &amp; Built-in Animations</strong></p>
<p><a href="https://www.youtube.com/watch?v=ZmdG0T_58wg" target="_blank" rel="noreferrer">https://www.youtube.com/watch?v=ZmdG0T_58wg</a></p></blockquote>
<h3 id="sf-symbol-view-transition-effects">SF Symbol view-transition effects</h3>
<p>As a special case of view transitions, there are now SFSymbol transitions  too.</p>
<p>These transitions only affect views constructed by SFSymbols</p>
<pre class="code-block"><code><span class="code-line">.transition(.symbolEffect(.automatic))</span><span class="code-line">.transition(.symbolEffect(.appear))</span><span class="code-line">.transition(.symbolEffect(.disappear))</span><span class="code-line">.transition(.symbolEffect(.appear.up))</span><span class="code-line">.transition(.symbolEffect(.appear.down))</span><span class="code-line">.transition(.symbolEffect(.drawOn))   // iOS 26+</span><span class="code-line">.transition(.symbolEffect(.drawOff))  // iOS 26+</span></code></pre>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 14.16.08.gif" alt="CleanShot 2026-08-03 at 14.16.08"></p>
<p>You can do much more with SFSymbol effect transitions and encourage you to watch my YouTube video on that topic.</p>
<blockquote><p><strong>SFSymbol Animations in iOS 17</strong></p>
<p><a href="https://www.youtube.com/watch?v=euia2GkPo7U" target="_blank" rel="noreferrer">https://www.youtube.com/watch?v=euia2GkPo7U</a></p></blockquote>
<h2 id="contenttransition-the-view-stays-its-content-changes"><code>contentTransition</code>: the view stays, its content changes</h2>
<p>Now consider a counter:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">CounterExample</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">  <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> count <span class="code-punctuation">=</span> <span class="code-number">0</span></span><span class="code-line">  </span><span class="code-line">  <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">VStack</span><span class="code-punctuation">(</span>spacing<span class="code-punctuation">:</span> <span class="code-number">20</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">      <span class="code-type">Text</span><span class="code-punctuation">(</span>count<span class="code-punctuation">,</span> format<span class="code-punctuation">:</span> <span class="code-property">.number</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.system</span><span class="code-punctuation">(</span>size<span class="code-punctuation">:</span> <span class="code-number">64</span><span class="code-punctuation">,</span> weight<span class="code-punctuation">:</span> <span class="code-property">.bold</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">      <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Decrease"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">          withAnimation <span class="code-punctuation">{</span></span><span class="code-line">            count <span class="code-punctuation">-</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line">          <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Increase"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">          count <span class="code-punctuation">+</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">      <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line">  <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>When you tap on <strong>Decrease</strong> or <strong>Increase</strong> the state value changes and the view updates.  It is not moving in our out of the view, but the content is changing.</p>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 15.17.45.gif" alt="CleanShot 2026-08-03 at 15.17.45"></p>
<p>However, the transition from one number to another is not very exciting.  We can improve this by applying a <strong>contentTransition</strong>.  Like a <strong>transition</strong> it too requires two parts.  A <strong>contentTransition</strong> modifier and an <strong>animation</strong> block surrounding the trigger.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Text</span><span class="code-punctuation">(</span>count<span class="code-punctuation">,</span> format<span class="code-punctuation">:</span> <span class="code-property">.number</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.system</span><span class="code-punctuation">(</span>size<span class="code-punctuation">:</span> <span class="code-number">64</span><span class="code-punctuation">,</span> weight<span class="code-punctuation">:</span> <span class="code-property">.bold</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">    <span class="code-property">.contentTransition</span><span class="code-punctuation">(</span></span><span class="code-line is-highlighted">        <span class="code-property">.numericText</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-type">Double</span><span class="code-punctuation">(</span>count<span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">)</span></span></code></pre>
<p>And </p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Decrease"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">    withAnimation <span class="code-punctuation">{</span></span><span class="code-line">        count <span class="code-punctuation">-</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line is-highlighted">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Increase"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">    withAnimation <span class="code-punctuation">{</span></span><span class="code-line">        count <span class="code-punctuation">+</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line is-highlighted">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 15.19.12.gif" alt="CleanShot 2026-08-03 at 15.19.12"></p>
<p>In this case, we used a <strong>numericText</strong> content transition where it is observing the value of the count variable which has to be cast as a Double.</p>
<p>SwiftUI provides five main content-transition families, with two forms of <code>numericText</code>.</p>
<div class="markdown-table-wrapper">
<table>
<thead>
<tr><th scope="col">Content transition</th><th scope="col">Purpose</th></tr>
</thead>
<tbody>
<tr><td><code>identity</code></td><td>Makes the content change immediately without a visual transition</td></tr>
<tr><td><code>opacity</code></td><td>Cross-fades between the old and new content</td></tr>
<tr><td><code>interpolate</code></td><td>Interpolates matching text glyphs and their visual properties</td></tr>
<tr><td><code>numericText</code></td><td>Animates changing numeric text vertically</td></tr>
<tr><td><code>symbolEffect</code></td><td>Animates between SF Symbols or symbol configurations</td></tr>
</tbody>
</table>
</div>
<h2 id="sample-content-transitions">Sample content transitions</h2>
<p>Once you know that the content is changing in place, SwiftUI offers several useful choices.</p>
<h3 id="numeric-text">Numeric text</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Text</span><span class="code-punctuation">(</span>count<span class="code-punctuation">,</span> format<span class="code-punctuation">:</span> <span class="code-property">.number</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.contentTransition</span><span class="code-punctuation">(</span><span class="code-property">.numericText</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-type">Double</span><span class="code-punctuation">(</span>count<span class="code-punctuation">)</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span></code></pre>
<p>This is ideal for counters, scores, totals, timers, and changing measurements.</p>
<h3 id="opacity">Opacity</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> isDaytime <span class="code-punctuation">?</span> <span class="code-string">"sun.max.fill"</span> <span class="code-punctuation">:</span> <span class="code-string">"moon.fill"</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.contentTransition</span><span class="code-punctuation">(</span><span class="code-property">.opacity</span><span class="code-punctuation">)</span></span></code></pre>
<p>This gives changing text or images a simple cross-fade.</p>
<h3 id="interpolation">Interpolation</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Tap to animate"</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.system</span><span class="code-punctuation">(</span>size<span class="code-punctuation">:</span> emphasized <span class="code-punctuation">?</span> <span class="code-number">40</span> <span class="code-punctuation">:</span> <span class="code-number">32</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.foregroundStyle</span><span class="code-punctuation">(</span>emphasized <span class="code-punctuation">?</span> <span class="code-property">.blue</span> <span class="code-punctuation">:</span> <span class="code-property">.red</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.contentTransition</span><span class="code-punctuation">(</span><span class="code-property">.interpolate</span><span class="code-punctuation">)</span></span></code></pre>
<p>When the text contains matching glyphs, interpolation can animate properties such as size, position, and color.</p>
<h3 id="symbol-replacement">Symbol replacement</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> isLiked <span class="code-punctuation">?</span> <span class="code-string">"heart.fill"</span> <span class="code-punctuation">:</span> <span class="code-string">"heart"</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-property">.contentTransition</span><span class="code-punctuation">(</span><span class="code-property">.symbolEffect</span><span class="code-punctuation">(</span><span class="code-property">.replace</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span></code></pre>
<p>This is designed for changes between compatible SF Symbols.</p>
<p><img src="blog/2026-09-09-transition-or-contenttransition_assets/CleanShot 2026-08-03 at 15.27.18.gif" alt="CleanShot 2026-08-03 at 15.27.18"></p>
<h2 id="a-simple-decision-test">A simple decision test</h2>
<p>When you are unsure which modifier to use, look at the code that responds to the state change.</p>
<p>Ask these questions in order:</p>
<ol><li><strong>Does an <code>if</code>, <code>switch</code>, collection update, or identity change cause a view to appear or disappear?</strong></li></ol>
<p>   Start with <code>transition</code>.</p>
<ol start="2"><li><strong>Does the same <code>Text</code>, <code>Image</code>, or other view remain while its displayed content changes?</strong></li></ol>
<p>   Start with <code>contentTransition</code>.</p>
<ol start="3"><li><strong>Did you provide an animation for the state change?</strong></li></ol>
<p>   If not, neither transition will have an animated change to perform.</p>
<h2 id="final-takeaway">Final takeaway</h2>
<p>The names are similar, but the jobs are not:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">View enters or leaves       → transition</span><span class="code-line">View stays, content changes → contentTransition</span></code></pre>
<p>Once you focus on <em>what actually changed</em>—the hierarchy or the content—the choice becomes straightforward.</p>
<p>And as with all animation, restraint helps. A transition should clarify a change, not compete with it.</p>]]></content:encoded>
  </item>
  <item>
    <title>Mac App Direct Distribution, DMG Signing &amp; Notarization Guide</title>
    <link>https://www.createchsol.com/blog/2026-08-30-mac-app-direct-distribution-dmg-signing-notarization-guide.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-08-30-mac-app-direct-distribution-dmg-signing-notarization-guide.html</guid>
    <pubDate>Sun, 30 Aug 2026 07:00:00 +0000</pubDate>
    <description>This guide walks through a generic directdistribution workflow for a macOS app.</description>
                    <category>Distribution</category>
                <category>DMG</category>
                <category>macOS</category>
                <category>Xcode 27</category>
    <content:encoded><![CDATA[<p>This guide walks through a generic direct-distribution workflow for a macOS app.</p>
<p>You can following along with me as I preform all of these steps in this YouTube video: <a href="https://youtu.be/fzK3jodJCuM" target="_blank" rel="noreferrer">Distribute Your macOS App Like a Pro  DMG, Code Signing &amp; Notarization</a></p>
<a href="http://www.youtube.com/watch?feature=player_embedded&v=fzK3jodJCuM
" target="_blank"><img src="http://img.youtube.com/vi/fzK3jodJCuM/0.jpg" 
alt="Mac App Direct Distribution" width="480" height="360" border="1" /></a>
<ol><li>Archive the app in Xcode.</li><li>Export the notarized <code>.app</code>.</li><li>Verify the exported app's signature and Gatekeeper status.</li><li>Build a polished installer DMG with a background image and an Applications shortcut.</li><li>Convert the DMG to a compressed read-only image.</li><li>Sign, notarize, staple, and verify the final DMG.</li></ol>
<p>The commands intentionally use placeholders so this document can be shared safely.</p>
<h2 id="placeholders-used-in-this-guide">Placeholders Used in This Guide</h2>
<p>Some values are known before you start. Others are discovered later from command output or created during the notarization setup. This guide introduces each value when you need it.</p>
<p>Values you choose at the beginning:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">&lt;&lt;APPNAME&gt;&gt;                 # App bundle name without .app, for example: MyApp</span><span class="code-line">&lt;&lt;VOLUMENAME&gt;&gt;              # Mounted DMG volume name, for example: MyApp Installer</span><span class="code-line">&lt;&lt;DMGNAME&gt;&gt;                 # Final DMG filename without .dmg, for example: MyApp</span></code></pre>
<p>Values you will collect or create later:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">&lt;&lt;APPLE_ID&gt;&gt;                # Apple ID email for the Apple Developer account</span><span class="code-line">&lt;&lt;TEAM_ID&gt;&gt;                 # Apple Developer Team ID</span><span class="code-line">&lt;&lt;NOTARY_PROFILE&gt;&gt;          # Local Keychain profile name for notarytool</span><span class="code-line">&lt;&lt;APP_SPECIFIC_PASSWORD&gt;&gt;   # App-specific password generated at account.apple.com</span><span class="code-line">&lt;&lt;DEVELOPER_ID_CERT&gt;&gt;       # Developer ID Application certificate name or SHA-1 hash</span></code></pre>
<h2 id="1-archive-the-app-in-xcode">1. Archive the App in Xcode</h2>
<p>Archiving creates the distributable build using your release configuration, signing settings, hardened runtime, entitlements, and provisioning choices. For direct distribution outside the Mac App Store, this is the starting point for a properly signed Developer ID app.</p>
<p>In Xcode:</p>
<ol><li>Select a generic macOS destination, not a simulator.</li><li>Choose <strong>Product &gt; Archive</strong>.</li><li>When Organizer opens, select the archive.</li><li>Click <strong>Distribute App</strong>.</li><li>Choose <strong>Direct Distribution</strong>.</li><li>Continue through the signing and upload steps.</li><li>Wait for Apple to process/notarize the archive.</li><li>Export the notarized app when Xcode allows it.</li></ol>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Xcode Organizer shows the archive as validated/notarized, and you can export a signed .app bundle.</span></code></pre>
<h2 id="2-create-a-release-builds-folder">2. Create a Release Builds Folder</h2>
<p>Keeping the exported app, temporary DMG, final DMG, and background image in one working folder makes the rest of the process easier to follow. It also avoids accidentally packaging the wrong copy of the app.</p>
<p>Create a folder somewhere convenient, such as your Desktop:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">~/Desktop/ReleaseBuilds</span></code></pre>
<p>In Finder:</p>
<ol><li>Open your Desktop.</li><li>Create a new folder named <code>ReleaseBuilds</code>.</li><li>Copy the notarized app you exported from Xcode into that folder.</li></ol>
<p>If you already have a background image for the DMG, this is also a good place to put it so everything for this release lives together.</p>
<h2 id="3-set-the-starting-variables">3. Set the Starting Variables</h2>
<p>Do this after copying the exported app into <code>ReleaseBuilds</code> and before running the first verification command.</p>
<ol><li>Open Terminal.</li><li>Use <code>cd</code> to move into the <code>ReleaseBuilds</code> folder.</li><li>Copy the variable block below.</li><li>Replace the placeholders with your app name, volume name, DMG name, and exported app path.</li><li>Paste the edited block into Terminal and press Return.</li></ol>
<p>After that, the early commands can use short names like <code>$APP_PATH</code>, <code>$TEMP_DMG</code>, and <code>$FINAL_DMG</code> instead of making you type the full app name and file paths over and over.</p>
<p>Template:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">APP_NAME="&lt;&lt;APPNAME&gt;&gt;"</span><span class="code-line">VOLUME_NAME="&lt;&lt;VOLUMENAME&gt;&gt;"</span><span class="code-line">DMG_NAME="&lt;&lt;DMGNAME&gt;&gt;"</span><span class="code-line">APP_PATH="/path/to/${APP_NAME}.app"</span><span class="code-line">TEMP_DMG="${DMG_NAME}-temp.dmg"</span><span class="code-line">FINAL_DMG="${DMG_NAME}.dmg"</span></code></pre>
<p>Example using fake values:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">cd ~/Desktop/ReleaseBuilds</span><span class="code-line"></span><span class="code-line">APP_NAME="MyGreatApp"</span><span class="code-line">VOLUME_NAME="MyGreatApp Installer"</span><span class="code-line">DMG_NAME="MyGreatApp"</span><span class="code-line">APP_PATH="$HOME/Desktop/ReleaseBuilds/MyGreatApp.app"</span><span class="code-line">TEMP_DMG="${DMG_NAME}-temp.dmg"</span><span class="code-line">FINAL_DMG="${DMG_NAME}.dmg"</span></code></pre>
<p>With those example values, the guide will create:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">MyGreatApp-temp.dmg</span><span class="code-line">MyGreatApp.dmg</span></code></pre>
<p>And when a later command says:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign --verify --deep --strict --verbose=2 "$APP_PATH"</span></code></pre>
<p>Terminal treats it as:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign --verify --deep --strict --verbose=2 "$HOME/Desktop/ReleaseBuilds/MyGreatApp.app"</span></code></pre>
<p>The important thing: <strong>Keep using the same Terminal window as you work through the guide. The variables live in that Terminal session</strong>.</p>
<h2 id="4-verify-the-exported-app-signature">4. Verify the Exported App Signature</h2>
<p>Notarization is not a substitute for local verification. Before packaging the app into a DMG, confirm that the <code>.app</code> bundle is signed correctly and that nested code, frameworks, helpers, and resources pass strict validation.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign --verify --deep --strict --verbose=2 "$APP_PATH"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">/path/to/&lt;&lt;APPNAME&gt;&gt;.app: valid on disk</span><span class="code-line">/path/to/&lt;&lt;APPNAME&gt;&gt;.app: satisfies its Designated Requirement</span></code></pre>
<p>If this fails, fix the app signing issue before building the DMG.</p>
<h2 id="5-inspect-the-app-signing-details">5. Inspect the App Signing Details</h2>
<p>This confirms which Developer ID certificate signed the app. You may also need the team identifier later when storing notarization credentials.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign -dv --verbose=4 "$APP_PATH"</span></code></pre>
<p>Look for these fields:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Authority=Developer ID Application: &lt;&lt;DEVELOPER_NAME&gt;&gt; (&lt;&lt;TEAM_ID&gt;&gt;)</span><span class="code-line">TeamIdentifier=&lt;&lt;TEAM_ID&gt;&gt;</span><span class="code-line">Runtime Version=...</span></code></pre>
<p>Copy the value after <code>TeamIdentifier=</code>. You will need it later when you store notarization credentials.</p>
<p>Now save it as a Terminal variable:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">TEAM_ID="&lt;&lt;TEAM_ID&gt;&gt;"</span></code></pre>
<h2 id="6-check-gatekeeper-assessment-for-the-app">6. Check Gatekeeper Assessment for the App</h2>
<p><strong>Gatekeeper</strong> is what users encounter when opening software downloaded from the internet. This check confirms macOS sees the exported app as acceptable executable code.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">spctl -a -t exec -vv "$APP_PATH"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">/path/to/&lt;&lt;APPNAME&gt;&gt;.app: accepted</span><span class="code-line">source=Notarized Developer ID</span><span class="code-line">origin=Developer ID Application: &lt;&lt;DEVELOPER_NAME&gt;&gt; (&lt;&lt;TEAM_ID&gt;&gt;)</span></code></pre>
<p>The exact wording can vary by macOS version, but you want <code>accepted</code> and a Developer ID/notarized source.</p>
<h2 id="7-create-a-writable-temporary-dmg">7. Create a Writable Temporary DMG</h2>
<p>The temporary DMG is the staging area. You need it writable so you can copy in the app, add the Applications shortcut, add the background image, and set Finder layout preferences.</p>
<p>Choose a size comfortably larger than your app bundle.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">diskutil image create blank \</span><span class="code-line">  --size 100m \</span><span class="code-line">  --volumeName "$VOLUME_NAME" \</span><span class="code-line">  --format UDRW \</span><span class="code-line">  "$TEMP_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">created: /path/to/&lt;&lt;DMGNAME&gt;&gt;-temp.dmg</span></code></pre>
<p>If your app is larger, increase <code>100m</code> to something appropriate, such as <code>250m</code> or <code>500m</code>.</p>
<h2 id="8-mount-the-temporary-dmg">8. Mount the Temporary DMG</h2>
<p>Mounting exposes the writable disk image as a normal Finder volume under <code>/Volumes</code>, which lets you arrange the installer exactly how users will see it.</p>
<p>In Finder, double-click the temporary DMG:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">&lt;&lt;DMGNAME&gt;&gt;-temp.dmg</span></code></pre>
<p>Expected result: a new mounted volume appears on your Desktop and in Finder's sidebar.</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">/Volumes/&lt;&lt;VOLUMENAME&gt;&gt;</span></code></pre>
<h2 id="9-copy-the-app-into-the-mounted-volume">9. Copy the App into the Mounted Volume</h2>
<p>The DMG should contain the app bundle users will drag into Applications.</p>
<p>In Finder:</p>
<ol><li>Open the mounted <code>&lt;&lt;VOLUMENAME&gt;&gt;</code> volume.</li><li>Find your exported <code>&lt;&lt;APPNAME&gt;&gt;.app</code>.</li><li>Drag <code>&lt;&lt;APPNAME&gt;&gt;.app</code> into the mounted volume.</li></ol>
<h2 id="10-add-the-applications-shortcut">10. Add the Applications Shortcut</h2>
<p>The Applications shortcut gives users the familiar drag-to-install experience: app on the left, Applications on the right.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">ln -s /Applications "/Volumes/${VOLUME_NAME}/Applications"</span></code></pre>
<p>You should now see both the application and the shortcut to the applications folder in the mounted volume.</p>
<h2 id="11-add-the-hidden-background-folder">11. Add the Hidden Background Folder</h2>
<p>Finder can use an image stored inside the DMG as the window background. Keeping it in <code>.background</code> keeps the installer window clean for users and under normal circumstances, background folder will be hidden</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">mkdir -p "/Volumes/${VOLUME_NAME}/.background"</span></code></pre>
<p>Then, in Finder:</p>
<ol><li>Open the mounted volume.</li><li>Press <strong>Command-Shift-.</strong> to show hidden files.</li><li>Open the <code>.background</code> folder.</li><li>Drag your background image into that folder.</li></ol>
<p>Expected result: the background image is inside <code>/Volumes/&lt;&lt;VOLUMENAME&gt;&gt;/.background/</code>.</p>
<h2 id="12-configure-the-finder-window">12. Configure the Finder Window</h2>
<p>Finder stores window layout metadata on the mounted volume. This gives users a clean installer window instead of a plain file listing.</p>
<p>Open the mounted DMG volume in Finder, then set:</p>
<ol><li><strong>View &gt; As Icons</strong></li><li><strong>View &gt; Show View Options</strong> or press <strong>Command-J</strong></li><li>Enable <strong>Always open in icon view</strong></li><li>Set icon size, commonly <code>96</code> or <code>128</code></li><li>Set text size, commonly <code>12</code></li><li>Set <strong>Background &gt; Picture</strong></li><li>Open the hidden <code>.background</code> folder in Finder.</li><li>Drag the background image from <code>.background</code> onto the picture drop target in the View Options window.</li><li>Position <code>&lt;&lt;APPNAME&gt;&gt;.app</code> on the left</li><li>Position <code>Applications</code> on the right</li><li>Resize the Finder window to the desired final size</li><li>Hide hidden files again with <strong>Command-Shift-.</strong></li><li>Close the Finder window</li></ol>
<h2 id="13-eject-the-temporary-dmg">13. Eject the Temporary DMG</h2>
<p>Ejecting the mounted volume finalizes the changes you made to the writable temporary DMG.</p>
<p>In Finder:</p>
<ol><li>Close the mounted DMG window.</li><li>Eject the <code>&lt;&lt;VOLUMENAME&gt;&gt;</code> volume from the Finder sidebar or Desktop.</li></ol>
<p>If Finder says the volume is still in use, close any Finder windows showing the mounted DMG and try again.</p>
<h2 id="14-convert-to-a-compressed-read-only-dmg">14. Convert to a Compressed Read-Only DMG</h2>
<p>Users should receive a final DMG that is smaller, read-only, and not accidentally modifiable.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">diskutil image create from \</span><span class="code-line">  "$TEMP_DMG" \</span><span class="code-line">  "$FINAL_DMG" \</span><span class="code-line">  --format UDZO</span></code></pre>
<p>You can remove the temporary writable image after confirming the final DMG exists and when mounted and opened, you can see the background image as well as the application and shortcut to the applications folder.</p>
<h2 id="15-create-an-app-specific-password">15. Create an App-Specific Password</h2>
<p>The <code>notarytool</code> should not use your normal Apple ID password. Apple requires an app-specific password for command-line notarization when using Apple ID authentication.</p>
<p>At <a href="https://account.apple.com" target="_blank" rel="noreferrer">account.apple.com</a>:</p>
<ol><li>Sign in with the Apple ID for the developer account.</li><li>Open <strong>Sign-In and Security</strong>.</li><li>Choose <strong>App-Specific Passwords</strong>.</li><li>Generate a new password.</li><li>Give it a recognizable name, such as <code>NotaryTool</code>.</li><li>Copy it immediately.</li></ol>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Apple shows a one-time app-specific password.</span></code></pre>
<p>Do not paste the real password into documentation, screenshots, source control, issue trackers, or chat. You cannot retrieve it later; if lost, revoke it and create another one.</p>
<h2 id="16-store-notarization-credentials-in-keychain">16. Store Notarization Credentials in Keychain</h2>
<p>Storing credentials once in Keychain avoids putting secrets directly into every notarization command.</p>
<p>Before running the command, decide on two values:</p>
<ol><li><code>APPLE_ID</code>: the Apple ID email address for your Apple Developer account.</li><li><code>NOTARY_PROFILE</code>: a local nickname for these saved credentials. You choose this name. <code>MyNotaryProfile</code> is a common example.</li></ol>
<p>Save those values in Terminal:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">APPLE_ID="&lt;&lt;APPLE_ID&gt;&gt;"</span><span class="code-line">NOTARY_PROFILE="&lt;&lt;NOTARY_PROFILE&gt;&gt;"</span></code></pre>
<p>Example using fake values:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">APPLE_ID="developer@example.com"</span><span class="code-line">NOTARY_PROFILE="MyNotaryProfile"</span></code></pre>
<p>Do not define the app-specific password as a Terminal variable. It is a secret, and it is only needed once so <code>notarytool</code> can save it securely in Keychain.</p>
<p>Run this command and replace <code>&lt;&lt;APP_SPECIFIC_PASSWORD&gt;&gt;</code> directly in the command with the app-specific password you just generated.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">xcrun notarytool store-credentials "$NOTARY_PROFILE" \</span><span class="code-line">  --apple-id "$APPLE_ID" \</span><span class="code-line">  --team-id "$TEAM_ID" \</span><span class="code-line">  --password "&lt;&lt;APP_SPECIFIC_PASSWORD&gt;&gt;"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Credentials saved to Keychain.</span></code></pre>
<h2 id="17-find-and-save-the-developer-id-certificate">17. Find and Save the Developer ID Certificate</h2>
<p>Signing the DMG requires the correct Developer ID Application identity. You can sign with either the certificate name or its SHA-1 hash.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">security find-identity -v -p codesigning</span></code></pre>
<p>Look for:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">1) &lt;&lt;SHA_1_HASH&gt;&gt; "Developer ID Application: &lt;&lt;DEVELOPER_NAME&gt;&gt; (&lt;&lt;TEAM_ID&gt;&gt;)"</span></code></pre>
<p>The SHA-1 hash is not labeled in the output. It is the long 40-character string before the certificate name.</p>
<p>Example using fake values:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">1) AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "Developer ID Application: Example Developer (ABCDE12345)"</span><span class="code-line">2) BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB "Developer ID Application: Example Developer (ABCDE12345)"</span><span class="code-line">   2 valid identities found</span></code></pre>
<p>In that example, either <code>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</code> or <code>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</code> is a SHA-1 hash.</p>
<p>Use the Developer ID Application identity, not a Mac Developer, Apple Development, or Installer certificate.</p>
<p>Copy either the SHA-1 hash or the full certificate name and save it in Terminal. If you see more than one <code>Developer ID Application</code> identity with the same certificate name, use one of the SHA-1 hashes instead of the name so <code>codesign</code> knows exactly which identity you mean.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">DEVELOPER_ID_CERT="&lt;&lt;DEVELOPER_ID_CERT&gt;&gt;"</span></code></pre>
<p>Example using a fake SHA-1 hash:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">DEVELOPER_ID_CERT="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"</span></code></pre>
<p>Example using a fake certificate name:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">DEVELOPER_ID_CERT="Developer ID Application: Example Developer (ABCDE12345)"</span></code></pre>
<h2 id="18-sign-the-final-dmg">18. Sign the Final DMG</h2>
<p>The app inside the DMG is already signed, but the DMG itself is a separate downloadable artifact. Signing it lets macOS verify that the disk image was created by your Developer ID certificate and has not been modified.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign \</span><span class="code-line">  --force \</span><span class="code-line">  --sign "$DEVELOPER_ID_CERT" \</span><span class="code-line">  "$FINAL_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line"># No output usually means success.</span></code></pre>
<h2 id="19-verify-the-dmg-signature">19. Verify the DMG Signature</h2>
<p>This catches signing mistakes before notarization.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign --verify --verbose=2 "$FINAL_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">&lt;&lt;DMGNAME&gt;&gt;.dmg: valid on disk</span><span class="code-line">&lt;&lt;DMGNAME&gt;&gt;.dmg: satisfies its Designated Requirement</span></code></pre>
<h2 id="20-inspect-the-dmg-certificate-details">20. Inspect the DMG Certificate Details</h2>
<p>This confirms the DMG was signed by the intended Developer ID identity.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">codesign -dv --verbose=4 "$FINAL_DMG"</span></code></pre>
<p>Look for:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Authority=Developer ID Application: &lt;&lt;DEVELOPER_NAME&gt;&gt; (&lt;&lt;TEAM_ID&gt;&gt;)</span><span class="code-line">TeamIdentifier=&lt;&lt;TEAM_ID&gt;&gt;</span></code></pre>
<h2 id="21-submit-the-dmg-for-notarization">21. Submit the DMG for Notarization</h2>
<p>Notarization lets Apple scan and approve the distributable artifact. The <code>--wait</code> option keeps the command running until Apple returns a final status.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">xcrun notarytool submit "$FINAL_DMG" \</span><span class="code-line">  --keychain-profile "$NOTARY_PROFILE" \</span><span class="code-line">  --wait</span></code></pre>
<p>Expected successful result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">id: &lt;&lt;SUBMISSION_ID&gt;&gt;</span><span class="code-line">status: Accepted</span></code></pre>
<p>If the status is not <code>Accepted</code>, fetch the log using the submission ID:</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">xcrun notarytool log "&lt;&lt;SUBMISSION_ID&gt;&gt;" \</span><span class="code-line">  --keychain-profile "$NOTARY_PROFILE"</span></code></pre>
<p>Use the log to identify what Apple rejected. Common issues include unsigned nested code, missing hardened runtime, invalid entitlements, or packaging the wrong build.</p>
<h2 id="22-staple-the-notarization-ticket">22. Staple the Notarization Ticket</h2>
<p>Stapling attaches the notarization ticket to the DMG. This lets users install the app even when macOS cannot immediately contact Apple's notarization servers.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">xcrun stapler staple "$FINAL_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">The staple and validate action worked!</span></code></pre>
<h2 id="23-validate-the-stapled-ticket">23. Validate the Stapled Ticket</h2>
<p>This confirms the ticket is attached to the DMG and readable.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">xcrun stapler validate "$FINAL_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">The validate action worked!</span></code></pre>
<h2 id="24-final-gatekeeper-verification">24. Final Gatekeeper Verification</h2>
<p>This is the closest command-line check to what users will experience when opening the downloaded DMG.</p>
<pre class="code-block" data-language="BASH"><code class="language-bash"><span class="code-line">spctl \</span><span class="code-line">  -a \</span><span class="code-line">  -t open \</span><span class="code-line">  --context context:primary-signature \</span><span class="code-line">  -vv \</span><span class="code-line">  "$FINAL_DMG"</span></code></pre>
<p>Expected result:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">&lt;&lt;DMGNAME&gt;&gt;.dmg: accepted</span><span class="code-line">source=Notarized Developer ID</span><span class="code-line">origin=Developer ID Application: &lt;&lt;DEVELOPER_NAME&gt;&gt; (&lt;&lt;TEAM_ID&gt;&gt;)</span></code></pre>
<p>Now all you have to do is publish the DMG for download.  This can one on your website or through some shared folder.  You can also publish it via GitHub Releases and the video mentioned at the top of this blog goes through that process.</p>]]></content:encoded>
  </item>
  <item>
    <title>A Change of State</title>
    <link>https://www.createchsol.com/blog/2026-08-12-a-change-of-state.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-08-12-a-change-of-state.html</guid>
    <pubDate>Wed, 12 Aug 2026 07:00:00 +0000</pubDate>
    <description>One of the quieter, but very welcome, improvements in Xcode 27 is a change to how @State is implemented. Although your code looks almost identical, the way SwiftUI initializes state has changed significantly.</description>
                    <category>SwiftUI</category>
                <category>Xcode 27</category>
    <content:encoded><![CDATA[<p>One of the quieter, but very welcome, improvements in Xcode 27 is a change to how <code>@State</code> is implemented. Although your code looks almost identical, the way SwiftUI initializes state has changed significantly.</p>
<p>In this post, we will investigate the difference between Xcode 26 and Xcode 27, explain why the change was made, and discuss the benefits you get simply by building your app with Xcode 27.</p>
<p>Consider the following code:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">SwiftUI</span></span><span class="code-line"></span><span class="code-line"><span class="code-attribute">@Observable</span></span><span class="code-line">final <span class="code-keyword">class</span> <span class="code-type">DemoModel</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> id <span class="code-punctuation">=</span> <span class="code-type">UUID</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        print<span class="code-punctuation">(</span><span class="code-string">"DemoModel initialized:"</span><span class="code-punctuation">,</span> id<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ContentView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> refreshCount <span class="code-punctuation">=</span> <span class="code-number">0</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> model <span class="code-punctuation">=</span> <span class="code-type">DemoModel</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Parent refreshes: \(refreshCount)"</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.title2</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Refresh Parent View"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                refreshCount <span class="code-punctuation">+</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.borderedProminent</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Divider</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">VStack</span><span class="code-punctuation">(</span>spacing<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Child View"</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.headline</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-type">Text</span><span class="code-punctuation">(</span>model<span class="code-property">.id</span><span class="code-property">.uuidString</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.caption</span><span class="code-property">.monospaced</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.multilineTextAlignment</span><span class="code-punctuation">(</span><span class="code-property">.center</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Watch the console"</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.foregroundStyle</span><span class="code-punctuation">(</span><span class="code-property">.secondary</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.background</span><span class="code-punctuation">(</span><span class="code-property">.thinMaterial</span><span class="code-punctuation">,</span> <span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-property">.rect</span><span class="code-punctuation">(</span>cornerRadius<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>If I execute this code in the preview canvas, when the view loads, the model's id property is used in the child view and it is also printed to the console.</p>
<p>Each time I tap the Refresh Parent View button, only the view enumerating the number of refreshes is updated.  There is no reinitialization of the observable model.</p>
<p><img src="blog/2026-08-12-a-change-of-state_assets/Ex1.gif" alt="Ex1"></p>
<p>This version works perfectly well. <code>ContentView</code> owns both the <code>refresh counter</code> and the <code>model</code> used by the lower portion of the interface.</p>
<p>Although there is nothing technically wrong with this design, the lower portion of the interface really belongs in its own view.</p>
<h2 id="refactoring-the-child-view">Refactoring the Child View</h2>
<p>Let's extract the lower section into a separate <code>ChildView</code> and initialize the model as a SwiftUI @State property for that view.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ChildView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> model <span class="code-punctuation">=</span> <span class="code-type">DemoModel</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">VStack</span><span class="code-punctuation">(</span>spacing<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Child View"</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.headline</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span>model<span class="code-property">.id</span><span class="code-property">.uuidString</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.caption</span><span class="code-property">.monospaced</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.multilineTextAlignment</span><span class="code-punctuation">(</span><span class="code-property">.center</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Watch the console"</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.foregroundStyle</span><span class="code-punctuation">(</span><span class="code-property">.secondary</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.background</span><span class="code-punctuation">(</span><span class="code-property">.thinMaterial</span><span class="code-punctuation">,</span> <span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-property">.rect</span><span class="code-punctuation">(</span>cornerRadius<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Then, in ContentView, remove the model from the parent ContentView then replace the VStack after the Divider with the <code>ChildView</code>.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ContentView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> refreshCount <span class="code-punctuation">=</span> <span class="code-number">0</span></span><span class="code-line is-highlighted">    <span class="code-comment">// @State private var model = DemoModel()</span></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Parent refreshes: \(refreshCount)"</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.title2</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Refresh Parent View"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                refreshCount <span class="code-punctuation">+</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.borderedProminent</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Divider</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">            <span class="code-type">ChildView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This version better reflects how SwiftUI views should own their own state. <code>ContentView</code> owns the refresh counter, while <code>ChildView</code> owns the <code>DemoModel</code> it displays.</p>
<p>We I execute this in the canvas we see a very different behaviour.</p>
<ol><li>As before, when I load the view, the model is initialized and the <code>id</code> is printed to the console and used in the child view presentation.  The difference however, is that it is the <code>ChildView</code> that is doing the initialization and not the parent <code>ContentView</code>.</li><li>When I tap on the refresh button, the UUID Displayed on the screen never changes.</li><li>The console prints multiple <code>DemoModel initialized...</code> messages.</li></ol>
<p>The UUID proves that SwiftUI continues to use the original <code>DemoModel</code> stored in <code>@State</code>.</p>
<p>The console tells a different story. Every time the parent view is recreated, the expression <code>DemoModel()</code> is evaluated again, creating additional instances that are immediately discarded.</p>
<p><img src="blog/2026-08-12-a-change-of-state_assets/Ex2.gif" alt="Ex2"></p>
<h2 id="same-code-but-xcode-27">Same Code, but Xcode 27</h2>
<p>If we open and run this same code in <strong>Xcode 27</strong> we get an entirely different result.</p>
<p>The UUID still never changes, but this time the console prints <strong>only one</strong> initialization message.</p>
<p><img src="blog/2026-08-12-a-change-of-state_assets/Ex3.gif" alt="Ex3"></p>
<h2 id="whats-changed">What's Changed?</h2>
<p>In Xcode 26 and earlier, <code>@State</code> is treated as <code>PropertyWrapper</code> whereas in Xcode 27, it is now a <code>Macro</code></p>
<p>Every tap increments <code>refreshCount</code>, which causes SwiftUI to recreate the <code>ContentView</code> value.</p>
<p>In Xcode 26, recreating the view also reevaluated this expression:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> model <span class="code-punctuation">=</span> <span class="code-type">DemoModel</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>SwiftUI continued using the existing state storage, but the initialization expression still executed. The newly created object was immediately discarded because SwiftUI already had a stored state value.</p>
<p>The flow looked something like this:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Xcode 26</span><span class="code-line"></span><span class="code-line">Parent refresh</span><span class="code-line">      ↓</span><span class="code-line">ContentView recreated</span><span class="code-line">      ↓</span><span class="code-line">ChildView recreated</span><span class="code-line">      ↓</span><span class="code-line">DemoModel() called again</span><span class="code-line">      ↓</span><span class="code-line">New DemoModel instance created</span><span class="code-line">      ↓</span><span class="code-line">SwiftUI already has state storage</span><span class="code-line">      ↓</span><span class="code-line">New instance discarded</span></code></pre>
<p>The important part is that the UUID on screen does not change. SwiftUI is still preserving the original state value. The problem is that extra <code>DemoModel</code> instances are being created along the way and then thrown away.</p>
<p>In <strong>Xcode 27</strong>, the initialization expression is evaluated lazily when the state storage is first created. Subsequent recreations of the view no longer evaluate <code>DemoModel()</code>.</p>
<p>The flow is now much simpler:</p>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Xcode 27</span><span class="code-line"></span><span class="code-line">Parent refresh</span><span class="code-line">      ↓</span><span class="code-line">ContentView recreated</span><span class="code-line">      ↓</span><span class="code-line">ChildView recreated</span><span class="code-line">      ↓</span><span class="code-line">Existing state storage reused</span><span class="code-line">      ↓</span><span class="code-line">No new DemoModel instance created</span></code></pre>
<p>From your perspective as the developer, the code hasn't changed. The behavior behind the scenes has.</p>
<h2 id="why-this-matters">Why This Matters</h2>
<p>In this sample, the initializer simply prints a message.</p>
<p>Real applications often do much more inside an initializer. They might:</p>
<ul><li>Open a database.</li><li>Read files from disk.</li><li>Register for notifications.</li><li>Allocate large amounts of memory.</li><li>Perform expensive calculations.</li><li>Start asynchronous work.</li><li>Create timers or observers.</li></ul>
<p>Under the old implementation, that work could happen repeatedly even though every newly created object was immediately discarded.</p>
<p>The new implementation eliminates that unnecessary work.</p>
<h2 id="the-benefits">The Benefits</h2>
<p>The improvement is about more than performance.</p>
<p>Your code now behaves the way it appears to behave.</p>
<p>When you write:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> model <span class="code-punctuation">=</span> <span class="code-type">DemoModel</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>most developers naturally expect <code>DemoModel()</code> to be called exactly once.</p>
<p>That expectation is finally correct.</p>
<p>The benefits include:</p>
<ul><li>Less unnecessary object creation.</li><li>Better runtime performance.</li><li>Fewer accidental side effects from initializers.</li><li>Reduced memory allocations.</li><li>A simpler mental model for how <code>@State</code> works.</li></ul>
<p>Perhaps the biggest improvement is that the code is now easier to reason about. The object you initialize is the object SwiftUI keeps.</p>
<h2 id="should-you-change-your-existing-code">Should You Change Your Existing Code?</h2>
<p>The short answer is <strong>no</strong>.</p>
<p>If you're already using <code>@State</code> to own an <code>@Observable</code> object, there is nothing you need to rewrite. Your code continues to compile and behave exactly the same from the user's perspective.</p>
<p>What changes is what happens behind the scenes.</p>
<p>When you build your app with Xcode 27, SwiftUI no longer repeatedly evaluates the initialization expression for a <code>@State</code> property whenever the enclosing view is recreated. Instead, the initial value is created lazily when the state storage is first established.</p>
<p>You get the benefits automatically.</p>
<p>That means:</p>
<ul><li>Existing <code>@State</code> code continues to work.</li><li>Fewer unnecessary objects are created.</li><li>Expensive initializers run only when they are actually needed.</li><li>Your app performs less unnecessary work.</li><li>Your code more closely matches your expectations.</li></ul>
<p>As developers, we often get excited about new APIs, new view modifiers, and entirely new frameworks. Sometimes, however, the most valuable improvements are the ones that make existing APIs behave more intuitively.</p>
<p>This is one of those improvements.</p>
<p>You won't need to change a single line of code to benefit from it, but understanding what changed gives you a much better mental model of how <code>@State</code> works in modern SwiftUI.</p>]]></content:encoded>
  </item>
  <item>
    <title>Picker Label Alignment</title>
    <link>https://www.createchsol.com/blog/2026-07-29-picker-label-alignment.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-07-29-picker-label-alignment.html</guid>
    <pubDate>Wed, 29 Jul 2026 07:00:00 +0000</pubDate>
    <description>Picker Label Alignment</description>
                    <category>SwiftUI</category>
                <category>Technique</category>
    <content:encoded><![CDATA[<h1 id="picker-label-alignment">Picker Label Alignment</h1>
<p>One issue I have with some SwiftUI picker-style controls, such as <code>ColorPicker</code>, <code>DatePicker</code>, and <code>Toggle</code>, is that they are basically label/content views. The label is aligned to the leading edge and the control itself is aligned to the trailing edge, often leaving more space between them than I want.</p>
<p>For example:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span></code></pre>
<p>By default, SwiftUI renders them like this:</p>
<p><img src="blog/2026-07-29-picker-label-alignment_assets/image-20260619141347998.png" alt="image-20260619141347998"></p>
<p>But I might want to tighten up the space between the label and the control, and also specify the alignment. For example, here are the same three controls with the first using trailing alignment, the second using center alignment, and the third using leading alignment.</p>
<p><img src="blog/2026-07-29-picker-label-alignment_assets/image-20260619141152804.png" alt="image-20260619141152804"></p>
<h3 id="using-hstacks-and-spacers">Using HStacks and Spacers</h3>
<p>In my experience, most people would solve this by hiding the existing label with <code>.labelsHidden()</code>, embedding each picker in an <code>HStack</code>, adding a replacement <code>Text</code> view for the label, and then using <code>Spacer</code> views to get the desired alignment.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">        <span class="code-type">Spacer</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">    <span class="code-punctuation">}</span></span><span class="code-line is-highlighted">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">    <span class="code-punctuation">}</span></span><span class="code-line is-highlighted">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line is-highlighted">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-type">Spacer</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This works, but the main issue for me is that I am duplicating the label string.</p>
<p>The tendency might be to use an empty string for the picker label:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">""</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span></code></pre>
<p>However, if you provide an empty string, VoiceOver has no useful label unless you supply one another way.</p>
<h3 id="a-better-solution">A better solution</h3>
<p>A better solution is to remove the spacers altogether and use a frame with a <code>maxWidth</code> of <code>.infinity</code> and an alignment for the edge you want.</p>
<p>Since the default alignment is center, there is no need to add a frame to the <code>DatePicker</code>.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line is-highlighted">    <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.trailing</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-type">HStack</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.labelsHidden</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line is-highlighted">    <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.leading</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This is better, but it is still a lot of code and it still does not solve the issue of duplicating the label.</p>
<p>Instead, you can remove the <code>HStack</code> views altogether, along with the corresponding <code>Text</code> views, and apply the frame directly to the picker-style controls.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.trailing</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.leading</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>But now we are back to  the same issue we had before, where the picker takes up the full width of the enclosing view.</p>
<p><img src="blog/2026-07-29-picker-label-alignment_assets/image-20260619141347998.png" alt="image-20260619141347998"></p>
<p>There is a simple solution and that is to apply a <code>fixedSize()</code> modifier to the picker before the frame.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.fixedSize</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.trailing</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span>÷</span><span class="code-line is-highlighted">        <span class="code-property">.fixedSize</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.fixedSize</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> <span class="code-property">.leading</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-07-29-picker-label-alignment_assets/image-20260619141152804.png" alt="image-20260619141152804"></p>
<p>Now the controls only take up the space they need, while the frame controls the overall alignment.</p>
<h3 id="create-a-viewmodifier">Create A ViewModifier</h3>
<p>If you use this technique a lot, you would be wise to create a <code>ViewModifier</code>and a corresponding <code>View extension</code></p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">EdgeAligned</span><span class="code-punctuation">:</span> <span class="code-type">ViewModifier</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> alignment<span class="code-punctuation">:</span> <span class="code-type">Alignment</span></span><span class="code-line">    <span class="code-keyword">func</span> body<span class="code-punctuation">(</span>content<span class="code-punctuation">:</span> <span class="code-type">Content</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        content</span><span class="code-line">            <span class="code-property">.fixedSize</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.frame</span><span class="code-punctuation">(</span>maxWidth<span class="code-punctuation">:</span> <span class="code-property">.infinity</span><span class="code-punctuation">,</span> alignment<span class="code-punctuation">:</span> alignment<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">extension</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">func</span> edgeAligned<span class="code-punctuation">(</span>alignment<span class="code-punctuation">:</span> <span class="code-type">Alignment</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.modifier</span><span class="code-punctuation">(</span><span class="code-type">EdgeAligned</span><span class="code-punctuation">(</span>alignment<span class="code-punctuation">:</span> alignment<span class="code-punctuation">)</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>With the extension, we can apply the modifier directly to any picker-style control and just specify the alignment.</p>
<pre class="code-block has-line-focus" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ColorPicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Color"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $color<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.edgeAligned</span><span class="code-punctuation">(</span>alignment<span class="code-punctuation">:</span> <span class="code-property">.trailing</span> <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">DatePicker</span><span class="code-punctuation">(</span><span class="code-string">"Select Date"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $date<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.edgeAligned</span><span class="code-punctuation">(</span>alignment<span class="code-punctuation">:</span> <span class="code-property">.center</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-type">Toggle</span><span class="code-punctuation">(</span><span class="code-string">"Power"</span><span class="code-punctuation">,</span> isOn<span class="code-punctuation">:</span> $isOn<span class="code-punctuation">)</span></span><span class="code-line is-highlighted">        <span class="code-property">.edgeAligned</span><span class="code-punctuation">(</span>alignment<span class="code-punctuation">:</span> <span class="code-property">.leading</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>]]></content:encoded>
  </item>
  <item>
    <title>Enums as Namespaces</title>
    <link>https://www.createchsol.com/blog/2026-07-15-enums-as-namespaces.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-07-15-enums-as-namespaces.html</guid>
    <pubDate>Wed, 15 Jul 2026 07:00:00 +0000</pubDate>
    <description>Using Enums as Namespaces in Swift</description>
                    <category>Enum</category>
                <category>Swift</category>
                <category>SwiftUI</category>
    <content:encoded><![CDATA[<h1 id="using-enums-as-namespaces-in-swift">Using Enums as Namespaces in Swift</h1>
<h2 id="introduction">Introduction</h2>
<p>Swift enums are one of the most powerful types in the language. Most developers use them to model a fixed set of related values, such as navigation destinations, application state, network results, or user roles.</p>
<p>However, enums have another extremely useful purpose that often gets overlooked: acting as a <strong>namespace</strong>.</p>
<p>In many projects, you'll eventually find yourself collecting related constants, configuration values, helper methods, feature flags, API endpoints, validation rules, and other code that doesn't naturally belong to a specific type. The question then becomes: where should that code live?</p>
<p>Some developers reach for global constants. Others create utility structs. Still others create singleton objects. While all of these approaches work, there is often a cleaner solution.</p>
<p>In this blog post, we'll look at how enums can be used as namespaces, why they're often preferable to utility structs, how they differ from singletons, and when they are and are not appropriate.</p>
<hr>
<h2 id="the-problem">The Problem</h2>
<p>As Swift projects grow, it becomes increasingly common to accumulate values that need a home.</p>
<p>Consider this example of three properties that are created outside of any struct, class or enum:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> cornerRadius<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">12</span></span><span class="code-line"><span class="code-keyword">let</span> padding<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">20</span></span><span class="code-line"><span class="code-keyword">let</span> animationDuration<span class="code-punctuation">:</span> <span class="code-type">Double</span> <span class="code-punctuation">=</span> <span class="code-number">0.3</span></span></code></pre>
<p>There is nothing technically wrong with this code, but these constants now live in the <strong>global namespace</strong>.</p>
<p>As your project grows, global values can become difficult to discover and maintain. They also increase the likelihood of naming conflicts.  It is the <em>"difficult to discover"</em> concept that I find most problematic, particularly if I have been away from the project for a while.</p>
<p>Even worse, future developers may have no idea where a value came from when they encounter code like this:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.padding</span><span class="code-punctuation">(</span>padding<span class="code-punctuation">)</span></span></code></pre>
<p>The context is missing.</p>
<hr>
<h2 id="a-better-solution">A Better Solution</h2>
<p>One way to solve this problem is to create a <strong>namespace</strong>.</p>
<p>A <strong>namespace</strong> is a way of grouping related constants, functions, and types together under a common name.</p>
<p>All you need to do is to create the enum and then define your values as <strong>static properties</strong> or <strong>methods/functions</strong>.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">UI</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-comment">// Static stored properties</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> cornerRadius<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">12</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> padding<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">20</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> animationDuration<span class="code-punctuation">:</span> <span class="code-type">Double</span> <span class="code-punctuation">=</span> <span class="code-number">0.3</span></span><span class="code-line"></span><span class="code-line">    <span class="code-comment">// Static computed properties</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">var</span> cardShadowRadius<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">{</span></span><span class="code-line">        cornerRadius <span class="code-punctuation">/</span> <span class="code-number">2</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-comment">// Static methods</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">func</span> opacity<span class="code-punctuation">(</span></span><span class="code-line">        isEnabled<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Double</span> <span class="code-punctuation">{</span></span><span class="code-line">        isEnabled <span class="code-punctuation">?</span> <span class="code-number">1.0</span> <span class="code-punctuation">:</span> <span class="code-number">0.5</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">func</span> cardColor<span class="code-punctuation">(</span></span><span class="code-line">        isSelected<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Color</span> <span class="code-punctuation">{</span></span><span class="code-line">        isSelected <span class="code-punctuation">?</span> <span class="code-property">.teal</span> <span class="code-punctuation">:</span> <span class="code-property">.yellow</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Now, you get the benefit of Xcode's code completion.  When you type the enum name followed by a period, You get a list of all the  enum's static properties and methods to choose from.  All of theses properties and methods for the enum are prefaced with the <strong>M</strong> icon which stands for <em>member</em>.</p>
<p><img src="blog/2026-07-15-enums-as-namespaces_assets/image-20260605115645096.png" alt="image-20260605115645096"></p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Hello"</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-type">UI</span><span class="code-property">.padding</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-property">.background</span><span class="code-punctuation">(</span></span><span class="code-line">    <span class="code-type">UI</span><span class="code-property">.cardColor</span><span class="code-punctuation">(</span>isSelected<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span><span class="code-punctuation">,</span></span><span class="code-line">    <span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-property">.rect</span><span class="code-punctuation">(</span>cornerRadius<span class="code-punctuation">:</span> <span class="code-type">UI</span><span class="code-property">.cornerRadius</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-property">.shadow</span><span class="code-punctuation">(</span>radius<span class="code-punctuation">:</span> <span class="code-type">UI</span><span class="code-property">.cardShadowRadius</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-property">.opacity</span><span class="code-punctuation">(</span><span class="code-type">UI</span><span class="code-property">.opacity</span><span class="code-punctuation">(</span>isEnabled<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span><span class="code-punctuation">)</span></span></code></pre>
<p>The code is now much more self-documenting.</p>
<p>When you see:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">UI</span><span class="code-property">.padding</span></span></code></pre>
<p>you immediately know where the value comes from and what it represents.</p>
<hr>
<h2 id="why-use-an-enum">Why Use an Enum?</h2>
<p>At this point you might be wondering why we chose an enum rather than a struct or class.</p>
<p>The answer is simple: intent.</p>
<p>An enum with no cases cannot be instantiated.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">UI</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> padding<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">20</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Attempting to create an instance results in a compiler error:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> ui <span class="code-punctuation">=</span> <span class="code-type">UI</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>This tells every developer reading the code:</p>
<blockquote><p>This type exists solely to organize related functionality.</p></blockquote>
<p>That is exactly what we want from a <strong>namespace</strong>.</p>
<hr>
<h2 id="why-not-use-a-struct">Why Not Use a Struct?</h2>
<p>Many developers use a struct instead.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">UI</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> padding<span class="code-punctuation">:</span> <span class="code-type">CGFloat</span> <span class="code-punctuation">=</span> <span class="code-number">20</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This works perfectly well.</p>
<p>The problem is that the struct can still be instantiated.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> io <span class="code-punctuation">=</span> <span class="code-type">UI</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>The instance serves no purpose because every member is static.</p>
<p>By using an enum, we prevent accidental instantiation entirely and make our intentions clearer.</p>
<hr>
<h2 id="what-else-can-go-in-an-enum-namespace">What else can go in an enum namespace?</h2>
<p>We have already seen static stored and computed properties along with static methods, but what else can go in an enum namespace?  The answer is quite a bit, provided it is static.</p>
<h3 id="nested-enum-namespaces">Nested Enum namespaces</h3>
<p>A nested enum is perfect when you want to create additional namespaces.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">API</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> baseURL <span class="code-punctuation">=</span></span><span class="code-line">        <span class="code-string">"https://api.example.com"</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">enum</span> <span class="code-type">Endpoints</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">static</span> <span class="code-keyword">let</span> users <span class="code-punctuation">=</span> <span class="code-string">"/users"</span></span><span class="code-line">        <span class="code-keyword">static</span> <span class="code-keyword">let</span> videos <span class="code-punctuation">=</span> <span class="code-string">"/videos"</span></span><span class="code-line">        <span class="code-keyword">static</span> <span class="code-keyword">let</span> playlists <span class="code-punctuation">=</span> <span class="code-string">"/playlists"</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">let</span> url <span class="code-punctuation">=</span> <span class="code-type">API</span><span class="code-property">.baseURL</span> <span class="code-punctuation">+</span> <span class="code-type">API</span><span class="code-property">.Endpoints</span><span class="code-property">.videos</span></span></code></pre>
<hr>
<h3 id="nested-enum-with-cases">Nested Enum with Cases</h3>
<p>You can combine a namespace enum with another enum that actually has cases.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">Theme</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">enum</span> <span class="code-type">Style</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> light</span><span class="code-line">        <span class="code-keyword">case</span> dark</span><span class="code-line">        <span class="code-keyword">case</span> system</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">let</span> currentStyle<span class="code-punctuation">:</span> <span class="code-type">Theme</span><span class="code-property">.Style</span> <span class="code-punctuation">=</span> <span class="code-property">.system</span></span></code></pre>
<hr>
<h3 id="nested-struct">Nested Struct</h3>
<p>A nested struct is useful when the namespace owns a related model.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">AppInfo</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">struct</span> <span class="code-type">Version</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">let</span> major<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">        <span class="code-keyword">let</span> minor<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">        <span class="code-keyword">let</span> patch<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">let</span> version <span class="code-punctuation">=</span> <span class="code-type">AppInfo</span><span class="code-property">.Version</span><span class="code-punctuation">(</span></span><span class="code-line">    major<span class="code-punctuation">:</span> <span class="code-number">1</span><span class="code-punctuation">,</span></span><span class="code-line">    minor<span class="code-punctuation">:</span> <span class="code-number">2</span><span class="code-punctuation">,</span></span><span class="code-line">    patch<span class="code-punctuation">:</span> <span class="code-number">0</span></span><span class="code-line"><span class="code-punctuation">)</span></span></code></pre>
<h3 id="nested-class">Nested Class</h3>
<p>A nested class is useful when the namespace owns a related service or object that needs to maintain state over time.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">Utilities</span> <span class="code-punctuation">{</span></span><span class="code-line">    final <span class="code-keyword">class</span> <span class="code-type">Counter</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">private</span><span class="code-punctuation">(</span>set<span class="code-punctuation">)</span> <span class="code-keyword">var</span> count <span class="code-punctuation">=</span> <span class="code-number">0</span></span><span class="code-line">        <span class="code-keyword">func</span> increment<span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">            count <span class="code-punctuation">+</span><span class="code-punctuation">=</span> <span class="code-number">1</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">let</span> counter <span class="code-punctuation">=</span> <span class="code-type">Utilities</span><span class="code-property">.Counter</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">counter<span class="code-property">.increment</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">print<span class="code-punctuation">(</span>counter<span class="code-property">.count</span><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h3 id="nested-protocols">Nested Protocols</h3>
<p>Protocols are a great candidate because they often describe a group of related behaviors.</p>
<p>In this example, it is obvious that the protocol belongs to your networking layer.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">Networking</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">protocol</span> <span class="code-type">Requestable</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">var</span> endpoint<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">{</span> get <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">UserRequest</span><span class="code-punctuation">:</span> <span class="code-type">Networking</span><span class="code-property">.Requestable</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> endpoint <span class="code-punctuation">=</span> <span class="code-string">"/users"</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h3 id="type-alias">Type Alias</h3>
<p>Type aliases can become difficult to locate when they are global. It prevents global type aliases from cluttering a project</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">AppTypes</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">typealias</span> <span class="code-type">Completion</span> <span class="code-punctuation">=</span></span><span class="code-line">        <span class="code-punctuation">(</span><span class="code-type">Result</span>&lt;<span class="code-type">Void</span><span class="code-punctuation">,</span> <span class="code-type">Error</span>&gt;<span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Void</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-keyword">func</span> save<span class="code-punctuation">(</span></span><span class="code-line">    completion<span class="code-punctuation">:</span> <span class="code-type">AppTypes</span><span class="code-property">.Completion</span></span><span class="code-line"><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-comment">// ...</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h2 id="enum-namespace-vs-singleton">Enum Namespace vs Singleton</h2>
<p>This is where many developers become confused.</p>
<p>At first glance these patterns can look similar.</p>
<h3 id="singleton">Singleton</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line">final <span class="code-keyword">class</span> <span class="code-type">AppInfo</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> shared <span class="code-punctuation">=</span> <span class="code-type">AppInfo</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-keyword">private</span> <span class="code-keyword">init</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span><span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-keyword">var</span> appName <span class="code-punctuation">=</span> <span class="code-string">"My App"</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-type">AppInfo</span><span class="code-property">.shared</span><span class="code-property">.appName</span></span></code></pre>
<h3 id="enum-namespace">Enum Namespace</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">AppInfo</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">let</span> appName <span class="code-punctuation">=</span> <span class="code-string">"My App"</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-comment">// Example Usage:</span></span><span class="code-line"><span class="code-type">AppInfo</span><span class="code-property">.appName</span></span></code></pre>
<p>Although the call sites appear similar, the designs are fundamentally different. The singleton represents a single shared object that can maintain state throughout the life of the application. The enum namespace simply groups related values and functionality together and can never be instantiated.</p>
<p>In the case of the singleton, this is possible.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">AppInfo</span><span class="code-property">.shared</span><span class="code-property">.appName</span> <span class="code-punctuation">=</span> <span class="code-string">"My New App"</span></span></code></pre>
<p>Whereas the enum namespace would produce an error if we tried to do this</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">AppInfo</span><span class="code-property">.appName</span> <span class="code-punctuation">=</span> <span class="code-string">"My New App"</span></span></code></pre>
<hr>
<h3 id="when-to-use-a-namespace">When to Use a Namespace</h3>
<p>Namespaces are ideal when:</p>
<ul><li>Everything is static</li><li>No state is stored</li><li>No instance should ever exist</li><li>The goal is organization</li></ul>
<p>Examples include things such as layout constants, API endpoints, validation rules etc</p>
<hr>
<h3 id="when-to-use-a-singleton">When to Use a Singleton</h3>
<p>Singletons are appropriate when:</p>
<ul><li>Shared state exists</li><li>Resources are managed</li><li>One instance must exist</li><li>The object has a lifecycle</li></ul>
<p>Examples include network managers, cache managers database coordinators etc.</p>
<p>These are fundamentally different from namespaces.</p>
<hr>
<h2 id="benefits-of-enum-namespaces">Benefits of Enum Namespaces</h2>
<p>As we have discovered, enums:</p>
<ul><li>Prevent instantiation</li><li>Improve discoverability</li><li>Reduce global namespace pollution</li><li>Make code more self-documenting</li></ul>
<hr>
<h2 id="drawbacks-of-enum-namespaces">Drawbacks of Enum Namespaces</h2>
<p>Like any pattern, enum namespaces are not perfect.</p>
<ul><li>They cannot store state</li><li>They can become dumping grounds so avoid giant namespaces and create focused ones.</li></ul>
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>Using enums as namespaces is one of those simple Swift techniques that can significantly improve code organization.</p>
<p>By defining an enum with no cases and adding static members, you create a logical grouping of related functionality while preventing accidental instantiation. The pattern communicates intent clearly, reduces namespace pollution, and keeps code easier to discover and maintain.</p>
<p>Just remember that namespaces are not a replacement for extensions or singletons.</p>
<p>If functionality naturally belongs to an existing type, prefer an extension. If you need shared state or resource management, consider a singleton, class, actor, or protocol-based service.</p>
<p>But when all you need is a place to organize related constants, helper methods, and configuration values, an enum namespace is often the cleanest solution available in Swift.</p>]]></content:encoded>
  </item>
  <item>
    <title>Enum Sheets</title>
    <link>https://www.createchsol.com/blog/2026-07-01-enum-sheets.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-07-01-enum-sheets.html</guid>
    <pubDate>Wed, 01 Jul 2026 07:00:00 +0000</pubDate>
    <description>Using Enums That Conform to View for Cleaner Sheet Presentations in SwiftUI</description>
                    <category>Enum</category>
                <category>Swift</category>
                <category>SwiftUI</category>
    <content:encoded><![CDATA[<h1 id="using-enums-that-conform-to-view-for-cleaner-sheet-presentations-in-swiftui">Using Enums That Conform to View for Cleaner Sheet Presentations in SwiftUI</h1>
<p>SwiftUI makes presenting sheets incredibly easy, but as an application grows, managing multiple sheets can become messy. It's common to see several Boolean properties dedicated to controlling different presentations:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingSettings <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingProfile <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingHelp <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span></code></pre>
<p>This approach works, but it doesn't scale well. Every new sheet requires another state property, additional presentation logic, and more maintenance.</p>
<p>In this blog post, I'll show you a technique I use to simplify sheet presentations by creating an enum that conforms to both <code>View</code> and <code>Identifiable</code>. The result is cleaner code, fewer state properties, and a more scalable architecture.</p>
<h2 id="the-traditional-approach">The Traditional Approach</h2>
<p>Consider a view with three buttons that present three different sheets.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">TradionionalView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingSettings <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingProfile <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingHelp <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Settings"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    showingSettings <span class="code-punctuation">=</span> <span class="code-keyword">true</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Profile"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    showingProfile <span class="code-punctuation">=</span> <span class="code-keyword">true</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Help"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    showingHelp <span class="code-punctuation">=</span> <span class="code-keyword">true</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.bordered</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Enum Sheets"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.sheet</span><span class="code-punctuation">(</span>isPresented<span class="code-punctuation">:</span> $showingSettings<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.sheet</span><span class="code-punctuation">(</span>isPresented<span class="code-punctuation">:</span> $showingProfile<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.sheet</span><span class="code-punctuation">(</span>isPresented<span class="code-punctuation">:</span> $showingHelp<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">HelpView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-07-01-enum-sheets_assets/iPhone 17 Pro - 2026-06-02 at 11.09.08.gif" alt="iPhone 17 Pro - 2026-06-02 at 11.09.08"></p>
<p>Although functional, this solution has several drawbacks:</p>
<ul><li>Multiple Boolean state properties</li><li>Multiple sheet modifiers</li><li>More code to maintain</li><li>Greater chance of presentation conflicts</li></ul>
<h2 id="a-better-solution">A Better Solution</h2>
<p>Instead of tracking multiple Boolean values, we can track a single enum value representing the sheet that should be presented.</p>
<p>First, create an enum that conforms to <code>Identifiable</code> and <code>View</code>.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">:</span> <span class="code-type">Identifiable</span><span class="code-punctuation">,</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> settings</span><span class="code-line">    <span class="code-keyword">case</span> profile</span><span class="code-line">    <span class="code-keyword">case</span> help</span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">Self</span> <span class="code-punctuation">{</span> <span class="code-keyword">self</span> <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.settings</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.profile</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">HelpView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This enum serves two purposes:</p>
<ol><li>It identifies which sheet should be presented.</li><li>It knows how to build the view associated with each case.</li></ol>
<h2 id="presenting-the-sheet">Presenting the Sheet</h2>
<p>Now we only need a single optional state property.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">?</span></span></code></pre>
<p>The main view becomes much simpler.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">EnumSheetView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">?</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Settings"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.settings</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Profile"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.profile</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">                </span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Help"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.help</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.bordered</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Enum Sheets"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> sheet <span class="code-keyword">in</span></span><span class="code-line">               sheet</span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>That's it.</p>
<p>The sheet modifier receives the enum instance and simply presents it because the enum itself conforms to <code>View</code>.</p>
<h2 id="why-this-works">Why This Works</h2>
<p>The <code>.sheet(item:)</code> modifier requires an optional value that conforms to <code>Identifiable</code>.</p>
<p>By making the enum conform to <code>Identifiable</code>, SwiftUI can determine when a new sheet should be presented.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">Self</span> <span class="code-punctuation">{</span> <span class="code-keyword">self</span> <span class="code-punctuation">}</span></span></code></pre>
<p>Because each enum case is unique, using <code>self</code> as the identifier works perfectly.</p>
<p>At the same time, conforming to <code>View</code> allows each case to generate its own destination view.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.settings</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.profile</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-type">HelpView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Because the enum conforms to <code>View</code>, there is no need to add <code>@ViewBuilder</code> to the <code>body</code> property here. The switch branches each return a view, and SwiftUI can infer the result.</p>
<p>The enum becomes both the navigation state and the destination view.</p>
<h2 id="supporting-associated-values">Supporting Associated Values</h2>
<p>This pattern becomes even more powerful when working with associated values.</p>
<p>Consider this, where I have a new enum that is similar to ActiveSheet, except that the help case now has an associated value that is a String.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">ActiveSheet2</span><span class="code-punctuation">:</span> <span class="code-type">Identifiable</span><span class="code-punctuation">,</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> settings</span><span class="code-line">    <span class="code-keyword">case</span> profile</span><span class="code-line">    <span class="code-keyword">case</span> help<span class="code-punctuation">(</span><span class="code-type">String</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-string">"help"</span></span><span class="code-line">        default<span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-type">String</span><span class="code-punctuation">(</span>describing<span class="code-punctuation">:</span> <span class="code-keyword">self</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.settings</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.profile</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">(</span><span class="code-keyword">let</span> helpString<span class="code-punctuation">)</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">HelpView</span><span class="code-punctuation">(</span>helpString<span class="code-punctuation">:</span> helpString<span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<blockquote><p>Note.  Because the enum has at least one case with an associated value, we needed to change the id property to String and provide a specific value for the help case.  For the other two cases that do not have associated values, the id property can be String(describing:</p></blockquote>
<p>For the enum body, we can extract the associated value from the case and pass that in to the HelpView that can also accept a String parameter</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">(</span><span class="code-keyword">let</span> helpString<span class="code-punctuation">)</span><span class="code-punctuation">:</span></span><span class="code-line">    <span class="code-type">HelpView</span><span class="code-punctuation">(</span>helpString<span class="code-punctuation">:</span> helpString<span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Presenting a specific user becomes straightforward.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Help"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.help</span><span class="code-punctuation">(</span><span class="code-string">"This is the associated help string for this second view"</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The enum now carries both the destination type and any data required by the destination.</p>
<h2 id="the-final-refinement">The Final Refinement</h2>
<p>Once the enum conforms to <code>View</code>, the sheet presentation code can be simplified even further.</p>
<p>Many developers write:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> sheet <span class="code-keyword">in</span></span><span class="code-line">    sheet</span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>While perfectly valid, the closure is simply returning the value it receives.</p>
<p>Since <code>ActiveSheet</code> already conforms to <code>View</code>, we can shorten this to:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>This works because the closure parameter is an instance of <code>ActiveSheet</code>, and <code>ActiveSheet</code> is itself a view.</p>
<p>At this point, the enum serves three distinct roles:</p>
<ul><li>Navigation state</li><li>Sheet identifier</li><li>Sheet content</li></ul>
<p>The entire presentation logic is reduced to a single line of code.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>This is one of the most compelling reasons to adopt this pattern. The presentation code becomes almost trivial while remaining fully type-safe.</p>
<h2 id="the-evolution-of-the-pattern">The Evolution of the Pattern</h2>
<p>It's interesting to see how this approach evolves as your SwiftUI knowledge grows.</p>
<h3 id="step-1-multiple-boolean-properties">Step 1: Multiple Boolean Properties</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingSettings <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingProfile <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> showingHelp <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span></code></pre>
<h3 id="step-2-a-single-enum-state">Step 2: A Single Enum State</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">?</span></span></code></pre>
<h3 id="step-3-the-enum-becomes-the-destination">Step 3: The Enum Becomes the Destination</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">:</span> <span class="code-type">Identifiable</span><span class="code-punctuation">,</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> settings</span><span class="code-line">    <span class="code-keyword">case</span> profile</span><span class="code-line">    <span class="code-keyword">case</span> help</span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">Self</span> <span class="code-punctuation">{</span> <span class="code-keyword">self</span> <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.settings</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.profile</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">HelpView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<h3 id="step-4-presentation-logic-becomes-one-line">Step 4: Presentation Logic Becomes One Line</h3>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>At this stage, the enum completely encapsulates the sheet presentation logic. All the view needs to do is assign the appropriate case.</p>
<h2 id="advantages-of-this-pattern">Advantages of This Pattern</h2>
<h3 id="single-source-of-truth">Single Source of Truth</h3>
<p>Only one state property controls all sheet presentations.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">?</span></span></code></pre>
<h3 id="easy-to-extend">Easy to Extend</h3>
<p>Adding another sheet only requires a new enum case.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">case</span> about</span></code></pre>
<p>And one additional switch branch.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">case</span> <span class="code-property">.about</span><span class="code-punctuation">:</span></span><span class="code-line">    <span class="code-type">AboutView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<h3 id="better-organization">Better Organization</h3>
<p>All sheet destinations live in one place instead of being scattered throughout the view hierarchy.</p>
<h3 id="type-safety">Type Safety</h3>
<p>The compiler ensures every case is handled in the switch statement.</p>
<h3 id="less-boilerplate">Less Boilerplate</h3>
<p>No more collection of Boolean flags cluttering your view.</p>
<h2 id="when-should-you-use-this">When Should You Use This?</h2>
<p>This pattern works especially well when:</p>
<ul><li>A view can present multiple sheets</li><li>Sheet destinations are known in advance</li><li>You want centralized presentation logic</li><li>You want to reduce state management complexity</li></ul>
<p>For simple views with a single sheet, the traditional Boolean approach is perfectly acceptable. However, once you have three or more destinations, this enum-based approach often becomes easier to maintain.</p>
<h2 id="complete-example">Complete Example</h2>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">ActiveSheet2</span><span class="code-punctuation">:</span> <span class="code-type">Identifiable</span><span class="code-punctuation">,</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> settings</span><span class="code-line">    <span class="code-keyword">case</span> profile</span><span class="code-line">    <span class="code-keyword">case</span> help<span class="code-punctuation">(</span><span class="code-type">String</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-string">"help"</span></span><span class="code-line">        default<span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-type">String</span><span class="code-punctuation">(</span>describing<span class="code-punctuation">:</span> <span class="code-keyword">self</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.settings</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">SettingsView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.profile</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">ProfileView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.help</span><span class="code-punctuation">(</span><span class="code-keyword">let</span> helpString<span class="code-punctuation">)</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-type">HelpView</span><span class="code-punctuation">(</span>helpString<span class="code-punctuation">:</span> helpString<span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">EnumAssociatedValueView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet2</span><span class="code-punctuation">?</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Settings"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.settings</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Profile"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.profile</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">                </span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Help"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.help</span><span class="code-punctuation">(</span><span class="code-string">"This is the associated help string for this second view"</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.bordered</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Enum Sheets"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> sheet <span class="code-keyword">in</span></span><span class="code-line">                sheet</span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-07-01-enum-sheets_assets/iPhone 17 Pro - 2026-06-02 at 11.20.08.gif" alt="iPhone 17 Pro - 2026-06-02 at 11.20.08"></p>
<h2 id="the-same-pattern-works-with-fullscreencover">The Same Pattern Works with fullScreenCover</h2>
<p>One of the benefits of having your enum conform directly to <code>View</code> is that the same approach works with <code>fullScreenCover</code>.</p>
<p>Instead of:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>You can simply write:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.fullScreenCover</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>The enum doesn't care whether it is being presented as a sheet or a full-screen cover. It is still responsible for generating the destination view.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">EnumSheetView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> activeSheet<span class="code-punctuation">:</span> <span class="code-type">ActiveSheet</span><span class="code-punctuation">?</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Settings"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.settings</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Profile"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.profile</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">                </span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Help"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    activeSheet <span class="code-punctuation">=</span> <span class="code-property">.help</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.buttonStyle</span><span class="code-punctuation">(</span><span class="code-property">.bordered</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Enum Sheets"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.fullScreenCover</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This flexibility can be particularly useful when requirements change. You may initially present content as a sheet and later decide it should be full-screen. With this pattern, the only change required is swapping the presentation modifier.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.sheet</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>becomes</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.fullScreenCover</span><span class="code-punctuation">(</span>item<span class="code-punctuation">:</span> $activeSheet<span class="code-punctuation">)</span> <span class="code-punctuation">{</span> $<span class="code-number">0</span> <span class="code-punctuation">}</span></span></code></pre>
<p>Everything else remains exactly the same.</p>
<p>The enum continues to provide:</p>
<ul><li>Navigation state</li><li>Unique identification</li><li>Destination content</li></ul>
<p>This further demonstrates how powerful it can be to allow the enum to own the presentation logic.</p>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Using enums that conform to <code>View</code> is a simple but powerful SwiftUI technique. It allows you to combine navigation state and destination views into a single type, resulting in cleaner, more maintainable code.</p>
<p>The next time you find yourself adding a fourth or fifth Boolean property just to present another sheet, consider replacing them with a single enum. Your future self will thank you.</p>
<h2 id="github-repo">GitHub Repo:</h2>
<p>You can find a the completed source code on GitHub.</p>
<p><a href="https://github.com/StewartLynch/EnumSheets" target="_blank" rel="noreferrer">https://github.com/StewartLynch/EnumSheets</a></p>]]></content:encoded>
  </item>
  <item>
    <title>Swift Initializers Part 2: Classes</title>
    <link>https://www.createchsol.com/blog/2026-06-17-swift-initializers-part-2-classes.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-06-17-swift-initializers-part-2-classes.html</guid>
    <pubDate>Wed, 17 Jun 2026 07:00:00 +0000</pubDate>
    <description>Swift Initializers: Understanding Initializers in Classes</description>
                    <category>Foundation</category>
                <category>Swift</category>
    <content:encoded><![CDATA[<h2 id="swift-initializers-understanding-initializers-in-classes">Swift Initializers: Understanding Initializers in Classes</h2>
<h2 id="introduction">Introduction</h2>
<p>In the previous article <a href="https://www.createchsol.com/blog/2026-06-03-swift-initializers-part-1-structs.html" target="_blank" rel="noreferrer">Swift Initializers: Understanding Initializers in Structs</a>, we explored initializers in structs. </p>
<p>Structs are relatively straightforward because they do not support inheritance.</p>
<p>Classes introduce additional complexity because they participate in inheritance hierarchies. Swift must ensure that both a class and all of its superclasses are fully initialized before an object can be used.</p>
<p>The other important and significant difference between structs and classes is that classes do not provide a memberwise initializer.  All classes must include an initializer if any stored property does not have a default value.</p>
<p>In this article, you'll learn how class initializers work, the difference between designated and convenience initializers, initializer inheritance, required initializers, failable initializers, and Swift's two-phase initialization process.</p>
<hr>
<h2 id="why-class-initializers-are-different">Why Class Initializers Are Different</h2>
<p>If you create a class with properties that have default values and you do not provide an initializer, you cannot create a new instance of that class and specify different values for the properties at the time of creation.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">ClassUser</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">=</span> <span class="code-string">"Stewart"</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> user1 <span class="code-punctuation">=</span> <span class="code-type">ClassUser</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>If there were a struct, however, you still get a <strong>memberwise initializer</strong> by default and have all of the different options for initializers.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">StructUser</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">=</span> <span class="code-string">"Stewart"</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> user2 <span class="code-punctuation">=</span> <span class="code-type">StructUser</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-keyword">let</span> user3 <span class="code-punctuation">=</span> <span class="code-type">StructUser</span><span class="code-punctuation">(</span>isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-keyword">let</span> user4 <span class="code-punctuation">=</span> <span class="code-type">StructUser</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Emily"</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-keyword">let</span> user5 <span class="code-punctuation">=</span> <span class="code-type">StructUser</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Aidan"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span></code></pre>
<h2 id="classes-with-no-default-property-values">Classes with no default property values</h2>
<p>All stored properties in the class must be initialized so if there are no default values, these must be addressed in the <strong>initializer</strong>. </p>
<p>An <em>initializer</em> is a special type of member of a class or struct whose job is to create and prepare a new instance for use. </p>
<p> The <strong>init</strong> <em>keyword</em> is identifies the initializer and the initializer <em>parameters</em> are the values and types that callers can provide during initialization.  So if your properties do not have default values assigned, the initializer must have a parameter that is used in the initializer body assign the provided values to the corresponding object properties.</p>
<p>If the parameter names are the same as the property names, then in the initializer body, <code>self.</code>is used in front of the property name to refer to the property and avoid ambiguity.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h2 id="constant-properties-and-initialization">Constant Properties and Initialization</h2>
<p>The rules for constant properties in classes are the same as those for constant properties in structs.  They must receive values before initialization completes and they cannot be changed afterwards</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">ClassUser</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">ClassUser</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span></span><span class="code-line">user<span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> <span class="code-keyword">true</span> <span class="code-comment">// Error</span></span></code></pre>
<hr>
<h2 id="initializer-parameter-labels">Initializer Parameter Labels</h2>
<p>You can add additional external parameter labels to that are different from the property names. The purpose of <strong>external</strong> initializer parameter labels is to make code more readable and self-documenting at the point where an instance is created.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">ClassUser</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> nom<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> estPremiume<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name nom<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium estPremiume<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.nom</span> <span class="code-punctuation">=</span> nom</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.estPremiume</span> <span class="code-punctuation">=</span> estPremiume</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">ClassUser</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h2 id="default-parameter-values">Default Parameter Values</h2>
<p>You can provide <strong>default parameter values</strong> for one or more of your properties in the initializer parameters to make an initializer easier to use by providing sensible defaults for parameters that callers don’t always need to specify.</p>
<p>Each default parameter value will add an additional initializer option upon creation.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">)</span>  <span class="code-comment">// isPremium is false</span></span><span class="code-line"><span class="code-keyword">let</span> user2 <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h2 id="designated-initializers">Designated Initializers</h2>
<p>A <strong>designated initializer</strong> is the primary initializer of a class. Its responsibility is to ensure that all of the class’s stored properties receive values and that initialization continues up the inheritance chain by calling a designated initializer in the superclass as you will see.  It is responsible for fully initializing the class.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h2 id="convenience-initializers">Convenience Initializers</h2>
<p>A <strong>convenience initializer</strong> is an initializer that provides an easier or more specialized way to create an instance, while delegating the actual work of initialization to a designated initializer.</p>
<p>If a designated initializer is the <strong>master initializer</strong>, a convenience initializer is a <strong>shortcut</strong>.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Video</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.duration</span> <span class="code-punctuation">=</span> duration</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    convenience <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> title<span class="code-punctuation">,</span></span><span class="code-line">            duration<span class="code-punctuation">:</span> <span class="code-number">0</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">)</span> <span class="code-comment">// Duration = 0</span></span><span class="code-line"><span class="code-keyword">let</span> video2 <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-number">40</span><span class="code-punctuation">)</span></span></code></pre>
<p>Now you may be wondering how this differs from the example in <strong>Default Parameter Values</strong> above and this example there is really no difference.  Why not just write it like this? </p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Video</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span> <span class="code-punctuation">=</span> <span class="code-number">0</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.duration</span> <span class="code-punctuation">=</span> duration</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">)</span> <span class="code-comment">// Duration = 0</span></span><span class="code-line"><span class="code-keyword">let</span> video2 <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-number">40</span><span class="code-punctuation">)</span></span></code></pre>
<p>However, you can take advantage of convenience initializers to communicate intent.  For example, in the convenience initializer for this class, we can change the parameter label to clarify what this initializer is intended for.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Video</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.duration</span> <span class="code-punctuation">=</span> duration</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line">    convenience <span class="code-keyword">init</span><span class="code-punctuation">(</span>draftTitle<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> draftTitle<span class="code-punctuation">,</span></span><span class="code-line">            duration<span class="code-punctuation">:</span> <span class="code-number">0</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>draftTitle<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">)</span> <span class="code-comment">// Duration = 0</span></span><span class="code-line"><span class="code-keyword">let</span> video2 <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-string">"Understanding Initializers"</span><span class="code-punctuation">,</span> duration<span class="code-punctuation">:</span> <span class="code-number">40</span><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h2 id="designated-vs-convenience-initializers">Designated vs Convenience Initializers</h2>
<p>Designated initializers fully initialize the class.</p>
<p>Convenience initializers must call another initializer in the same class using <code>self.init(...)</code>.</p>
<hr>
<h2 id="class-inheritance">Class Inheritance</h2>
<p>In the article on structs, initialization was relatively straightforward because structs do not support inheritance.</p>
<p>Classes are different.</p>
<p>A class can inherit properties and behavior from another class.</p>
<p>Consider this example:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">  </span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Now let’s create a subclass:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>An <code>Employee</code> contains everything that belongs to a <code>Person</code> plus its own additional information.</p>
<p>Person</p>
<p>​     └─ name</p>
<p>Employee             </p>
<p> ├─ name</p>
<p> └─ employeeID</p>
<p>When an <code>Employee</code> is created, Swift must ensure that:</p>
<ol><li><code>employeeID</code> receives a value.</li><li><code>name</code> receives a value.</li><li>Both the <code>Employee</code> portion and the <code>Person</code> portion are properly initialized.</li></ol>
<p>This is where initialization becomes more complicated than it was for structs.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>What value should <code>name</code> have?</p>
<p>The superclass has not been initialized.</p>
<p>Swift prevents situations like this by enforcing a set of initialization rules.</p>
<h3 id="building-an-object-from-the-bottom-up"><strong>Building an Object from the Bottom Up</strong></h3>
<p>The subclass initializes its own stored properties first:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span></code></pre>
<p>Then it asks the superclass to initialize its properties</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span></code></pre>
<p>Only when every class in the hierarchy has finished initialization is the object considered ready to use.</p>
<p>Without these rules, Swift could allow partially initialized objects to exist</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> employee <span class="code-punctuation">=</span> <span class="code-type">Employee</span><span class="code-punctuation">(</span>...<span class="code-punctuation">)</span></span></code></pre>
<p>might contain a valid <code>employeeID</code> but an uninitialized <code>name</code>.</p>
<p>Swift’s initialization system prevents that from ever happening.</p>
<p>This focus on safety is the reason Swift introduces designated initializers, convenience initializers, and the delegation rules that we’ll examine next.</p>
<h3 id="understanding-swifts-three-delegation-rules">Understanding Swift's Three Delegation Rules</h3>
<p>When Swift introduced designated and convenience initializers, it also introduced three rules that govern how they interact.</p>
<h4 id="rule-1">Rule 1</h4>
<h5 id="a-designated-initializer-must-call-a-designated-initializer-from-its-immediate-superclass">A Designated Initializer Must Call a Designated Initializer from Its Immediate Superclass</h5>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span> <span class="code-comment">// This calls the Person designated initializer</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<ul><li>Subclass properties must be initialized <strong>before</strong> calling <code>super.init()</code>.</li></ul>
<ul><li>Designated initializers move <strong>up</strong> the inheritance chain.</li></ul>
<h4 id="rule-2">Rule 2</h4>
<h5 id="a-convenience-initializer-must-call-another-initializer-in-the-same-class">A Convenience Initializer Must Call Another Initializer in the Same Class</h5>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    convenience <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span> <span class="code-comment">// this calls the User initializer</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<ul><li>Convenience initializers move <strong>across</strong> the same class.</li></ul>
<h4 id="rule-3">Rule 3</h4>
<h5 id="a-convenience-initializer-must-ultimately-end-up-calling-a-designated-initializer">A Convenience Initializer Must Ultimately End Up Calling a Designated Initializer</h5>
<p>Every initialization path must eventually reach a designated initializer.</p>
<h6 id="remember">Remember</h6>
<pre class="code-block" data-language="TEXT"><code class="language-text"><span class="code-line">Convenience → Across</span><span class="code-line">Designated → Up</span></code></pre>
<hr>
<h3 id="overriding-initializers">Overriding Initializers</h3>
<p>A subclass can override an initializer of the superclass.</p>
<p>Overriding an initializer allows a subclass to customize how an inherited initialization process works.</p>
<p>In this example, the <code>Employee</code> class overrides the initializer inherited from <code>Person</code>.</p>
<p>Notice the use of the <code>override</code> keyword. This tells Swift that we’re replacing the implementation provided by the superclass.</p>
<blockquote><p>The override initializer in the Employee class first initializes the employeeID, giving every user a unique ID during initialization and only then can the initializer delegate to the superclass</p></blockquote>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"></span><span class="code-line">    override <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> <span class="code-type">Int</span><span class="code-property">.random</span><span class="code-punctuation">(</span><span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-number">1000...9999</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Swift follows these steps.</p>
<p>Employee.init(name:)</p>
<p>​        │</p>
<p>​        ▼</p>
<p>employeeID initialized</p>
<p>​        │</p>
<p>​        ▼</p>
<p>Person.init(name:)</p>
<p>​        │</p>
<p>​        ▼</p>
<p>name initialized</p>
<p>​        │</p>
<p>​        ▼</p>
<p>Object ready to use</p>
<hr>
<h3 id="required-initializers">Required Initializers</h3>
<p>Sometimes a superclass needs to ensure that every subclass provides a particular initializer.</p>
<p>The purpose of <code>required</code> is <strong>not</strong> to force a subclass to call <code>super.init(name:)</code>.</p>
<p>The purpose of <code>required</code> is to force a subclass to <strong>provide an initializer with the same signature</strong>.</p>
<p>Consider this class</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    required <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Now consider this subclass</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span>employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This <strong>fails</strong> because the <strong>required</strong> superclass init must be provided by the <code>Employee</code> subclass.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    required <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">           <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> <span class="code-number">0</span></span><span class="code-line">           <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">       <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span>employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h3 id="failable-and-throwing-initializers">Failable and Throwing Initializers</h3>
<p>Failable and throwing initializers work exactly the same in classes as they do in structs. The primary difference is that subclasses must also account for failures or errors that may occur when calling superclass initializers. If a superclass initializer can fail or throw, subclasses must handle that behavior as part of their own initialization process.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">?</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> !name<span class="code-property">.isEmpty</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-keyword">nil</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Employee</span><span class="code-punctuation">:</span> <span class="code-type">Person</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">?</span><span class="code-punctuation">(</span></span><span class="code-line">        name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span></span><span class="code-line">        employeeID<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.employeeID</span> <span class="code-punctuation">=</span> employeeID</span><span class="code-line">        <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> employee <span class="code-punctuation">=</span> <span class="code-type">Employee</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">""</span><span class="code-punctuation">,</span>employeeID<span class="code-punctuation">:</span> <span class="code-number">1001</span><span class="code-punctuation">)</span> <span class="code-comment">// nil</span></span></code></pre>
<p>In this example, <code>super.init(name: name)</code> fails because name is empty. Since the superclass initializer is failable, the subclass initializer must also be failable</p>
<hr>
<h1 id="final-example">Final Example</h1>
<p>Here is an example of a <code>Course</code> class with a <code>VideoCourse</code> subclass</p>
<p>The <code>Course</code> has a <code>throwing</code> initializer as well as a <code>convenience</code> initializer.</p>
<p>Similarly, <code>VideoCourse</code> has a <code>throwing</code> initializer and a <code>convenience</code> initializer o its own.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">CourseError</span><span class="code-punctuation">:</span> <span class="code-type">Error</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> emptyTitle</span><span class="code-line">    <span class="code-keyword">case</span> invalidDuration</span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">Course</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> lessonCount<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">let</span> isPublished<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span></span><span class="code-line">        title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span></span><span class="code-line">        lessonCount<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">,</span></span><span class="code-line">        isPublished<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> !title<span class="code-property">.isEmpty</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">CourseError</span><span class="code-property">.emptyTitle</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.lessonCount</span> <span class="code-punctuation">=</span> lessonCount</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPublished</span> <span class="code-punctuation">=</span> isPublished</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    convenience <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">try</span> <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> title<span class="code-punctuation">,</span></span><span class="code-line">            lessonCount<span class="code-punctuation">:</span> <span class="code-number">1</span><span class="code-punctuation">,</span></span><span class="code-line">            isPublished<span class="code-punctuation">:</span> <span class="code-keyword">false</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"><span class="code-keyword">class</span> <span class="code-type">VideoCourse</span><span class="code-punctuation">:</span> <span class="code-type">Course</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> durationInMinutes<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span></span><span class="code-line">        title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span></span><span class="code-line">        lessonCount<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">,</span></span><span class="code-line">        isPublished<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">,</span></span><span class="code-line">        durationInMinutes<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> durationInMinutes &gt; <span class="code-number">0</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">CourseError</span><span class="code-property">.invalidDuration</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.durationInMinutes</span> <span class="code-punctuation">=</span> durationInMinutes</span><span class="code-line">        <span class="code-keyword">try</span> <span class="code-keyword">super</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> title<span class="code-punctuation">,</span></span><span class="code-line">            lessonCount<span class="code-punctuation">:</span> lessonCount<span class="code-punctuation">,</span></span><span class="code-line">            isPublished<span class="code-punctuation">:</span> isPublished</span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    convenience <span class="code-keyword">init</span><span class="code-punctuation">(</span>title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">try</span> <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> title<span class="code-punctuation">,</span></span><span class="code-line">            lessonCount<span class="code-punctuation">:</span> <span class="code-number">1</span><span class="code-punctuation">,</span></span><span class="code-line">            isPublished<span class="code-punctuation">:</span> <span class="code-keyword">false</span><span class="code-punctuation">,</span></span><span class="code-line">            durationInMinutes<span class="code-punctuation">:</span> <span class="code-number">60</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Uses the videoCourse initializer</span></span><span class="code-line"><span class="code-keyword">let</span> swiftUICourse <span class="code-punctuation">=</span> <span class="code-keyword">try</span> <span class="code-type">VideoCourse</span><span class="code-punctuation">(</span></span><span class="code-line">    title<span class="code-punctuation">:</span> <span class="code-string">"Mastering SwiftUI"</span><span class="code-punctuation">,</span></span><span class="code-line">    lessonCount<span class="code-punctuation">:</span> <span class="code-number">42</span><span class="code-punctuation">,</span></span><span class="code-line">    isPublished<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">,</span></span><span class="code-line">    durationInMinutes<span class="code-punctuation">:</span> <span class="code-number">540</span></span><span class="code-line"><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Uses the VideoCourse convenience initializer</span></span><span class="code-line"><span class="code-keyword">let</span> draftCourse <span class="code-punctuation">=</span> <span class="code-keyword">try</span> <span class="code-type">VideoCourse</span><span class="code-punctuation">(</span></span><span class="code-line">    title<span class="code-punctuation">:</span> <span class="code-string">"Introduction to Swift"</span></span><span class="code-line"><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Fails the validation in VideoCourse where the duration must be &gt; 0</span></span><span class="code-line"><span class="code-keyword">let</span> course <span class="code-punctuation">=</span> <span class="code-keyword">try</span> <span class="code-type">VideoCourse</span><span class="code-punctuation">(</span></span><span class="code-line">    title<span class="code-punctuation">:</span> <span class="code-string">"SwiftUI"</span><span class="code-punctuation">,</span></span><span class="code-line">    lessonCount<span class="code-punctuation">:</span> <span class="code-number">20</span><span class="code-punctuation">,</span></span><span class="code-line">    isPublished<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">,</span></span><span class="code-line">    durationInMinutes<span class="code-punctuation">:</span> <span class="code-number">0</span></span><span class="code-line"><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line"><span class="code-comment">// Fails the validation where a Course title cannot be empty</span></span><span class="code-line"><span class="code-keyword">let</span> course2 <span class="code-punctuation">=</span> <span class="code-keyword">try</span> <span class="code-type">VideoCourse</span><span class="code-punctuation">(</span></span><span class="code-line">    title<span class="code-punctuation">:</span> <span class="code-string">""</span><span class="code-punctuation">,</span></span><span class="code-line">    lessonCount<span class="code-punctuation">:</span> <span class="code-number">20</span><span class="code-punctuation">,</span></span><span class="code-line">    isPublished<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">,</span></span><span class="code-line">    durationInMinutes<span class="code-punctuation">:</span> <span class="code-number">10</span></span><span class="code-line"><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h1 id="conclusion">Conclusion</h1>
<p>Class initialization builds on the concepts you learned with structs but adds inheritance, designated initializers, convenience initializers, required initializers, and two-phase initialization.</p>
<p>Remember:</p>
<p><strong>Convenience goes across. Designated goes up.</strong></p>]]></content:encoded>
  </item>
  <item>
    <title>Swift Initializers Part 1: Structs</title>
    <link>https://www.createchsol.com/blog/2026-06-03-swift-initializers-part-1-structs.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-06-03-swift-initializers-part-1-structs.html</guid>
    <pubDate>Wed, 03 Jun 2026 07:00:00 +0000</pubDate>
    <description>Swift Initializers: Understanding Initializers in Structs</description>
                    <category>Foundation</category>
                <category>Swift</category>
    <content:encoded><![CDATA[<h1 id="swift-initializers-understanding-initializers-in-structs">Swift Initializers: Understanding Initializers in Structs</h1>
<h2 id="introduction">Introduction</h2>
<p>Over the years, I have created a number of videos address the topic of initializers in Swift.   If you are interested in those videos instead of reading this blog, you can find them <a href="#youtube-videos-on-initializers">here</a>.</p>
<p>Everyone has their own learning style, so I thought that for those of you who prefer written content over YouTube videos, I would create an blog post and see if that works for you.</p>
<p>This is the <strong>first of two posts</strong> on initializers and in this one,  I will focus on initializers in <strong>structs</strong>.</p>
<p>One of the first things you'll encounter when learning Swift is the concept of an initializer. Every instance of a struct must be initialized before it can be used. An initializer ensures that all stored properties have valid values before an instance becomes available.</p>
<p>We'll begin with the basics and progressively explore more advanced initialization techniques.</p>
<hr>
<h3 id="why-do-we-need-initializers">Why Do We Need Initializers?</h3>
<p>When you create an instance of a struct, you need to provide values for all its stored properties.</p>
<p>Swift requires every stored property to have a value before an instance can exist.</p>
<p>For example, consider the following struct.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>If we just try to create an instance of user withouth providing values for all of its stored properties, we get an error.  Fortunately, as you will see shortly, Swift will do its best to prevent us from trying to do this.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-comment">// Error</span></span></code></pre>
<hr>
<h3 id="default-property-values">Default Property Values</h3>
<p>When you create your struct, you can provide default values for all of the store properties and when you do this, where we failed previous, we now succeed.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">=</span> <span class="code-string">"Guest"</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-comment">// OK</span></span></code></pre>
<hr>
<h2 id="the-memberwise-initializer">The Memberwise Initializer</h2>
<p>Earlier, I mentioned that Swift will do its best to prevent us from trying to create an instance of a struct without providing values for all of its stored properties.  This is unique to structs and does not apply to classes as you will learn in the next post.  Swift automatically creates a <strong>memberwise initializer</strong> for structs that do not define their own initializer.</p>
<p>This means, when you start to create an instance of your struct, Xcode will automatically provide you with all of the properties that have not yet been initialized so you can provide values for them</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span></code></pre>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise.png" alt="Memberwise Initializer"></p>
<h3 id="constant-properties-and-initialization">Constant Properties and Initialization</h3>
<p>One of the primary reasons initializers exist is to provide values for constant properties.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> age<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> age<span class="code-punctuation">:</span> <span class="code-number">75</span><span class="code-punctuation">)</span></span></code></pre>
<p>After initialization, these values cannot be changed.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line">user<span class="code-property">.name</span> <span class="code-punctuation">=</span> <span class="code-string">"Bob"</span> <span class="code-comment">// Error</span></span></code></pre>
<p>Constants make your types safer because they cannot be modified after creation. Some of the most common uses for constants are IDs and creation dates.</p>
<h3 id="memberwise-initializers-and-default-values">Memberwise Initializers and Default Values</h3>
<p>If you have properties that do have a default value assigned, you will get additional memberwise initializes so that you can override the default value.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-keyword">var</span> age <span class="code-punctuation">=</span> <span class="code-number">74</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span><span class="code-line">or</span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">,</span> age<span class="code-punctuation">:</span> <span class="code-number">75</span><span class="code-punctuation">)</span></span></code></pre>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise2.png" alt="Memberwise2"></p>
<p>If there is more than one property that has a default value assigned, Xcode will collapse them into a single line where the ones with default values are dimmed out so of you press enter on your keyboard you will get only those properties that do not have a value assigned and the other values will be assigned their default values.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-keyword">var</span> age <span class="code-punctuation">=</span> <span class="code-number">74</span></span><span class="code-line">    <span class="code-keyword">var</span> sex <span class="code-punctuation">=</span> <span class="code-string">"M"</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise3.png" alt="Memberwise3"></p>
<p>If, when creating the instance, you continue to type the names or partial names of the properties that have default values, they will be no longer be dimmed, and tapping on the keyboard will crate the memberwise initializer for all of those properties</p>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise4.png" alt="CleanShot 2026-05-30 at 13.04.40"></p>
<p>The other alternative is to use the right arrow key on your keyboard to present all possible initializers for the structure and you can choose which one you want.</p>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise5.png" alt="CleanShot 2026-05-30 at 13.04.40"></p>
<h2 id="custom-initializers">Custom Initializers</h2>
<p>If memberwise initializers did not exist, as you will see in the next post for classes, you would have to create your own initializer.</p>
<p>For example, in our struct that we started with</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The initializer, which is basically a method that requires parameters for all properties that do not have a default value and assign those parameters to the corresponding properties.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">  <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">  <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This is what we will have to do with classes as you will see in the next post.</p>
<p>The confusing part for beginners is the use of the syntax <code>self.name = name</code></p>
<p><code>self.name</code> refers to the actual property instance, and not the parameter, so we need to avoid ambiguity.</p>
<p>There is no reason why we need to use the same strings for our parameter labels as our properties however.  This is just convention.  If we do not use the same strings, then we can avoid using <code>self</code>.  For example the following is a perfectly legitimate initializer.</p>
<blockquote><p>Note that when creating an instance of User, the initializer parameter labels are used.</p></blockquote>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">var</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>initialName<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> initialIsPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        name <span class="code-punctuation">=</span> initialName</span><span class="code-line">        isPremium <span class="code-punctuation">=</span> initialIsPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">let</span> user <span class="code-punctuation">=</span> <span class="code-type">User</span><span class="code-punctuation">(</span>initialName<span class="code-punctuation">:</span> <span class="code-string">"Stewart"</span><span class="code-punctuation">,</span> initialIsPremium<span class="code-punctuation">:</span> <span class="code-keyword">true</span><span class="code-punctuation">)</span></span></code></pre>
<p>I am not a supporter of doing this however, because it can lead to confusion.  It is likely wiser to use external parameter labels instead.</p>
<hr>
<h3 id="initializer-parameter-labels">Initializer Parameter Labels</h3>
<p>Initializer parameters support both external and internal names.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">Video</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> nom<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>videoTitle nom<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.nom</span> <span class="code-punctuation">=</span> nom</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Usage:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>videoTitle<span class="code-punctuation">:</span> <span class="code-string">"Swift Initializers"</span><span class="code-punctuation">)</span></span></code></pre>
<p>Here:</p>
<ul><li><code>videoTitle</code> is the external label</li><li><code>nom</code> is the internal parameter name</li></ul>
<p>When an instance is created, the initializers uses the external label and then assigns whatever was provided to the property in your struct that has the internal label.</p>
<p>Good labels can create self-documenting code, particularly if you are dealing with an API where the property names are not obvious.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>videoTitle<span class="code-punctuation">:</span> <span class="code-string">"Swift Initializers"</span><span class="code-punctuation">)</span></span></code></pre>
<p>This may clearer to English speakers than:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span>nom<span class="code-punctuation">:</span> <span class="code-string">"Swift Initializers"</span><span class="code-punctuation">)</span></span></code></pre>
<hr>
<h3 id="omitting-external-labels">Omitting External Labels</h3>
<p>Sometimes, you don't want to have to provide a label at all and you can do this by providing an _ as the external parameter label</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">Video</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>_ title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> video <span class="code-punctuation">=</span> <span class="code-type">Video</span><span class="code-punctuation">(</span><span class="code-string">"Swift Initializers"</span><span class="code-punctuation">)</span></span></code></pre>
<p>Use omitted labels sparingly and only when the meaning is obvious.</p>
<hr>
<h3 id="preserving-the-memberwise-initializer">Preserving the Memberwise Initializer</h3>
<p>One of the initial drawbacks of creating a custom initializer is that you lose the memberwise version.  This can be resolved however, by creating an extension to the struct, and creating your custom initializer in the extension instead, you get both</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">extension</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Now both the memberwise initializer and the custom initializer are available.</p>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/MemberWise6.png" alt="Memberwise6"></p>
<hr>
<h2 id="multiple-initializers">Multiple Initializers</h2>
<p>You can also create multiple initializers for a struct.  By doing so, you can create a version of an initializer that will assign a default value for one of the properties as you see in this example, where the second initializer assigns false to the stored isPremium property.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>You can use multiple initializers when there are multiple valid ways to create an instance.</p>
<h3 id="initializer-delegation">Initializer Delegation</h3>
<p>And there is an another way to accomplish the same thing as above by using <strong>initializer delegation.</strong>  Delegation can avoid duplication by having one initializer call another</p>
<p>For example, here, the second initializer </p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> name<span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<h3 id="convenience-initializer-for-structs">Convenience Initializer for Structs</h3>
<p>There is a simpler way to accomplish exactly the same thing as the above two example.  You can provide a default value right within the initializer itself</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">User</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> name<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>name<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> isPremium<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.name</span> <span class="code-punctuation">=</span> name</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPremium</span> <span class="code-punctuation">=</span> isPremium</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Both </p>
<p><img src="blog/2026-06-03-swift-initializers-part-1-structs_assets/Convenience.png" alt="Convenience"></p>
<hr>
<h2 id="failable-initializers">Failable Initializers</h2>
<p>Initializers can be failable too.  You add <code>? </code> to the end of of the init.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">EmailAddress</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> value<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">?</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> value<span class="code-property">.contains</span><span class="code-punctuation">(</span><span class="code-string">"@"</span><span class="code-punctuation">)</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-keyword">nil</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.value</span> <span class="code-punctuation">=</span> value</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> valid <span class="code-punctuation">=</span> <span class="code-type">EmailAddress</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-string">"stewart@example.com"</span><span class="code-punctuation">)</span> <span class="code-comment">// valid Optional&lt;EmailAddress&gt;</span></span><span class="code-line"><span class="code-keyword">let</span> invalid <span class="code-punctuation">=</span> <span class="code-type">EmailAddress</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-string">"invalid"</span><span class="code-punctuation">)</span> <span class="code-comment">// nil</span></span></code></pre>
<p>Use <code>init?</code> when initialization should either succeed or fail.</p>
<hr>
<h2 id="throwing-initializers">Throwing Initializers</h2>
<p>Initializers can also throw errors and this can be handy if you want to provide detailed failure information.  These are better in my opinion than Failable initializers.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">PasswordError</span><span class="code-punctuation">:</span> <span class="code-type">Error</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> tooShort</span><span class="code-line">    <span class="code-keyword">case</span> missingNumber</span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">Password</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> value<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>value<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> value<span class="code-property">.count</span> &gt;<span class="code-punctuation">=</span> <span class="code-number">8</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">PasswordError</span><span class="code-property">.tooShort</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">guard</span> value<span class="code-property">.contains</span><span class="code-punctuation">(</span><span class="code-keyword">where</span><span class="code-punctuation">:</span> \<span class="code-property">.isNumber</span><span class="code-punctuation">)</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">PasswordError</span><span class="code-property">.missingNumber</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.value</span> <span class="code-punctuation">=</span> value</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h1 id="final-example">Final Example</h1>
<p>Putting it all together, here is an example of a Course struct that </p>
<ul><li>Default parameter values</li><li>Validation</li><li>Throwing initialization</li><li>Delegating initialization</li></ul>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">CourseError</span><span class="code-punctuation">:</span> <span class="code-type">Error</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> emptyTitle</span><span class="code-line">    <span class="code-keyword">case</span> invalidLessonCount</span><span class="code-line"><span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">Course</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">let</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span></span><span class="code-line">    <span class="code-keyword">let</span> lessonCount<span class="code-punctuation">:</span> <span class="code-type">Int</span></span><span class="code-line">    <span class="code-keyword">let</span> isPublished<span class="code-punctuation">:</span> <span class="code-type">Bool</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span></span><span class="code-line">        title<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span></span><span class="code-line">        lessonCount<span class="code-punctuation">:</span> <span class="code-type">Int</span><span class="code-punctuation">,</span></span><span class="code-line">        isPublished<span class="code-punctuation">:</span> <span class="code-type">Bool</span> <span class="code-punctuation">=</span> <span class="code-keyword">false</span></span><span class="code-line">    <span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">guard</span> !title<span class="code-property">.isEmpty</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">CourseError</span><span class="code-property">.emptyTitle</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">guard</span> lessonCount &gt; <span class="code-number">0</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">throw</span> <span class="code-type">CourseError</span><span class="code-property">.invalidLessonCount</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.title</span> <span class="code-punctuation">=</span> title</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.lessonCount</span> <span class="code-punctuation">=</span> lessonCount</span><span class="code-line">        <span class="code-keyword">self</span><span class="code-property">.isPublished</span> <span class="code-punctuation">=</span> isPublished</span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">init</span><span class="code-punctuation">(</span>draftTitle<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-keyword">throws</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">try</span> <span class="code-keyword">self</span><span class="code-property">.init</span><span class="code-punctuation">(</span></span><span class="code-line">            title<span class="code-punctuation">:</span> draftTitle<span class="code-punctuation">,</span></span><span class="code-line">            lessonCount<span class="code-punctuation">:</span> <span class="code-number">1</span><span class="code-punctuation">,</span></span><span class="code-line">            isPublished<span class="code-punctuation">:</span> <span class="code-keyword">false</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<hr>
<h1 id="conclusion">Conclusion</h1>
<p>Most structs begin life with default values or Swift's synthesized memberwise initializer. As your types become more sophisticated, custom initializers allow you to validate input, simplify APIs, and prevent invalid state.</p>
<p>A good progression is:</p>
<ol><li>Start with the memberwise initializer.</li><li>Add default values where appropriate.</li><li>Create custom initializers when business rules emerge.</li><li>Delegate whenever possible.</li><li>Use failable or throwing initializers when validation is required.</li></ol>
<p>Understanding these patterns will make your Swift code safer, clearer, and easier to maintain.</p>
<p>------</p>
<h2 id="youtube-videos-on-initializers">YouTube videos on Initializers</h2>
<p>Here are some videos that I have created on YouTube on Initializers.</p>
<p>The first two were back in 2020</p>
<p><strong>Initializers Part I</strong></p>
<p><a href="https://youtu.be/qtR13ygYEns" target="_blank" rel="noreferrer">https://youtu.be/qtR13ygYEns)</a></p>
<p><strong>Initializers Part II</strong></p>
<p><a href="https://youtu.be/We4rLsgKAws" target="_blank" rel="noreferrer">https://youtu.be/We4rLsgKAws</a></p>
<p>And then I created another one in 2024 with much of the same content, but presented in a slightly different way.</p>
<p><strong>Understanding Swift Initializers</strong></p>
<p><a href="https://youtu.be/ElfPQZ9MVTQ" target="_blank" rel="noreferrer">https://youtu.be/ElfPQZ9MVTQ</a></p>
<p><a href="#introduction">Return to introduction</a></p>]]></content:encoded>
  </item>
  <item>
    <title>Generating a QR Code from a String in SwiftUI</title>
    <link>https://www.createchsol.com/blog/2026-05-08-generating-a-qr-code-from-a-string-in-swiftui.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-05-08-generating-a-qr-code-from-a-string-in-swiftui.html</guid>
    <pubDate>Fri, 08 May 2026 07:00:00 +0000</pubDate>
    <description>As I am thinking about enhancements for my recently released app MyLinks I thought that I would like an option to generate a QR code for any one or series of those links so that I could tap on a share button to present a...</description>
                    <category>SwiftUI</category>
                <category>Technique</category>
    <content:encoded><![CDATA[<p>As I am thinking about enhancements for my recently released app <a href="https://apple.co/4cCjCpE" target="_blank" rel="noreferrer">MyLinks</a> I thought that I would like an option to generate a QR code for any one or series of those links so that I could tap on a share button to present a modal sheet that will show the QRCode on the screen and then people that I am sharing with can simply scan the code to open the link. </p>
<p>  <img src="blog/2026-05-08-generating-a-qr-code-from-a-string-in-swiftui_assets/RocketSim_Recording_iPhone_17_Pro_6.3_2026-04-29_13.37.57.gif" alt="RocketSim_Recording_iPhone_17_Pro_6.3_2026-04-29_13.37.57"></p>
<p>As I am doing that, I thought that it might be helpful to write a blog post for my website about how to generate a QR code from a string and present it on the screen so that is what this blog post is about.</p>
<h2 id="the-goal">The Goal</h2>
<p>We want a tiny helper that lets us write this:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">if</span> <span class="code-keyword">let</span> image <span class="code-punctuation">=</span> <span class="code-type">QRCodeGenerator</span><span class="code-property">.image</span><span class="code-punctuation">(</span>from<span class="code-punctuation">:</span> <span class="code-string">"https://www.createchsol.com"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    image</span><span class="code-line">        <span class="code-property">.interpolation</span><span class="code-punctuation">(</span><span class="code-property">.none</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.resizable</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.scaledToFit</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The helper should hide the Core Image setup so the view does not have to know anything about filters, contexts, image extents, or scaling transforms.</p>
<h2 id="why-use-an-enum">Why Use an Enum?</h2>
<p>For this example, <code>QRCodeGenerator</code> is an <code>enum</code> with static functions:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">QRCodeGenerator</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">func</span> image<span class="code-punctuation">(</span>from text<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Image</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-comment">// Generate a QR code image</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>This is a nice fit because the type does not need to store app state. It is more like a toolbox than an object. You are not creating "a QR code generator" that has a lifecycle; you are calling a utility function that converts input into output.</p>
<p>Using an enum with no cases also prevents accidental initialization:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> generator <span class="code-punctuation">=</span> <span class="code-type">QRCodeGenerator</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span> <span class="code-comment">// Not possible</span></span></code></pre>
<p>That is exactly what we want for a simple namespace.</p>
<h2 id="the-core-image-filter">The Core Image Filter</h2>
<p>Apple gives us a built-in QR code filter through Core Image:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">CIFilter</span><span class="code-property">.qrCodeGenerator</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span></code></pre>
<p>The filter expects its message as <code>Data</code>, so a Swift <code>String</code> needs to be converted first:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line">filter<span class="code-property">.message</span> <span class="code-punctuation">=</span> <span class="code-type">Data</span><span class="code-punctuation">(</span>text<span class="code-property">.utf8</span><span class="code-punctuation">)</span></span></code></pre>
<p>It also supports an error correction level:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line">filter<span class="code-property">.correctionLevel</span> <span class="code-punctuation">=</span> <span class="code-string">"M"</span></span></code></pre>
<p>The common levels are:</p>
<ul><li><code>L</code>: Low</li><li><code>M</code>: Medium</li><li><code>Q</code>: Quartile</li><li><code>H</code>: High</li></ul>
<p>Higher correction levels make the QR code more resilient if it is partially damaged or obscured, but they can also make the code denser. <code>M</code> is a sensible default for everyday generated codes.</p>
<h2 id="the-qrcodegenerator-type">The QRCodeGenerator Type</h2>
<p>There are two imports besides SwiftUI. </p>
<p>I import <strong>CoreImage.CIFilterBuiltins</strong> so I can use Core Image’s typed, Swift-friendly filter APIs like CIFilter.qrCodeGenerator(). It avoids older string-based filter creation and gives clearer, safer code with autocomplete for properties like message and correctionLevel</p>
<p>I import <strong>UIKit</strong> because the generator returns a UIImage.</p>
<p>Here is the full helper:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">CoreImage</span><span class="code-property">.CIFilterBuiltins</span></span><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">SwiftUI</span></span><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">UIKit</span></span><span class="code-line"></span><span class="code-line"><span class="code-attribute">@MainActor</span></span><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">QRCodeGenerator</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">let</span> context <span class="code-punctuation">=</span> <span class="code-type">CIContext</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">func</span> image<span class="code-punctuation">(</span>from text<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Image</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> <span class="code-keyword">let</span> uiImage <span class="code-punctuation">=</span> uiImage<span class="code-punctuation">(</span>from<span class="code-punctuation">:</span> text<span class="code-punctuation">)</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span> <span class="code-keyword">return</span> <span class="code-keyword">nil</span> <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-keyword">return</span> <span class="code-type">Image</span><span class="code-punctuation">(</span>uiImage<span class="code-punctuation">:</span> uiImage<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">static</span> <span class="code-keyword">func</span> uiImage<span class="code-punctuation">(</span>from text<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">UIImage</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">let</span> filter <span class="code-punctuation">=</span> <span class="code-type">CIFilter</span><span class="code-property">.qrCodeGenerator</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        filter<span class="code-property">.message</span> <span class="code-punctuation">=</span> <span class="code-type">Data</span><span class="code-punctuation">(</span>text<span class="code-property">.utf8</span><span class="code-punctuation">)</span></span><span class="code-line">        filter<span class="code-property">.correctionLevel</span> <span class="code-punctuation">=</span> <span class="code-string">"M"</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">guard</span> <span class="code-keyword">let</span> outputImage <span class="code-punctuation">=</span> filter<span class="code-property">.outputImage</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span> <span class="code-keyword">return</span> <span class="code-keyword">nil</span> <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">let</span> scaledImage <span class="code-punctuation">=</span> outputImage<span class="code-property">.transformed</span><span class="code-punctuation">(</span></span><span class="code-line">            by<span class="code-punctuation">:</span> <span class="code-type">CGAffineTransform</span><span class="code-punctuation">(</span>scaleX<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">,</span> y<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">guard</span> <span class="code-keyword">let</span> cgImage <span class="code-punctuation">=</span> context<span class="code-property">.createCGImage</span><span class="code-punctuation">(</span></span><span class="code-line">            scaledImage<span class="code-punctuation">,</span></span><span class="code-line">            from<span class="code-punctuation">:</span> scaledImage<span class="code-property">.extent</span></span><span class="code-line">        <span class="code-punctuation">)</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-keyword">return</span> <span class="code-keyword">nil</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">        <span class="code-keyword">return</span> <span class="code-type">UIImage</span><span class="code-punctuation">(</span>cgImage<span class="code-punctuation">:</span> cgImage<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>There are two public functions here:</p>
<ul><li><code>image(from:)</code> returns a SwiftUI <code>Image</code>, which is convenient for displaying in a view.</li><li><code>uiImage(from:)</code> returns a <code>UIImage</code>, which is useful if you later want to share, save, or render the QR code into another image (and I do that in the sample project referenced at the end of this post).</li></ul>
<p>The SwiftUI function simply builds on top of the UIKit function.</p>
<h2 id="why-scale-the-output-image">Why Scale the Output Image?</h2>
<p>Core Image's QR code output starts very small. If you display it directly and let SwiftUI stretch it, the result can become blurry.</p>
<p>This line scales the Core Image output before turning it into a <code>CGImage</code>:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">let</span> scaledImage <span class="code-punctuation">=</span> outputImage<span class="code-property">.transformed</span><span class="code-punctuation">(</span></span><span class="code-line">    by<span class="code-punctuation">:</span> <span class="code-type">CGAffineTransform</span><span class="code-punctuation">(</span>scaleX<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">,</span> y<span class="code-punctuation">:</span> <span class="code-number">12</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">)</span></span></code></pre>
<p>Then, when displaying the final image in SwiftUI, use:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-property">.interpolation</span><span class="code-punctuation">(</span><span class="code-property">.none</span><span class="code-punctuation">)</span></span></code></pre>
<p>That tells SwiftUI not to smooth the hard edges. QR codes are supposed to look like crisp little block mosaics, not soft watercolor paintings.</p>
<h2 id="a-minimal-swiftui-example">A Minimal SwiftUI Example</h2>
<p>Here is a small view that uses the helper:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">SwiftUI</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ContentView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> text <span class="code-punctuation">=</span> <span class="code-string">""</span></span><span class="code-line">    <span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> qrCodeText <span class="code-punctuation">=</span> <span class="code-string">""</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">private</span> <span class="code-keyword">var</span> qrCodeImage<span class="code-punctuation">:</span> <span class="code-type">Image</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">guard</span> !qrCodeText<span class="code-property">.isEmpty</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span> <span class="code-keyword">return</span> <span class="code-keyword">nil</span> <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-keyword">return</span> <span class="code-type">QRCodeGenerator</span><span class="code-property">.image</span><span class="code-punctuation">(</span>from<span class="code-punctuation">:</span> qrCodeText<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">Form</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Section</span><span class="code-punctuation">(</span><span class="code-string">"QR Code Content"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    <span class="code-type">TextField</span><span class="code-punctuation">(</span><span class="code-string">"Enter text or a URL"</span><span class="code-punctuation">,</span> text<span class="code-punctuation">:</span> $text<span class="code-punctuation">)</span></span><span class="code-line">                        <span class="code-property">.textInputAutocapitalization</span><span class="code-punctuation">(</span><span class="code-property">.never</span><span class="code-punctuation">)</span></span><span class="code-line">                        <span class="code-property">.autocorrectionDisabled</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">                    <span class="code-type">Button</span><span class="code-punctuation">(</span><span class="code-string">"Generate QR Code"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                        <span class="code-keyword">let</span> trimmedText <span class="code-punctuation">=</span> text<span class="code-property">.trimmingCharacters</span><span class="code-punctuation">(</span></span><span class="code-line">                            <span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-property">.whitespacesAndNewlines</span></span><span class="code-line">                        <span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">                        <span class="code-keyword">guard</span> !trimmedText<span class="code-property">.isEmpty</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span> <span class="code-keyword">return</span> <span class="code-punctuation">}</span></span><span class="code-line">                        qrCodeText <span class="code-punctuation">=</span> trimmedText</span><span class="code-line">                    <span class="code-punctuation">}</span></span><span class="code-line">                    <span class="code-property">.disabled</span><span class="code-punctuation">(</span></span><span class="code-line">                        text<span class="code-property">.trimmingCharacters</span><span class="code-punctuation">(</span><span class="code-keyword">in</span><span class="code-punctuation">:</span> <span class="code-property">.whitespacesAndNewlines</span><span class="code-punctuation">)</span><span class="code-property">.isEmpty</span></span><span class="code-line">                    <span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">                <span class="code-keyword">if</span> <span class="code-keyword">let</span> qrCodeImage <span class="code-punctuation">{</span></span><span class="code-line">                    <span class="code-type">Section</span><span class="code-punctuation">(</span><span class="code-string">"Preview"</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                        qrCodeImage</span><span class="code-line">                            <span class="code-property">.interpolation</span><span class="code-punctuation">(</span><span class="code-property">.none</span><span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-property">.resizable</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-property">.scaledToFit</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-property">.frame</span><span class="code-punctuation">(</span>width<span class="code-punctuation">:</span> <span class="code-number">240</span><span class="code-punctuation">,</span> height<span class="code-punctuation">:</span> <span class="code-number">240</span><span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-property">.background</span><span class="code-punctuation">(</span><span class="code-property">.white</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-punctuation">}</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"QR Code Generator"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Notice the two pieces of state:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> text <span class="code-punctuation">=</span> <span class="code-string">""</span></span><span class="code-line"><span class="code-attribute">@State</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> qrCodeText <span class="code-punctuation">=</span> <span class="code-string">""</span></span></code></pre>
<p><code>text</code> is what the user is currently typing. <code>qrCodeText</code> is the committed value used to generate the QR code.</p>
<p>That small separation keeps the UI predictable. The QR code changes only when the user taps the button, not every time a character is typed.</p>
<h2 id="handling-failure">Handling Failure</h2>
<p>Both of the QRCodeGenerator image functions return optionals:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">static</span> <span class="code-keyword">func</span> image<span class="code-punctuation">(</span>from text<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">Image</span><span class="code-punctuation">?</span></span><span class="code-line"><span class="code-keyword">static</span> <span class="code-keyword">func</span> uiImage<span class="code-punctuation">(</span>from text<span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">)</span> <span class="code-punctuation">-</span>&gt; <span class="code-type">UIImage</span><span class="code-punctuation">?</span></span></code></pre>
<p>That is intentional. QR generation can fail, especially with very large strings. Returning <code>nil</code> gives the view a clean way to show a fallback message:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">if</span> <span class="code-keyword">let</span> image <span class="code-punctuation">=</span> <span class="code-type">QRCodeGenerator</span><span class="code-property">.image</span><span class="code-punctuation">(</span>from<span class="code-punctuation">:</span> qrCodeText<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    image</span><span class="code-line">        <span class="code-property">.interpolation</span><span class="code-punctuation">(</span><span class="code-property">.none</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.resizable</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.scaledToFit</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span> <span class="code-keyword">else</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ContentUnavailableView</span><span class="code-punctuation">(</span></span><span class="code-line">        <span class="code-string">"QR Code Unavailable"</span><span class="code-punctuation">,</span></span><span class="code-line">        systemImage<span class="code-punctuation">:</span> <span class="code-string">"qrcode"</span><span class="code-punctuation">,</span></span><span class="code-line">        description<span class="code-punctuation">:</span> <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Enter shorter text and try again."</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">)</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<h1 id="where-the-full-sample-app-goes-further">Where the Full Sample App Goes Further</h1>
<p>You can find a full sample application on GitHub. https://github.com/StewartLynch/QRCodeGenerator</p>
<p><img src="blog/2026-05-08-generating-a-qr-code-from-a-string-in-swiftui_assets/QRCodeGenerator.gif" alt="QRCodeGenerator"></p>
<p>The full GitHub sample app builds on this focused helper with:</p>
<ul><li>A larger text editor</li><li>Empty-state handling</li><li>Reset behavior</li><li>A polished preview</li><li>Share sheet support</li><li>A custom share image that includes both the QR code and the original text</li></ul>
<p>But the core idea remains the same: keep the QR generation logic isolated in one small type, then let SwiftUI focus on the user experience.</p>
<p>That separation is the quiet win. The view handles interaction. The generator handles generation. Each part has one job, and neither has to pretend to be the other.</p>]]></content:encoded>
  </item>
  <item>
    <title>Appearance Mode Changer</title>
    <link>https://www.createchsol.com/blog/2026-04-28-appearance-mode-changer.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-04-28-appearance-mode-changer.html</guid>
    <pubDate>Tue, 28 Apr 2026 07:00:00 +0000</pubDate>
    <description>Creating an Appearance Mode Picker in SwiftUI</description>
                    <category>Appearance</category>
                <category>SwiftUI</category>
                <category>Technique</category>
    <content:encoded><![CDATA[<h1 id="creating-an-appearance-mode-picker-in-swiftui">Creating an Appearance Mode Picker in SwiftUI</h1>
<p>Many apps give users a simple choice for how the interface should look:</p>
<ul><li>Follow the system appearance</li><li>Always use light mode</li><li>Always use dark mode</li></ul>
<p>SwiftUI makes this surprisingly easy. The trick is to model the choice once, save it with <code>@AppStorage</code>, and apply it at the root of your app with <code>preferredColorScheme</code>.</p>
<p>In this post, we will build an appearance mode setting that can be reused in almost any SwiftUI application.</p>
<h2 id="the-goal">The Goal</h2>
<p>We want the user to choose an appearance mode from inside the app. Once selected, the app should update immediately and remember that choice the next time it launches.</p>
<p>The finished behavior looks like this:</p>
<ul><li><code>System</code> follows the device's current light or dark mode setting.</li><li><code>Light</code> forces the app to use light mode.</li><li><code>Dark</code> forces the app to use dark mode.</li><li>The selected value persists across launches.</li><li>Navigation views and modal sheets inherit the selected appearance.</li></ul>
<h2 id="create-the-appearance-mode-type">Create the Appearance Mode Type</h2>
<p>Start by creating an enum to represent the three supported modes.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">SwiftUI</span></span><span class="code-line"></span><span class="code-line"><span class="code-keyword">enum</span> <span class="code-type">AppearanceMode</span><span class="code-punctuation">:</span> <span class="code-type">String</span><span class="code-punctuation">,</span> <span class="code-type">CaseIterable</span><span class="code-punctuation">,</span> <span class="code-type">Identifiable</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> system</span><span class="code-line">    <span class="code-keyword">case</span> light</span><span class="code-line">    <span class="code-keyword">case</span> dark</span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> id<span class="code-punctuation">:</span> <span class="code-type">Self</span> <span class="code-punctuation">{</span> <span class="code-keyword">self</span> <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> title<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.system</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"System"</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.light</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"Light"</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.dark</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"Dark"</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> iconName<span class="code-punctuation">:</span> <span class="code-type">String</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.system</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"sun.righthalf.filled"</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.light</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"sun.max.fill"</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.dark</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-string">"moon.fill"</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> colorScheme<span class="code-punctuation">:</span> <span class="code-type">ColorScheme</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.system</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-keyword">nil</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.light</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-property">.light</span></span><span class="code-line">        <span class="code-keyword">case</span> <span class="code-property">.dark</span><span class="code-punctuation">:</span></span><span class="code-line">            <span class="code-property">.dark</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>There are a few useful details here.</p>
<p><code>CaseIterable</code> lets us build a picker by looping over all cases. <code>Identifiable</code> makes the enum convenient to use in <code>ForEach</code>. The <code>title</code> and <code>iconName</code> properties keep display details close to the option they describe.</p>
<p>The most important property is <code>colorScheme</code>.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">var</span> colorScheme<span class="code-punctuation">:</span> <span class="code-type">ColorScheme</span><span class="code-punctuation">?</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">switch</span> <span class="code-keyword">self</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.system</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-keyword">nil</span></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.light</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-property">.light</span></span><span class="code-line">    <span class="code-keyword">case</span> <span class="code-property">.dark</span><span class="code-punctuation">:</span></span><span class="code-line">        <span class="code-property">.dark</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p><code>preferredColorScheme</code> accepts an optional <code>ColorScheme</code>. Passing <code>.light</code> or <code>.dark</code> forces that appearance. Passing <code>nil</code> tells SwiftUI not to override the system appearance.</p>
<p>That makes <code>nil</code> the perfect value for the <code>System</code> option.</p>
<h2 id="save-the-selection-with-appstorage">Save the Selection with AppStorage</h2>
<p>Because <code>AppearanceMode</code> is backed by a <code>String</code> raw value, it works well with <code>@AppStorage</code>.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-attribute">@AppStorage</span><span class="code-punctuation">(</span><span class="code-string">"appearanceMode"</span><span class="code-punctuation">)</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> appearanceMode <span class="code-punctuation">=</span> <span class="code-type">AppearanceMode</span><span class="code-property">.system</span></span></code></pre>
<p>This stores the user's choice in <code>UserDefaults</code>. When the value changes, SwiftUI updates any view that depends on it. When the app launches again, the saved value is restored automatically.</p>
<p>You can use any key name you like, but keep it stable once your app ships. Changing the key later would make existing users lose their saved appearance preference.</p>
<h2 id="apply-the-appearance-at-the-app-root">Apply the Appearance at the App Root</h2>
<p>The appearance mode should be applied as high in the view hierarchy as possible. In most apps, that means the <code>App</code> entry point.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">import</span> <span class="code-type">SwiftUI</span></span><span class="code-line"></span><span class="code-line"><span class="code-attribute">@main</span></span><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">MyApp</span><span class="code-punctuation">:</span> <span class="code-type">App</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@AppStorage</span><span class="code-punctuation">(</span><span class="code-string">"appearanceMode"</span><span class="code-punctuation">)</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> appearanceMode <span class="code-punctuation">=</span> <span class="code-type">AppearanceMode</span><span class="code-property">.system</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">Scene</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">WindowGroup</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">ContentView</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-property">.preferredColorScheme</span><span class="code-punctuation">(</span>appearanceMode<span class="code-property">.colorScheme</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Applying <code>preferredColorScheme</code> here means the choice affects the whole app, including pushed navigation destinations and presented sheets.</p>
<p>If you apply the modifier deeper in the hierarchy, you may end up with only part of the interface changing appearance. That can be useful for special cases, but for a user-facing app setting, the root is usually the right place.</p>
<h2 id="add-a-picker-to-the-interface">Add a Picker to the Interface</h2>
<p>Now you need a way for the user to change the value.</p>
<p>Here is a simple toolbar menu:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ContentView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@AppStorage</span><span class="code-punctuation">(</span><span class="code-string">"appearanceMode"</span><span class="code-punctuation">)</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> appearanceMode <span class="code-punctuation">=</span> <span class="code-type">AppearanceMode</span><span class="code-property">.system</span></span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> <span class="code-string">"globe"</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.imageScale</span><span class="code-punctuation">(</span><span class="code-property">.large</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-property">.foregroundStyle</span><span class="code-punctuation">(</span><span class="code-property">.tint</span><span class="code-punctuation">)</span></span><span class="code-line"></span><span class="code-line">                <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Hello, world!"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Mode Changer"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.toolbar</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">ToolbarItem</span><span class="code-punctuation">(</span>placement<span class="code-punctuation">:</span> <span class="code-property">.bottomBar</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    <span class="code-type">Menu</span> <span class="code-punctuation">{</span></span><span class="code-line">                        <span class="code-type">Picker</span><span class="code-punctuation">(</span><span class="code-string">"Appearance"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $appearanceMode<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                            <span class="code-type">ForEach</span><span class="code-punctuation">(</span><span class="code-type">AppearanceMode</span><span class="code-property">.allCases</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span> mode <span class="code-keyword">in</span></span><span class="code-line">                                <span class="code-type">Label</span><span class="code-punctuation">(</span>mode<span class="code-property">.title</span><span class="code-punctuation">,</span> systemImage<span class="code-punctuation">:</span> mode<span class="code-property">.iconName</span><span class="code-punctuation">)</span></span><span class="code-line">                                    <span class="code-property">.tag</span><span class="code-punctuation">(</span>mode<span class="code-punctuation">)</span></span><span class="code-line">                            <span class="code-punctuation">}</span></span><span class="code-line">                        <span class="code-punctuation">}</span></span><span class="code-line">                    <span class="code-punctuation">}</span> label<span class="code-punctuation">:</span> <span class="code-punctuation">{</span></span><span class="code-line">                        <span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> appearanceMode<span class="code-property">.iconName</span><span class="code-punctuation">)</span></span><span class="code-line">                    <span class="code-punctuation">}</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The picker writes directly to the same <code>@AppStorage</code> value. As soon as the selection changes, the app-level <code>preferredColorScheme</code> receives the new value and the interface updates.</p>
<h2 id="why-use-a-menu">Why Use a Menu?</h2>
<p>A menu works well when the setting is available from a toolbar. It keeps the interface tidy while still making the choice easy to reach.</p>
<p>For a settings screen, you may prefer a segmented picker or a list row:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-type">Picker</span><span class="code-punctuation">(</span><span class="code-string">"Appearance"</span><span class="code-punctuation">,</span> selection<span class="code-punctuation">:</span> $appearanceMode<span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-type">ForEach</span><span class="code-punctuation">(</span><span class="code-type">AppearanceMode</span><span class="code-property">.allCases</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span> mode <span class="code-keyword">in</span></span><span class="code-line">        <span class="code-type">Label</span><span class="code-punctuation">(</span>mode<span class="code-property">.title</span><span class="code-punctuation">,</span> systemImage<span class="code-punctuation">:</span> mode<span class="code-property">.iconName</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.tag</span><span class="code-punctuation">(</span>mode<span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>The important part is not the picker style. The important part is that every picker binds to the same stored <code>appearanceMode</code> value.</p>
<h2 id="make-sure-sheets-and-navigation-inherit-the-mode">Make Sure Sheets and Navigation Inherit the Mode</h2>
<p>Because the color scheme is applied at the app root, child views do not need to know anything about the appearance setting.</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">NavigationStackView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"This view was pushed onto the navigation stack."</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> <span class="code-string">"star.fill"</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.largeTitle</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">        <span class="code-property">.navigationTitle</span><span class="code-punctuation">(</span><span class="code-string">"Pushed View"</span><span class="code-punctuation">)</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>Presented sheets also inherit the selected mode:</p>
<pre class="code-block" data-language="SWIFT"><code class="language-swift"><span class="code-line"><span class="code-keyword">struct</span> <span class="code-type">ModalSheetView</span><span class="code-punctuation">:</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">    <span class="code-attribute">@Environment</span><span class="code-punctuation">(</span>\<span class="code-property">.dismiss</span><span class="code-punctuation">)</span> <span class="code-keyword">private</span> <span class="code-keyword">var</span> dismiss</span><span class="code-line"></span><span class="code-line">    <span class="code-keyword">var</span> body<span class="code-punctuation">:</span> <span class="code-keyword">some</span> <span class="code-type">View</span> <span class="code-punctuation">{</span></span><span class="code-line">        <span class="code-type">NavigationStack</span> <span class="code-punctuation">{</span></span><span class="code-line">            <span class="code-type">VStack</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Text</span><span class="code-punctuation">(</span><span class="code-string">"Presented as a modal sheet."</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-type">Image</span><span class="code-punctuation">(</span>systemName<span class="code-punctuation">:</span> <span class="code-string">"apple.logo"</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-property">.font</span><span class="code-punctuation">(</span><span class="code-property">.largeTitle</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.padding</span><span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">            <span class="code-property">.toolbar</span> <span class="code-punctuation">{</span></span><span class="code-line">                <span class="code-type">Button</span><span class="code-punctuation">(</span>role<span class="code-punctuation">:</span> <span class="code-property">.close</span><span class="code-punctuation">)</span> <span class="code-punctuation">{</span></span><span class="code-line">                    dismiss<span class="code-punctuation">(</span><span class="code-punctuation">)</span></span><span class="code-line">                <span class="code-punctuation">}</span></span><span class="code-line">            <span class="code-punctuation">}</span></span><span class="code-line">        <span class="code-punctuation">}</span></span><span class="code-line">    <span class="code-punctuation">}</span></span><span class="code-line"><span class="code-punctuation">}</span></span></code></pre>
<p>These views stay clean because appearance mode is an app-level concern, not a screen-level concern.</p>
<h2 id="the-complete-pattern">The Complete Pattern</h2>
<p>The reusable pattern is:</p>
<ol><li>Create an <code>AppearanceMode</code> enum.</li><li>Store the selected value with <code>@AppStorage</code>.</li><li>Apply <code>preferredColorScheme</code> at the <code>App</code> root.</li><li>Bind any picker or settings control to the same stored value.</li></ol>
<p>Once those pieces are in place, you can expose the setting anywhere in your app.</p>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Appearance mode is a small feature, but it is one of those details that makes an app feel more considerate. Some users want their apps to follow the system. Others want a specific app to stay light or dark regardless of the device setting.</p>
<p>With SwiftUI, supporting all three options only takes a small enum, a stored preference, and one app-wide modifier.</p>
<p>That is a tidy little feature with a lot of user-facing polish.</p>
<p>If you want to download the code for a sample project using this technique you can find on my GitHub.</p>
<p><a href="https://github.com/StewartLynch/ModeChanger" target="_blank" rel="noreferrer">ModeChanger</a></p>]]></content:encoded>
  </item>
  <item>
    <title>Building my Own Static Website Builder</title>
    <link>https://www.createchsol.com/blog/2026-04-20-building-my-own-static-website-builder.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2026-04-20-building-my-own-static-website-builder.html</guid>
    <pubDate>Mon, 20 Apr 2026 07:00:00 +0000</pubDate>
    <description>I have been wanting a better way to maintain the CreaTECH Solutions website.</description>
                    <category>Personal</category>
                <category>Web</category>
    <content:encoded><![CDATA[<p>I have been wanting a better way to maintain the CreaTECH Solutions website.</p>
<p>The site itself is not especially unusual. It has an About page, a YouTube tutorials page, an app portfolio, and a blog. But keeping those pages up to date can become surprisingly repetitive. Each new video needs a thumbnail, a title, a release date, and a link. Each app needs artwork, a description, a source, a download URL, and sometimes a separate app page. Blog entries need images and markdown content. Even simple site-wide details like the logo, header, footer, and social links need to stay consistent across every page.</p>
<p>So instead of continuing to hand-edit web pages, I decided to build a macOS app that could become the content management system for my own site.</p>
<p>The result is CTSiteBuilder, a SwiftUI app that lets me manage the website content in one place and export the whole thing as a static website.</p>
<h3 id="this-site-you-are-viewing-this-blog-on-was-generated-with-this-application">This site you are viewing this blog on was generated with this application.</h3>
<h2 id="starting-with-the-content">Starting With the Content</h2>
<p>The first step was not the UI. It was understanding the shape of the website.</p>
<p>I listed the pages I needed:</p>
<ul><li>About</li><li>YouTube Tutorials</li><li>App Portfolio</li><li>Blog</li></ul>
<p>Then I broke those pages down into the actual pieces of data they needed. The About page needed a title, an about paragraph, a banner image, social links, a Ko-fi callout, and a newsletter callout. The Tutorials page needed playlist information, current video information, thumbnails, YouTube links, release dates, and a way to mark whether a video had been released. The Portfolio page needed app records grouped by source, such as App Store, Gumroad, and GitHub. The Blog page needed entries with dates, images, titles, and markdown content.</p>
<p>That became the foundation of the app. Rather than thinking of the site as a collection of HTML files, I treated it as structured data.</p>
<h2 id="using-sqlitedata-as-the-backbone">Using SQLiteData as the Backbone</h2>
<p>For persistence I used SQLiteData. Each major part of the site has its own table-backed model: site configuration, about page, social links, tutorials page, playlists, videos, portfolio page, portfolio apps, blog page, and blog entries.</p>
<p>This gave the project a clean separation:</p>
<ul><li>SwiftUI is responsible for editing the content.</li><li>SQLiteData is responsible for storing it.</li><li>The exporter is responsible for turning it into web pages.</li></ul>
<p>That separation mattered. Once the data model was in place, it became much easier to add features without rethinking the entire app. For example, adding newsletter fields to the About page or adding a released flag to videos was handled as a database migration, not a rewrite.</p>
<p>The app also supports CloudKit synchronization through SQLiteData, so the content can be synced through iCloud. I added a manual "Force iCloud Resynchronization" action for the point where the CloudKit schema has been deployed and I want to make sure local website records are pushed again.</p>
<h2 id="building-the-editor">Building the Editor</h2>
<p>The main app UI uses a SwiftUI <code>NavigationSplitView</code> with sections for Site Settings, About Page, YouTube Tutorials, App Portfolio, Blog, and Export.</p>
<p>Each section is an editor for a specific part of the website. Site Settings handles shared identity: the site name, logo, live URL, test URL, header title, header subtitle, and footer copyright. The page editors handle their own page title, page name, markdown content, images, and related child records.</p>
<p>The child records were important. Social links, playlists, videos, portfolio apps, and blog entries all need full create, edit, and delete support. Some also need ordering, so I added sort order support and drag-to-reorder behavior where it makes sense.</p>
<p>Images are stored with the records as data. The app supports choosing an image through a file picker or dragging an image directly into the editor. That may sound small, but it makes the app feel much more like a tool I would actually want to use.</p>
<h2 id="markdown-in-html-out">Markdown In, HTML Out</h2>
<p>I wanted writing content to remain comfortable, especially for about text and blog entries. Markdown was the obvious choice.</p>
<p>The app lets me write longer text in markdown, then converts it to HTML during export. That means I can keep the editing experience lightweight while still producing proper web pages. Blog entries become individual detail pages, and the blog index shows excerpts with "Read More" links.</p>
<p>This also kept the website flexible. I can write content naturally in the app without thinking too much about the final HTML structure.</p>
<h2 id="exporting-a-static-website">Exporting a Static Website</h2>
<p>The export process was the major turning point.</p>
<p>All the site data lives in SQLite, but the final output is a static website. When I click export, CTSiteBuilder creates the HTML files, writes image assets into an <code>images</code> folder, creates individual blog detail pages in a <code>blog</code> folder, and copies the shared stylesheet.</p>
<p>The exported pages are generated from templates bundled with the app. There are separate templates for About, Tutorials, Portfolio, Blog, and Blog Entry pages, plus a shared CSS file.</p>
<p>That template approach was intentional. I did not want the design to be buried entirely in Swift code. By keeping HTML templates and CSS as export assets, I can adjust the design of the website without changing the underlying database or editor logic.</p>
<p>The exported site supports:</p>
<ul><li>A shared header and footer.</li><li>Site logo and name on every page.</li><li>Navigation generated from the page records.</li><li>Responsive layout for mobile screens.</li><li>Light and dark mode styling.</li><li>Markdown-rendered content.</li><li>Image export for logos, thumbnails, banners, blog images, and social icons.</li></ul>
<p>The Tutorials page also exports an interactive video browser. Released videos are listed in reverse date order, and selecting a video displays the thumbnail, details, and an embedded player. The Portfolio page groups apps by source. The Blog page generates both the listing page and separate pages for each entry.</p>
<h2 id="deployment-workflow">Deployment Workflow</h2>
<p>Once the static site export was working, the next obvious step was deployment.</p>
<p>The app includes an export section where I can choose an export folder, generate the site, and then deploy it. I built in rsync support because it is a good fit for static websites: it transfers only changed files and works over SSH.</p>
<p>I also added dry-run support. That way I can preview what rsync would change before uploading anything. For safety, the rsync deployment avoids deleting unrelated files at the root of the remote site. It only prunes generated files inside the <code>blog</code> and <code>images</code> folders.</p>
<p>There is also FTP deployment support, including a remote manifest so previously generated files can be removed when they no longer exist locally. But rsync is the workflow I expect to lean on most.</p>
<h2 id="what-i-like-about-this-approach">What I Like About This Approach</h2>
<p>The thing I like most is that the app is tailored to the actual website.</p>
<p>It is not a generic website builder. It does not try to solve every possible publishing problem. It solves my publishing problem: maintaining the CreaTECH Solutions website, keeping tutorials and apps current, writing blog posts in markdown, and exporting a clean static site when I am ready.</p>
<p>That made the project much more approachable. I could start with a concrete list of pages and fields, build a database around that structure, add editing screens, and then focus on generating exactly the website I needed.</p>
<p>It also shows why building small custom tools can be so satisfying. A lot of the time, the best app is not the most universal one. It is the one that understands your workflow.</p>
<h2 id="the-feature-set-today">The Feature Set Today</h2>
<p>CTSiteBuilder now includes:</p>
<ul><li>Site-wide settings for branding, URLs, header text, and footer text.</li><li>Editors for About, Tutorials, Portfolio, and Blog pages.</li><li>CRUD support for social links, playlists, videos, portfolio apps, and blog entries.</li><li>Image import through file picking and drag and drop.</li><li>Markdown support for longer content.</li><li>SQLiteData persistence with database migrations.</li><li>CloudKit synchronization through SQLiteData.</li><li>Static HTML export from bundled templates.</li><li>Responsive CSS with light and dark mode support.</li><li>Generated image assets and blog detail pages.</li><li>FTP deployment support.</li><li>Rsync deployment with dry-run mode and selective pruning.</li></ul>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>This project started with a simple question: what would make updating my website easier?</p>
<p>The answer was not another admin panel or a full web CMS. It was a native Mac app built around the exact content I publish.</p>
<p>That is what I enjoy about this kind of project. SwiftUI gives me a fast way to build the editing experience, SQLiteData gives me a structured and syncable data layer, and a static export keeps the final website simple, fast, and easy to host.</p>
<p>The end result is both a tool and a workflow. I can manage the content locally, sync it through iCloud, export the finished pages, test the result, and deploy it when ready.</p>
<p>For me, that is the sweet spot: a custom app that removes friction from a real recurring task.</p>]]></content:encoded>
  </item>
  <item>
    <title>Can I call myself a YouTuber?</title>
    <link>https://www.createchsol.com/blog/2020-08-31-can-i-call-myself-a-youtuber.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2020-08-31-can-i-call-myself-a-youtuber.html</guid>
    <pubDate>Mon, 31 Aug 2020 07:00:00 +0000</pubDate>
    <description>Some time ago I wrote a blog post titled &quot;Can I call myself a Software Developer&quot; where I mused about my path to becoming a software developer over the course of over 45 years. The jury is still out on that question but...</description>
                    <category>Musing</category>
                <category>Personal</category>
    <content:encoded><![CDATA[<p>Some time ago I wrote a blog post titled "Can I call myself a Software Developer" where I mused about my path to becoming a software developer over the course of over 45 years. The jury is still out on that question but I have not stopped in my quest. The difference is that I really think that I am a far better developer two years later than I was back then. The difference? I became a YouTuber (I think). More on this in just a minute.</p>
<p>In June of 2019 I as interviewed by Sean Allen for his "Origin Stories" theme on his "iOS Dev Discussion" podcast. He felt, after reading my blog that I had a story to share so I jumped at the chance to build my network of fellow developers with the exposure the podcast would bring.</p>
<h4 id="self-taught-vs-self-directed">Self Taught vs Self Directed</h4>
<p>I don't say that I am self taught. I say that I am a self directed learner because I don't believe anyone can teach themselves to be an iOS developer. We all learn from others whether that be through some kind of structured degree program or boot camp or by watching videos, reading other blog posts and asking questions on Twitter, a Facebook group or heaven forbid, Stack Overflow. </p>
<h4 id="building-a-network">Building A Network</h4>
<p>To be a self directed learner you have to be able to build your network of fellow developers or learners; preferably both. You learn from others who know more from you, but just as valuable is learning by sharing what you know with others who are at the same level or still catching up to you.</p>
<p>After Sean's interview, my network started to grow. I also decided through Patreon and GitHub to support some of the people I respect the most for sharing their content for free. Two key people for me at that time were Paul Hudson of Hacking With Swift and Mark Moeykens of Big Mountain Studio. Both offer quality content and at the time, everything they did was free. Both now offer other paid services like Paul's Hacking With Swift Plus and Mark's exceptional SwiftUI resources, which I am happy to support and pay for. You get what you pay for. I am only mentioning Sean, Paul and Mark here because they, unbeknownst to them, played a big part in my progress to become a YouTuber. There are too many to mention here and there are lots of bloggers and YouTubers who deserve credit, but that is not the point of this blog.</p>
<h4 id="in-the-beginning">In the beginning...</h4>
<p>It seems that my interview with Sean struck a chord with some people as my Twitter feed started to grow. Some people reached out to me to say that they are able to identify with my path and encouraged me to keep going. Last year, 2019, before Christmas, Paul Hudson started his 100 Days of SwiftUI. I had been learning SwiftUI from the start but was lacking a structured learning path so I started right at Day 1, committed to work through it to the end. I tweeted about my progress as did many others. One of my followers reached out to me who too was working through the course and had some questions and wondered if I could help him out. His name is Chris and we developed a bit of a rapport. I had more experience than he had and I found that I was able to offer him some suggestions. I have been at this a long time and made a lot of mistakes along the way. I have a background in education and so I know a thing or two about learning and teaching. The one thing I pride myself in is making sure that I do my homework. I want to make sure that the information that I am offering is accurate, structured, applicable and easy to understand. </p>
<p>I hesitate to say it, but I believe that I was a mentor to Chris, It made me feel good. But more than that, it made me analyze how I did things and I realized that in the past, I was not always adhering to best practice. </p>
<p>In my previous company, I was responsible for creating short product videos for YouTube that would show our users how to take advantage of certain features of the product. I created over 100 different videos for that channel so I had some experience with YouTube. That company's product also had a tool that allowed our customers to use a proprietary language based on BASIC to create additional tools that could be used to enhance the functionality of the product. I developed courses to teach those clients how to code those tools. I traveled across North America and parts of Europe teaching 3 day courses on the topic. Later on, the product evolved to a web based tool with an API so I transformed my focus into building web based tools. I continued, after leaving the company to consult and teach coding classes related to that product. Well, the product is basically grandfathered now and the consulting and demand for my services dried up. In my retirement, I needed something to keep my brain active and I realized that my self worth relied a lot on the positive feedback I was getting from my teaching. So, on Jan 12, 2020, I revised my only personal YouTube channel to start focusing on tutorials about coding in Swift.</p>
<h4 id="my-youtube-channel">My YouTube Channel</h4>
<p>I wanted to focus on Swift and SwiftUI Fundamentals. In one of my earlier posts, I categorized the videos as being based on a line from an old song by Rod Stewart and the Faces. "I wish I knew what I know now, when I was younger." If only I knew what I know now about clean code when I first started out, then I would be a better coder now. I look at some of my old projects now and the code is atrocious. If I wanted to implement something I would watch a video, read a few blog posts and copy and paste someone else's code and tweak it until I got the results I wanted. Needless to say, there is no common architecture between apps and even within a single app there might be several different ones.</p>
<p>What I found was that when I was preparing for a video, I had to do a lot of research and make sure that what I wanted to cover followed best practices. This, more than anything has made me a much better developer. There is nothing better than to put yourself out there for the world to see and to comment or criticize on. It seems to work. With over 75 videos on my channel now, I have not yet had a negative review and the feedback has been really encouraging.</p>
<p>My channel is not really for beginners, nor it is for experienced developers though I think there is something there for those categories too. My focus is on people like me. People who have left the starting gate in their coding experience but constantly need reinforcement and review to stay on top of things and improve their skills in their quest to land a software development position.</p>
<p>My channel videos are focussed around 4 different themes. Focussed Playlists, Swift/SwiftUI Fundamentals, Techniques and Developer Tools. </p>
<p>I am guided by the following principals:</p>
<ul><li>Research carefully the topic I am about to present.</li><li>Don't ramble — stay on topic.</li><li>Provide practical examples.</li><li>Only publish quality videos that I am proud of.</li><li>Always credit other developers if I borrow and share something that they have published.</li><li>Publish at least one video a week every Sunday</li></ul>
<p>You will never see my face on a video. I don't think there is any need for a talking head in a YouTube video about coding. You may have a different opinion, but the focus is on the code, not me. Besides, I am afraid that if some of my younger audience actually saw how old I am they would be turned off and dismissive. There is definitely a prejudice with respect to the older generation and a failure to recognize that we have something to offer after all. </p>
<h4 id="the-process">The process</h4>
<p>With those principals in mind, this is how I go about creating my videos.</p>
<p>I start each new video idea by mulling the topic over in my mind and thinking about the best way to present the topic. I use Raindrop.io to gather resources. I often am thinking about many ideas at the same time. There is no fixed amount of time allocated to this task.&lt;br&gt;Once I have decide what the topic is for this week, I try to come up with a sample project or playground that I can work through during the video recording. This will go through many iterations until I am satisfied. Next, I loosely script out the step by step process for creating the project so that I can follow it when recording. Once the script is complete, I use Camtasia to record myself without audio. When the recording is complete, I create a Keynote presentation that I can use as an introduction and export it as a .mov and import it in as the beginning of the video. I then go through the video, editing out any false moves and corrections. The next step is to actually script the entire video, word for word. That's correct. I watch my own videos and write a transcript. When that is done, I use Audacity to record my voice over. I then edit the audio file by removing mistakes, unwanted noises and I normalize the volume. When I am satisfied, I export it as an MP3 and import it in to Camtasia. This is where the fun begins. I have to match the audio with the video. Sometimes I have to extend a frame and on other occasions I have to speed up the video. I seldom edit the audio once I have imported it. I know enough about how I recorded the video that I know when to pause and slow down during the recording of my voice over script. The final video production stage is to add annotations, call outs and zoom and transition effects so that it is clear what I am talking about and what I want the viewer to focus on. The final step is to upload to YouTube and set a date that I want to release it. When it comes to the release date, I post on Twitter, a number of iOS related YouTube groups, Reddit and LinkedIn and update my web site to point to the video. As you can see it is a lengthy, well thought out process and that is why I limit myself to one a week. It is not unusual for it to take 3 days to produce a 20 - 30 minute video. There are some downsides to this of course. My style is not for everyone. I have not had anyone tell me that the content is invalid, but I have had some comments about the lack of spontaneity and enthusiasm in my presentation style.</p>
<h4 id="how-am-i-doing">How Am I Doing?</h4>
<p>I posted my first video on Jan 12, 2020 on creating and using a Swift Package with Swift Package Manager. The feedback I was positive and encouraging but not many viewers. Still, I hung in there. By May, I had reached 500 subscribers. By July I hit 1000 and by November I was at 2000 subscribers. I am averaging somewhere between 200 - 250 new subscribers a month now. Today, as I write this blog I have reached the YouTube threshold of a minimum 4000 watch hours over a 12 month period that entitles me to add ads to my videos. I am still undecided here in that regard. It would be nice to make some revenue after all, but I don't believe I have the numbers to really make anything worthwhile.</p>
<p>I am aways surprised by what content gets the most feedback. Some topics I am really excited about turn out to be not very interesting to others. One video though that really took off was one where I took a concept that I saw Paul Hudson do on his HWS+ feed that converts an SVG to a UIBezier Path in SwiftUI and animates it. I extended that thought in a video. Another time, Mark Moeykens mentioned my name and channel in one of his videos and that resulted in a number of new subscribers. Now it is mostly word of mouth and the fact that I now have over 70 videos in the channel and that they are more discoverable in a Google search.</p>
<p>I once put out a survey asking what kind of videos people wanted to see based on my categories of Fundamentals, Techniques and software development tools. The lowest was for videos on software development tools, yet by far the two most viewed videos I have the ones about Raidrop.io and Typora. I guess I appeal to more than one segment of the YouTube population.</p>
<p>Anyway, that is where I am today. Can I call myself a YouTuber? I think probably yes, but I am still looking to increase my viewing audience as I believe that there are many people who would benefit from what I have to offer. You can find my channel at <a href="https://youtube.com/StewartLynch" target="_blank" rel="noreferrer">https://youTube.com/StewartLynch</a>and feel free to reach out to me on Twitter @StewartLynch. You can also visit my web site at <a href="https://www.createchsol.com/" target="_blank" rel="noreferrer">https://www.createchsol.com</a> to find out about my apps and other things about me. I would love to hear from you and get your feedback on how I am doing.</p>]]></content:encoded>
  </item>
  <item>
    <title>Can I call myself a Software Developer?</title>
    <link>https://www.createchsol.com/blog/2020-08-06-can-i-call-myself-a-software-developer.html</link>
    <guid isPermaLink="true">https://www.createchsol.com/blog/2020-08-06-can-i-call-myself-a-software-developer.html</guid>
    <pubDate>Thu, 06 Aug 2020 07:00:00 +0000</pubDate>
    <description>This is a question I struggle to answer. Am I worthy? I have been involved in IT for most of my working life, but my interest preceded that. You see, I am a bit of a dinosaur. I started university in 1969 when there was...</description>
                    <category>Musing</category>
                <category>Personal</category>
    <content:encoded><![CDATA[<p>This is a question I struggle to answer. Am I worthy? I have been involved in IT for most of my working life, but my interest preceded that. You see, I am a bit of a dinosaur. I started university in 1969 when there was no computer science department. Computer programming was part of the Math Department and I was studying for my BSc with a major in mathematics. I took every computer based course I could and learned how to code in FORTRAN and PL1 using punch cards and submitting my programs for batch processing on the IBM 360. It was frustrating and I certainly wouldn't call myself a programmer after that experience.</p>
<p>I ended up becoming a Math teacher and in 1980, an Apple II+ was introduced to my classroom. I started coding in BASIC, writing all sorts of little utilities that would help me explain concepts and give students a chance to build and review their skills. Still, I wasn't a 'software developer'. By 1986, computers were all throughout the school district but most teachers had no real idea what to do with them. I was seconded from the classroom to work with teachers and students to integrate the use of computers into the classroom. That ended my teaching career. For the next 20 years (with the exception of 3 years in hell as a High School Vice Principal), I worked my way up the chain in two different school districts, leaving in 2007 as the Director of Technology, responsible for IT in both the education and corporate sectors of one of the larger school districts in the Vancouver area.</p>
<p>During my career as an IT director, we purchased a very efficient and extremely flexible email/collaboration system that governed the way we communicated and shared information in our District. The software was flexible and customizable and allowed for the development of add-on tools that could enhance and extend the functionality of the product. I was in heaven. I got to develop all sorts of tools that allowed me to streamline the system administration and communicate with district SQL databases to give secure, real-time access to district data sources. Programming was a break from the endless, tedious meetings and I became quite competent. The district started marketing the tools I created and made a substantial profit from sales.</p>
<p>I began to establish a relationship with the software company and got certified as a trainer so I could share my skills with others all over the US and Canada. This brought in more money for the District. I became a very vocal supporter and evangelist of sorts for the software and eventually, they made me an offer that I couldn't refuse.</p>
<p>Not retiring, recareering!&lt;br&gt;I took the early retirement and went to work for this software company. But….. not as a 'software developer'. I was a "Senior Services Engineer". I did a fair amount of training, but also was able to continue developing tools as value-added products for our customers. Still…. it was made very clear to me that I was not a 'software developer'. I was a hacker. I was undisciplined and could never contribute to the core product. I was basically self taught and had a lot of very bad habits. If any of the real developers looked at my code, that would be very evident. Well, as often happens in the private sector, the division downsized and I was forced into another retirement.</p>
<p>A new beginning&lt;br&gt;Now what was I do do? This was 2014. What else happened in 2014? Swift, the new programming languge for iOS development was released. This fuelled my passion and set me in a new direction that consumes me to this day.</p>
<p>Like a lot of people, I started taking Udemy courses on how to develop apps for the iPhone using Swift. This got me started and I was able to launch my first app to the app store shortly afterwards, but in hindsight, I am not conviced that this was the best way to go.</p>
<p>A false start&lt;br&gt;The instructors advertised taking you from nowhere to being a full fledged iOS developer. Sure, I was able to create and publish an app on the App Store, but could I really call myself a software developer? These courses showed you how to create and utilize a lot of the APIs but lacked explanations. They did not follow best practice nor use recognized design patterns. My method for developing apps was basically copying code from someone else and substituting in my own values to fit my needs. I asked a lot of questions on Stack Overflow and accepted the abuse for asking questions that had already been answered. I lacked the ability to even frame a question correctly it seems. There was very little understanding of what I was actually doing. It worked, but when I had to go back to those apps a couple of years later to update and enhance, I had a really difficult time understanding and replicating what I did. There was a lot of redundant code and work arounds to get things working.</p>
<p>There is no easy route to being a software developer&lt;br&gt;That is when I decided that I needed to be more methodical in my learning and go back to square one. I wasn't able to attend any boot camps so I decided to invest my money in purchasing highly recommended resources that could teach me the right way to code and to be able to develop software that could stand the test of time. This also meant dedicating a lot of time reading, following tutorials and practising what I learned.</p>
<p>An ongoing adventure&lt;br&gt;My adventure continues. I have just published my 9th iPhone app. Three of these apps have Apple Watch companion applications. I learned how to use Swift to develop Mac apps and one of my iPhone apps has a Mac version on the Mac app store, I also studied Kotlin and recreated my first iPhone app as an Android app and published it on the Google Play Store.</p>
<p>Recommended Resources&lt;br&gt;So who did I rely on to reroute my learning? There are lots of good resources out there, but there are several that I would like to acknowledge as giving me ongoing inspiration and encouragement.</p>
<p>Ray Wendrerlich (https://www.raywenderlich.com/, @rwenderlich)&lt;br&gt;The resources and instructors available at raywenderlich.com are outstanding. I have purchased just about every book they have published and am an annual video subscriber. I look forward each week to see what new tutorials are published. I started with the Swift and iOS Apprentice books which provided me with a solid grounding in best practices.</p>
<p>Hacking with Swift (https://www.hackingwithswift.com/, @twoStraws)&lt;br&gt;Paul Hudson is a machine. Every one of his publications is so well laid out and presented, that I have to discipline myself to continue through to the end of each publication for fear of missing some key point. Again, I have purchased almost all of his books and it is just a matter of time before I purchase the remaining ones. He is a Swift Conference rock star and his presentation style is without compare.</p>
<p>YouTubers&lt;br&gt;There are a lot of YouTube series available as well that deserve mention. More than I have space for. There are three in particular that I would like to point out.</p>
<p>Mark Moeykens - Big Mountain Studio @bigmtnstudio&lt;br&gt;Mark has a special way of presenting material and is inspiring. He has a sense of design that appeals to me and if you look at my more recent apps you will definitely see his influence. I have appreciated his contributions so much that I have become a patron of his on Patreon.</p>
<p>Sean Allen - @seanallen_dev&lt;br&gt;Sean is another inspiring developer. He went from no programming experience to a full time developer in a very short period of time after enrolling in a developer Boot Camp. He shares his experience on his YouTube Channel and his weekly news updates on everything Swift. He has combined with Paul Hudson to present the Swift Over Coffee podcast. Sean is a breath of fresh air. He is not judgemental and always willing to offer assistance.</p>
<p>Code With Chris - @CodeWithChris&lt;br&gt;Chris is a long time YouTuber with an excellent set of YouTube videos. He also has a great FaceBook page where people can ask and answer questions. Perfect for the developer who is just starting out.</p>
<p>Twitter&lt;br&gt;Twitter is how I start my day. I have created my own twitter list of 70 individuals who live and breath iOS/Swift development. Every day the latest news and resources are highlighted and referenced in tweets. It is a fantastic resource. In addition to the above twitter accounts that I have already referenced, there are many more worth following. Here are just a few of the best: @swiftbysundell, @hanning_thomas, @DigitalLeaves, @objcio, @NatashaTheRobot, @johnsundell, @abargh, @ayabibagib, @mennenia, @davedelong, @harlanhaskinsm @subdigital, @erucasadun, @bendodson</p>
<p>Newsletters&lt;br&gt;I subscribe to several newsletters that publish weekly Swift updates and links to resources. Here at just a few of them</p>
<p>IOS Dev Weekly&lt;br&gt;Indie iOS Focus Weekly&lt;br&gt;Swift Developments&lt;br&gt;Use Your Loaf&lt;br&gt;Swift Weekly&lt;br&gt;iOS Dev Nuggets&lt;br&gt;So. Am I a Software Developer?&lt;br&gt;The question I guess is still open. Does it really matter? I am 6X years old and still going strong. I have no desire to get a job as a software developer. My age is against me, though I think that I am as qualified now as a lot of junior developers. I don't need a job. I just need something to keep my brain working and provide me with a little extra income to pay for my vacations. Don't count us old folks out, but also don't for a minute think that just because we are senior citizens we don't have something to contribute.</p>
<p>I don't go to conferences or meetups because I have experienced age discrimination in the past and don't need the aggravation. I communicate with a lot of people via email or online chats. When my age is unknown, what I have to offer is given more attention and my questions are more likely to be considered.</p>
<p>Still, I feel incredibly blessed to be able to come up with an idea and create a tool that can be useful to me and others. It is a great community to be in. Maybe one day I will be a software developer.</p>]]></content:encoded>
  </item>
  </channel>
</rss>