<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Sagar Unagar's Blog]]></title><description><![CDATA[Sagar Unagar's Blog]]></description><link>https://www.sagarunagar.com/blog/tags/all</link><generator>GatsbyJS</generator><lastBuildDate>Sat, 28 Feb 2026 11:25:45 GMT</lastBuildDate><item><title><![CDATA[Mastering Geometry in SwiftUI - GeometryReader, GeometryProxy & onGeometryChange]]></title><description><![CDATA[SwiftUI's layout system is declarative, adaptive, and proposal-driven. Most of the time, stacks and spacers are enough. But the moment you…]]></description><link>https://www.sagarunagar.com/blog/geometry-in-swiftui/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/geometry-in-swiftui/</guid><pubDate>Sat, 28 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SwiftUI&apos;s layout system is declarative, adaptive, and proposal-driven. Most of the time, stacks and spacers are enough. But the moment you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Track scroll offset&lt;/li&gt;
&lt;li&gt;Build a collapsing header&lt;/li&gt;
&lt;li&gt;Implement parallax&lt;/li&gt;
&lt;li&gt;Create a fully custom layout&lt;/li&gt;
&lt;li&gt;React to safe area changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You enter the world of &lt;strong&gt;geometry&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Understanding geometry in SwiftUI isn&apos;t about memorizing APIs. It&apos;s about understanding how layout works and where geometry fits inside that system.&lt;/p&gt;
&lt;p&gt;In this article, we’ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How SwiftUI layout actually works&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryProxy&lt;/code&gt; (the core abstraction)&lt;/li&gt;
&lt;li&gt;Coordinate spaces&lt;/li&gt;
&lt;li&gt;Measuring child views with preferences&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;onGeometryChange&lt;/code&gt; (modern observation API)&lt;/li&gt;
&lt;li&gt;Geometry vs the &lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt; protocol&lt;/li&gt;
&lt;li&gt;Pitfalls and best practices&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a long-form, architectural deep dive — not just an API tour.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;How SwiftUI Layout Actually Works&lt;/h3&gt;
&lt;p&gt;SwiftUI layout follows a three-phase process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Parent proposes a size&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Child chooses a size&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parent places the child&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unlike Auto Layout, SwiftUI does not solve constraints. It negotiates size.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;World&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What happens internally?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VStack&lt;/code&gt; receives a size proposal from its parent.&lt;/li&gt;
&lt;li&gt;It proposes a width to each child.&lt;/li&gt;
&lt;li&gt;Each &lt;code class=&quot;language-text&quot;&gt;Text&lt;/code&gt; returns its ideal height.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VStack&lt;/code&gt; stacks them vertically and reports its own size upward.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Geometry APIs allow us to inspect the result of that negotiation.&lt;/p&gt;
&lt;p&gt;They do not control layout — they observe it.&lt;/p&gt;
&lt;p&gt;That distinction is critical.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; is the original way to access layout information in SwiftUI.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Width: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gives you a GeometryProxy, which contains information about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The view’s size&lt;/li&gt;
&lt;li&gt;Its frame in different coordinate spaces&lt;/li&gt;
&lt;li&gt;Safe area insets&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Important Behavior&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; expands to fill all available space.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADDUlEQVR42u2XTUgbQRTHB+q50GIUwYtKkk22Gtn4lcREkUiCptHSxFQqsVIQCioFL4ZCoQVbpfcW9GiSiofW1o+oxc9qKwZFCPXWnqxQPxIPTUzcj9eZTdpaT0r2INiFP+/tm/d+O7PD7M4glLyyFQpFb2Nj43xbW9uau9UdbGm5G+zq6gp6HnmCPT09ojweD451im1utzvY2upeczgcczRNP8UMWYqFrlvM5s3NjQ04ikb58P4+xKMxAJ4Hv9cLD9rb4WFnpyjijwwPA4AAidgRHB4cwM72Nv9xcRFqa2rWMOsqys3L615YWcFJkNiNhLnQt6/8Mcfx+J632O08TuKvZGSIIr7d6RTb4jjn+94eP7O8zEUT8cTs0hLIcnI6UK3O4N31vwaYDLD8+3GAiUkQ7XgAwl4/hJ73w5f+F6KIf+jz4zac824MhMkACFPTAFMz7M6QDwxa7SCyKZRvohoGQKNlBY2W2KSKcExbDlBR+a+YsmQbziH5fNJnw9g3FhQMIRulHo3pjAB6EyvoTcT+kYDjPIaclJDM/ZuTtGxEVwlGudyH7ARYbiBPZ4XTvTmDUjXsIWZUyRU+dJOi3koKbCgsnI6W6UmQkwToYJjln6U6AJ1RGqCNUgVSQ04TqIcqBQba1eqxWLlkQ/ai29IMmYvgeaimqBH8DkvSB+Lag5IKqCspnUcNNwrn0p5lAiytACvDzCM7TQekAIYJUKudk+YdpnpoYZgFdKu4WKJJ0UENTU8gm4qelWqlmORyr/Rr2UZRo5cFiNcy+cBeYKAh+QuQHqj8D0wfqLxsQ66XHqi8mMAIXstGeYEP1ZH9IQkaqlnBUIXt+ZSsqWbDmGHIzx9CZkrl+0E2jeoilqc1INDF5xKpAVURu4MZOqVyEOVmZXUv3LsP8GogLvT2cfCsjz+HOLHm5UBiqsUN2TJZBzkFXDPb7evrW1twhDfjCbwjPz6j4oIg1qyFQmCyWlfFU8DvcwqmP6m3Wj+4nM7PzU1Nq0SuE2o+5RPdcbk+1VksM1mZmY8xI5OQfgH+lINte3CyegAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;geometry reader important behaviour&quot; title=&quot;&quot; src=&quot;/static/b71afe109a9dd35d872700e01e0b5611/88c73/geometry-reader-important-behaviour.png&quot; srcset=&quot;/static/b71afe109a9dd35d872700e01e0b5611/772e8/geometry-reader-important-behaviour.png 200w,
/static/b71afe109a9dd35d872700e01e0b5611/88c73/geometry-reader-important-behaviour.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;The red view will take all vertical space.&lt;/p&gt;
&lt;p&gt;This happens because &lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; is itself a layout container.&lt;/p&gt;
&lt;p&gt;That’s why it’s powerful — and why it can be intrusive.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryProxy&lt;/code&gt; - The Core Abstraction&lt;/h3&gt;
&lt;p&gt;Both &lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;onGeometryChange&lt;/code&gt; expose the same type:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;GeometryProxy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the heart of SwiftUI geometry.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Think of &lt;code class=&quot;language-text&quot;&gt;GeometryProxy&lt;/code&gt; as a read-only snapshot of resolved layout information.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It does not control layout. It reflects it.&lt;/p&gt;
&lt;p&gt;Let’s examine its key APIs.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;size&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Returns the resolved size of the view during that layout pass.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Rectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADUklEQVR42u2XW0jTURzHz5zUW1CUEngpAiHEoheXrLlaysTNqbiYQ5n4EBGYRPbgsJvzWgpJrxZZXjIfVKjQDHXoUNmoDDXqqYdwsHQXaPf9z379ztGu9NBwD4Id+PI/l9/3w7n//39CNlJyRkZGS0mJZrq6utpqqDLYKisrbLW1tTZjg9FWX1/PZTQase4SbzMYDLaqKoNVq9VOZWZmmpBxYJNF9p3NVy6+ebsIXn+Arjld4AsEgUYBevsH4PyFi1BTe5mL5Z88HQJsAn8gBOsuD3xetVPzzCycUeRbkbWHHE5PqZubncYQCLnXHcKnj0tUECIUy7RUpaQYRHeLxVwsryvV8DYqBKnTsUrnzRNCOOALzZon4eDB5BqSLc/vuzfzBXreQ+TBOwoPl6LAnj3LAHdnXXBlYAmuDq5wsXyXxYMxAPcXKTxajsLjFdQHiHSZ7XBCIu0mqdnqYdFNH5BWiBBTFIgJgDTBxrMV1fmHWuGXGIxvpEBaICK+5oLULFkvSZOoR8UtfkjohEhCexQSbsNPYZm00d8k+kuMCL2JJjekHZf1k7STmlFRsx9IB/awDQHtEJuYB73iRg8C5QiUFI0kxBN4RFr8UtSEc3gHhLgAj8rLLMTkjR/wkEQ9loiLIu4AQYwTLMaJjklskXBRdpl+ADXPRNf9bBsI5BbbBhCbmKcZe9jggfRj8j4iUZZZtINeqHgOgn4kCvpRiE3oYd5zA27IkpweIni4LV6vlx09IRplpzS2tOkRnE4nFBYWTpOiouKpr14frxTwRmCXQixiHuZdW3dBQUHBNNFoNGM+n2/LPXS5OHCKlGnL4jNkBCqVSjMpLS2JC9DtdoNCoXhB1Gr1ZByGHPF4PJCbm9uHi1I04vf7eeVWgXI5bmzs4ehOAsq2OVAm+w/crkDVThuyKu5AlWp7AtmNLZOd6if46hvevLG3BGQvKalU2kvy8vL6HQ4Hr6SU8oBYxDzMa7fbIScnp5ukpKTUmc1mVhnEAIF9P8cgYdMTGh8fh+Rk/MbGtBd7+RoTBAIBGgqFIBwO/5OCwSD3WK1WyJXLF/hfwPf/FEyNuECvdOW6eb1ev8Ck49Jx6flzo07Py/qF8vLyOVyDiaSkpBvI2M9I3wCIDGaIIuwuYwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;geometry proxy size&quot; title=&quot;&quot; src=&quot;/static/eccc417a34fb156f168e2bdd0749bc59/88c73/geometry-proxy-size.png&quot; srcset=&quot;/static/eccc417a34fb156f168e2bdd0749bc59/772e8/geometry-proxy-size.png 200w,
/static/eccc417a34fb156f168e2bdd0749bc59/88c73/geometry-proxy-size.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;Here we’re building a responsive rectangle whose height is half its width.&lt;/p&gt;
&lt;p&gt;Important nuance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is not the proposed size.&lt;/li&gt;
&lt;li&gt;It is the size after negotiation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;frame(in:)&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;This is where things get powerful.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Returns a &lt;code class=&quot;language-text&quot;&gt;CGRect&lt;/code&gt; representing the view’s position in a specific coordinate space.&lt;/p&gt;
&lt;p&gt;Available coordinate spaces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.local&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.global&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.named(&quot;custom&quot;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; frame &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Y: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;frame&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACk0lEQVR42u2XS2taQRTHB9wXWpq4ce0mn0CsDyQSiY8YIuil4QaXgVaEbpRCoYV+iiyjLlykgVJiLb6wtKIU6msV3AgKIj7Ad/Q6PWdUKGlTknYW0vbAn3vvPH5zZs6de88QsjC5Uql8bbfbE263OyseibnDw8c5j8eT8z/353w+H5Pf74eyp6xOFMXc0ZGYdTgc8a2trVfA2FiyyIOdnZ2vYHQ0GkntdhuuY4oWCoXo8fEx9Xq9THgfDodZ3WQyod1ul9brdSmdTlOj0ZgF1j2iUCiepVIp1qbZbM4KhYKEYHiWYCAJGkkymYwJ7202G6sbj8dSrVaTotHobDAYTGKxGN2Qy5+Q7e3tQLVapf1+f9pqtSiq1+sxL9DbYrFIy+UyE96jV2iSJNH5fM4ENgVPqVqtPiHgxVmlUqGXl5fTUqlE8/k8hZFZp2XjGw3rEYxAHFyj0ZwSi8VyPhwOWeF1wKrD9/pZG+zb6XQQGCSwJuewBqzw2jRuZSsgLoVOpwsSq9X65iYPfwu4t7f3funhjAvQ4Tj4CBHmB4SgXCynzAcIQXnLERggB3ymPMPXRq/Xh2ENHVyAuMN2d3cTGOU4hygDsE1NJlMC1/CCBxC3HgDj3NawBUD4LiTJ/r6dW1AMBsM7fA9jvHaKVqsN8N/Lv/p8/Y1AzZoD2S/gP3AtgeZ/bcpm7kCzeT2Bi+zrUZDAr+9slX39CRB/UpBwnmIGG2w0Gj+kc7fVKuHEDFalUp2wHDuZTGLhGBrMMNu9g2bLPpNIJELlmGOD3Qcvv4CxUwBm91dXV7cSJO6sTzabpVqdLsNOAatzCthLCNAHp8v5WRCEDMrJ5GQS2HVRJrBnIeNyuT5BDKKbm5svgPEQSd8AhNNTZ6w4XNQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;geometry proxy frame&quot; title=&quot;&quot; src=&quot;/static/f12c9a9e0a8f3aaf45cdcc22f5e18264/88c73/geometry-proxy-frame.png&quot; srcset=&quot;/static/f12c9a9e0a8f3aaf45cdcc22f5e18264/772e8/geometry-proxy-frame.png 200w,
/static/f12c9a9e0a8f3aaf45cdcc22f5e18264/88c73/geometry-proxy-frame.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;This enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scroll offset detection&lt;/li&gt;
&lt;li&gt;Sticky headers&lt;/li&gt;
&lt;li&gt;Parallax animations&lt;/li&gt;
&lt;li&gt;Visibility detection&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;safeAreaInsets&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;safeAreaInsets&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Returns safe area values at that layout location.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Top inset: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;safeAreaInsets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACn0lEQVR42u2XS2saURSAL7gvtDRxI7hzk18g1geiJMRniKBDg5LuhFYC2SiFQgv9FVlGXbhIA6XEWkxESysjQlFicKOrBBTULDTROJPbc64j2NLmQe9C2h44zMx9fHMec+89Q8hE1Dqd7q3X6z3afLYpBkPB0sbG01IkEinFXsZK0WiUaSwWg7YXrC8YDJZCoaDo8/kOl5aW3gBjQWGRR8vLy99A6OXlpdztdvFKUZLJJA2Hw3Rra4sp3qdSKdY3Go3o+fk5PTs7kwuFArXb7SKwHhCtVrudz+fZmHa7LQFYRjA8y6urqzIMklUqFVO8d7vdrG84HMqnp6dyJpORBoPBKJvN0gW1+jmxWq3xZrOJVo3xjf1+n6KVqI1Gg5bLZVqr1ejx8TGtVqvMKhRZlun19TVTkDFYSg0Gww4Bd/cqlQoF6Lher+OVnpycsMkIwhegKBN/EGxDMALRAKPRuEucTuf+xcUFa/zVJJwwqz+PmVrY6/UQmCAQk32IAWucdWPGnRtlCsRQmM3mBHG5XO9usvDeQI/H81GxUOIC9PnWPyuB5wOEpBwoLvMBQlLecwTGyToflyX8bCwWSwpi6OMC7HQ6FJbqEWb5kEOWAdilKysrRxjDAx5AXHoAPOQWww4AYV/IkbU1L7ekwM71Ab/DLK+VYjKZ4vzX8m3b198GNM45kB0B/4FzCXT8ay47uAMdjvkETqqvJwkCR9/etPr6EyAeUlBw7hKbzZZotVq/Ledu02nBiRWsXq/fIRqNZjuXy2HjEAZIWGPeQyVlziidTlM11tggD8HKMtbSWKxjdX91dXUnhcKdzRFFkZrM5iL7C5j+p4C8hgR98gf8XwVBKKL6mfqZCuw6aRPYs1AMBAJfIAeZxcXFV8B4jKTvw71R4cveje4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;geometry proxy safeAreaInsets&quot; title=&quot;&quot; src=&quot;/static/d590021408c3090630666b1b2860e8b0/88c73/geometry-proxy-safeAreaInsets.png&quot; srcset=&quot;/static/d590021408c3090630666b1b2860e8b0/772e8/geometry-proxy-safeAreaInsets.png 200w,
/static/d590021408c3090630666b1b2860e8b0/88c73/geometry-proxy-safeAreaInsets.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;Useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Custom navigation bars&lt;/li&gt;
&lt;li&gt;Full-screen backgrounds&lt;/li&gt;
&lt;li&gt;Keyboard-aware layouts&lt;/li&gt;
&lt;li&gt;Dynamic island spacing&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Coordinate Spaces Explained&lt;/h3&gt;
&lt;p&gt;Understanding coordinate spaces is essential.&lt;/p&gt;
&lt;p&gt;SwiftUI supports three types.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;.local&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;local&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Coordinates relative to the &lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;.global&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Coordinates relative to the entire screen.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;language-text&quot;&gt;.named(&quot;custom&quot;)&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;You can define custom spaces.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ScrollView&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; frame &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;named&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scroll&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Offset: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;frame&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;coordinateSpace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scroll&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;GeometryProxy namespace&quot; style=&quot;max-height: 512px;&quot;&gt;
    &lt;source src=&quot;/static/b98141f050c559f7ec1e5e94406c566f/geometry-proxy-namespace.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;Named spaces are ideal for scroll-based effects.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Measuring Child Views with Preferences&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; measures its own container.&lt;/p&gt;
&lt;p&gt;But what if you need to measure a child view?&lt;/p&gt;
&lt;p&gt;This is where &lt;code class=&quot;language-text&quot;&gt;PreferenceKey&lt;/code&gt; comes in.&lt;/p&gt;
&lt;h4&gt;Step 1: Define a PreferenceKey&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SizePreferenceKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PreferenceKey&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero

    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;inout&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nextValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nextValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Step 2: Attach Geometry in Background&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Measure me&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;GeometryReader&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clear
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preference&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SizePreferenceKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                            value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Step 3: Observe Changes&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onPreferenceChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SizePreferenceKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; size &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Size:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This pattern is foundational for advanced layout techniques.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt; - The Modern Way&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; participates in layout.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt; does not.&lt;/p&gt;
&lt;p&gt;It allows you to observe geometry changes without wrapping your view.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;GeometryChangeExample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Measure me&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onGeometryChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; newSize &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newSize
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;API breakdown:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onGeometryChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// extract value&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// react to change&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why this matters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No layout expansion&lt;/li&gt;
&lt;li&gt;Cleaner code&lt;/li&gt;
&lt;li&gt;More declarative&lt;/li&gt;
&lt;li&gt;Safer state updates&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Scroll Offset Example (Modern Approach)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ModernScrollOffset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; offset&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;ScrollView&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Header&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;largeTitle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offset &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onGeometryChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; proxy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                        proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minY
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                        offset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; index &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Row &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxWidth&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;infinity&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;GeometryProxy namespace&quot; style=&quot;max-height: 512px;&quot;&gt;
    &lt;source src=&quot;/static/f30b06295cabbadc5660c82bcd671eeb/scroll-offset-example-output.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;Notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No container view&lt;/li&gt;
&lt;li&gt;No unexpected layout behavior&lt;/li&gt;
&lt;li&gt;Pure observation&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; vs &lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt;&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Participates in layout&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expands to fill space&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom layout logic&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pure observation&lt;/td&gt;
&lt;td&gt;Not ideal&lt;/td&gt;
&lt;td&gt;Ideal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modern direction&lt;/td&gt;
&lt;td&gt;Legacy-heavy&lt;/td&gt;
&lt;td&gt;Preferred&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Rule of thumb:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; when building layout.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt; when observing layout.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Geometry vs the &lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt; Protocol&lt;/h3&gt;
&lt;p&gt;Since iOS 16, SwiftUI provides the Layout protocol for custom layout containers.&lt;/p&gt;
&lt;p&gt;Instead of geometry hacks, you can write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EqualWidthLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Layout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;sizeThatFits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;proposal&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProposedViewSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                      subviews&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subviews&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                      cache&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;inout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proposal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; subviews
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;map &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token short-argument&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sizeThatFits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;unspecified&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;placeSubviews&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                       proposal&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProposedViewSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                       subviews&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subviews&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                       cache&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;inout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minY

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; subview &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; subviews &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; subview&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sizeThatFits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;unspecified&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

            subview&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;place&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                at&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                proposal&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProposedViewSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                           height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

            y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LayoutTestView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;EqualWidthLayout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Short&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;This is a much longer piece of text&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;green&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Medium length&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;orange&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEMUlEQVR42uWX30+aVxjH38T7JVtWvfHaG/8CdBSziRB/YSuLkjUYL002Y7IbyZIlW7I/YVfNuouKXamdzrZCaVBaqaUQAy2lRgXEKig4AZXf749nz3MAw5w61nCxZSf55rznfc/5nHOec85znpfjSqmppaXlh4GBgaXR0VGXfkTvvnHjC/f4+Ljb8I3BPTk5yWQwGPDdV+ybXq93j4zoXVqtdrG1tfV7ZFwps7iPVCqVFxPk83kxmUxSDpSmp6dhbGwMJiYmmOjZZDKxb4VCAVKpFESjUXF5eRmUSqULWR9wzc3NX9vtdlYnHo8LHo9HzOVyIpZF7EjESmJDQwMTPff397Nv1HkkEhGtVquQyWQKNpsNrjQ1fckheQpBBORFUWS9S5LE8kQiAT6fD/x+PxM906goUV2qV67L40ihvb39Jtfb2/sr9sBeVkC1JqpfHgRPncvl8tsEnMtms+cCKw2qdV4daku2R6CRQ5tcCKx1lNSWTKFQKIxcX1/fbF2BGo3mcdmGQl2AWu2gI51O1w+Ii2IuT7k+QFyUB3UETnGD9ZmyQNumo6PDhDbU1gV4eHgI3d3dS7TKi3VYZQZUq9VLZENzpmxDkc7mewLp6CFwkRvUaBzpaATNmhekzDFA9gTgpHZJx8fky4TDcBhUSqWd+7xb7VgPxsGxB8KzdxI4diTIFqlXPMdlb3KRgPKScxCS+/vwqVz+iLve9ZntVTAFt5x7wo/m12Dy5SDDs8nUNP3TbXNwAFfb26c4rapz1hs4gLuBAv+LPwn3N3MQzRbhiC9AoliAJF+EZBF1Wi4phR4bpCog+lRFW5uRu67smnu7vQUPdt38b5vP4WHYCebwC3gUcqCwHMR8awUWQitg2XZi/hzmA0/BEV9HkxBQ/CtwbXcL5ndX+LseM5j8j1FWmPYuwMzbJ2B8OQt3VufB5H0IMz4z3H9jAePqLDyL+XGf0ZzPAK91qec2AgHYiLziA7se2NxBvfNAKOKFtfAq+BP7EM6lIJRNohIsD2K+nT4C6bwp9yIwtrUBMfcM/3rhJwjZp2B7+Q6sW3+G/Zf3IJ0+qVj/8kWpAPtxyruhAPwedPJh7yLsvLFDxP8UQh4b7K054CidKV1K5VWv1lmgXCbDESqVc+noHm7OIi/imRbxGJIAT49AZQJmLpZEfoDn+dTODsjbZMbSJVVyDrwkCHQ//ln07hJJPF8aIZ5ldkldduv9U3/4nwH2/N+m3FN3YE/PvxNYir4+MXJ49b13fFgNpEsKA87bXGdnpzEWi51GsNLf3CNnVQk4KYKVyWQ3q2PsPFYQmGOpXUK5TcFisUATxdiYPsRRrmICCtYpui/iHVKL6G+B2rhcLriqUDjZX0DlPwXTd7hAT4aGh17odDonaYhpiEnH8tI7HSvrnMPDwyu4BtbGxsZvkfExkf4AWt0rsyjKAM8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;layout protocol example&quot; title=&quot;&quot; src=&quot;/static/73626ae90c4a3eea0f08c47a9da1c285/88c73/layout-protocol-example.png&quot; srcset=&quot;/static/73626ae90c4a3eea0f08c47a9da1c285/772e8/layout-protocol-example.png 200w,
/static/73626ae90c4a3eea0f08c47a9da1c285/88c73/layout-protocol-example.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;Modern SwiftUI encourages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Custom layout → &lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Geometry observation → &lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; → edge cases&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;Common Pitfalls&lt;/h3&gt;
&lt;h4&gt;Wrapping entire screens in &lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Leads to unintended expansion.&lt;/p&gt;
&lt;h4&gt;Creating layout feedback loops&lt;/h4&gt;
&lt;p&gt;If geometry updates state that affects layout, you can trigger infinite re-layout cycles.&lt;/p&gt;
&lt;p&gt;Be cautious with:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onGeometryChange &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code class=&quot;language-text&quot;&gt;size&lt;/code&gt; affects layout, you may cause continuous updates.&lt;/p&gt;
&lt;h4&gt;Using geometry when Spacer is enough&lt;/h4&gt;
&lt;p&gt;Stacks + Spacer solve most layout needs.&lt;/p&gt;
&lt;p&gt;Geometry is not the default tool.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;The Mental Model&lt;/h3&gt;
&lt;p&gt;Here’s the refined mental model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SwiftUI describes layout declaratively.&lt;/li&gt;
&lt;li&gt;Layout negotiation happens internally.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryProxy&lt;/code&gt; gives you a snapshot of the result.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryReader&lt;/code&gt; embeds geometry into layout.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.onGeometryChange&lt;/code&gt; observes layout changes.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt; customizes layout behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Geometry is not about controlling layout.&lt;/p&gt;
&lt;p&gt;It’s about understanding it.&lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;Final Thoughts&lt;/h1&gt;
&lt;p&gt;Most SwiftUI layout bugs don’t come from SwiftUI.&lt;/p&gt;
&lt;p&gt;They come from misunderstanding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Size proposals&lt;/li&gt;
&lt;li&gt;Coordinate spaces&lt;/li&gt;
&lt;li&gt;When geometry is resolved&lt;/li&gt;
&lt;li&gt;How state interacts with layout&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you internalize:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proposal-based layout&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GeometryProxy&lt;/code&gt; as read-only snapshot&lt;/li&gt;
&lt;li&gt;Observation vs participation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You stop fighting SwiftUI — and start working with it.&lt;/p&gt;
&lt;p&gt;Geometry in SwiftUI is powerful.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions, feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support my work, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt; ☕️&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Static vs Dynamic Dispatch in Swift - How Method Dispatch Really Works]]></title><description><![CDATA[Method dispatch is one of those low-level Swift concepts that quietly influences performance, architecture, and API design. Although most…]]></description><link>https://www.sagarunagar.com/blog/static-vs-dynamic-dispatch-swift/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/static-vs-dynamic-dispatch-swift/</guid><pubDate>Sat, 21 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Method dispatch is one of those low-level Swift concepts that quietly influences performance, architecture, and API design. Although most apps function perfectly without thinking about dispatch, understanding how Swift decides which method implementation to call helps you write more predictable, efficient, and maintainable code—especially when building frameworks, reusable components, or performance-sensitive features.&lt;/p&gt;
&lt;p&gt;This article explains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What dispatch means in Swift&lt;/li&gt;
&lt;li&gt;The difference between &lt;strong&gt;static dispatch&lt;/strong&gt; and &lt;strong&gt;dynamic dispatch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;How structs, classes, protocols, and generics influence dispatch&lt;/li&gt;
&lt;li&gt;How Swift decides which dispatch mechanism to use&lt;/li&gt;
&lt;li&gt;Practical guidelines for designing APIs with dispatch in mind&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal is not to optimize prematurely, but to build a correct mental model of how Swift executes your code.&lt;/p&gt;
&lt;h3&gt;What Is Dispatch in Swift?&lt;/h3&gt;
&lt;p&gt;In Swift, dispatch refers to how the compiler and runtime determine &lt;strong&gt;which function implementation to execute&lt;/strong&gt; when a method is called.&lt;/p&gt;
&lt;p&gt;Consider this example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; greeter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At the call site (&lt;code class=&quot;language-text&quot;&gt;greeter.greet()&lt;/code&gt;), Swift must decide which concrete &lt;code class=&quot;language-text&quot;&gt;greet()&lt;/code&gt; implementation to run. That decision can be made in two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;At compile time → Static dispatch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;At runtime → Dynamic dispatch&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Understanding when each happens is key to understanding Swift’s performance and abstraction model.&lt;/p&gt;
&lt;h3&gt;Static Dispatch&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Static dispatch&lt;/strong&gt; means the compiler knows the exact method implementation at compile time and generates a direct call to that function. There is no runtime lookup.&lt;/p&gt;
&lt;h4&gt;Static Dispatch with Value Types&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        value &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; counter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code class=&quot;language-text&quot;&gt;Counter&lt;/code&gt; is a value type and cannot be subclassed, Swift knows exactly which &lt;code class=&quot;language-text&quot;&gt;increment(_:)&lt;/code&gt; method to call. The compiler can inline and optimize the call aggressively.&lt;/p&gt;
&lt;p&gt;This is one reason Swift encourages the use of structs and enums for modeling data and behavior.&lt;/p&gt;
&lt;h4&gt;Static Dispatch with &lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; Classes&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Marking a class as &lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; tells the compiler that the method cannot be overridden. This allows Swift to use static dispatch even for class methods.&lt;/p&gt;
&lt;h4&gt;Benefits of Static Dispatch&lt;/h4&gt;
&lt;p&gt;Static dispatch enables the compiler to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inline method calls&lt;/li&gt;
&lt;li&gt;Remove abstraction overhead&lt;/li&gt;
&lt;li&gt;Perform cross-function optimizations&lt;/li&gt;
&lt;li&gt;Reduce binary size&lt;/li&gt;
&lt;li&gt;Improve performance in hot paths&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In many cases, the call disappears entirely after optimization.&lt;/p&gt;
&lt;h3&gt;Dynamic Dispatch&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Dynamic dispatch&lt;/strong&gt; means the method implementation is chosen at &lt;strong&gt;runtime&lt;/strong&gt; based on the actual type of the instance. This is required when Swift cannot know the concrete implementation at compile time.&lt;/p&gt;
&lt;p&gt;Dynamic dispatch enables polymorphism but introduces runtime overhead.&lt;/p&gt;
&lt;h4&gt;Dynamic Dispatch with Class Inheritance&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Woof&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; animal&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;animal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Woof&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The static type is &lt;code class=&quot;language-text&quot;&gt;Animal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The runtime type is &lt;code class=&quot;language-text&quot;&gt;Dog&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Swift must determine the correct method implementation at runtime.&lt;/p&gt;
&lt;p&gt;This uses Swift’s class dispatch mechanism (virtual method tables).&lt;/p&gt;
&lt;h4&gt;Dynamic Dispatch with Protocol Existentials&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DiskStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Saved to disk&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DiskStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Saved to disk&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When a protocol is used as a type, Swift erases the concrete type information.&lt;/p&gt;
&lt;p&gt;The method call is resolved at runtime using a lookup mechanism.&lt;/p&gt;
&lt;p&gt;This flexibility allows you to write abstraction-oriented code, but comes with a small runtime cost.&lt;/p&gt;
&lt;h3&gt;Protocols, Generics, and Dispatch&lt;/h3&gt;
&lt;p&gt;Protocols in Swift can participate in either static or dynamic dispatch depending on how they are used.&lt;/p&gt;
&lt;h4&gt;Protocols as Generic Constraints (Static Dispatch)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; greeter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Because the compiler specializes this function for each concrete type, method calls are statically dispatched. This allows the compiler to inline and optimize aggressively.&lt;/p&gt;
&lt;h4&gt;Protocols as Types (Dynamic Dispatch)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; greeter&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; any &lt;span class=&quot;token class-name&quot;&gt;Greeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;EnglishGreeter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Hello&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, the concrete type is erased. Swift must perform runtime lookup to determine which implementation to call.&lt;/p&gt;
&lt;h3&gt;How &lt;code class=&quot;language-text&quot;&gt;@objc&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;dynamic&lt;/code&gt; Change Dispatch&lt;/h3&gt;
&lt;p&gt;When you mark methods with &lt;code class=&quot;language-text&quot;&gt;@objc&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;dynamic&lt;/code&gt;, Swift opts into Objective-C runtime dispatch:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NSObject&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@objc&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Playing&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; player &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
player&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;Playing&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This uses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Objective-C message sending&lt;/li&gt;
&lt;li&gt;Runtime method lookup&lt;/li&gt;
&lt;li&gt;KVO compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is &lt;strong&gt;slower than Swift v-table dispatch&lt;/strong&gt; and should be used only when you need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KVO&lt;/li&gt;
&lt;li&gt;Method swizzling&lt;/li&gt;
&lt;li&gt;Objective-C interoperability&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Dispatch Behavior Summary&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Dispatch Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generic constraint (&lt;code class=&quot;language-text&quot;&gt;&amp;lt;T: P&gt;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Static dispatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol as a type (&lt;code class=&quot;language-text&quot;&gt;P&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Dynamic dispatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Struct / enum methods&lt;/td&gt;
&lt;td&gt;Static dispatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final class methods&lt;/td&gt;
&lt;td&gt;Static dispatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overridable class methods&lt;/td&gt;
&lt;td&gt;Dynamic dispatch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;How Swift Chooses Which Dispatch to Use&lt;/h3&gt;
&lt;p&gt;Swift follows a few general rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the method cannot be overridden, Swift prefers static dispatch&lt;/li&gt;
&lt;li&gt;If the method can be overridden, Swift uses dynamic dispatch&lt;/li&gt;
&lt;li&gt;If type information is erased (protocol existentials), Swift uses dynamic dispatch&lt;/li&gt;
&lt;li&gt;If the compiler can specialize the call (generics), Swift prefers static dispatch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Swift is designed to favor static dispatch whenever it is safe to do so.&lt;/p&gt;
&lt;h3&gt;Practical Design Guidelines&lt;/h3&gt;
&lt;h4&gt;Prefer Static Dispatch When&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Writing performance-sensitive code&lt;/li&gt;
&lt;li&gt;Implementing algorithms and transformations&lt;/li&gt;
&lt;li&gt;Designing libraries and reusable components&lt;/li&gt;
&lt;li&gt;Working inside tight loops&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prefer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Structs and enums&lt;/li&gt;
&lt;li&gt;Generics&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; classes when subclassing is not intended&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Prefer Dynamic Dispatch When&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Modeling polymorphic domain behavior&lt;/li&gt;
&lt;li&gt;Designing plugin-style systems&lt;/li&gt;
&lt;li&gt;Abstracting over multiple runtime implementations&lt;/li&gt;
&lt;li&gt;Building dependency injection boundaries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dynamic dispatch improves flexibility and architecture clarity.&lt;/p&gt;
&lt;h3&gt;Common Misconceptions&lt;/h3&gt;
&lt;h4&gt;&quot;Swift always uses static dispatch&quot;&lt;/h4&gt;
&lt;p&gt;Swift prefers static dispatch, but falls back to dynamic dispatch when runtime polymorphism is required.&lt;/p&gt;
&lt;h4&gt;“Dynamic dispatch is slow and should be avoided”&lt;/h4&gt;
&lt;p&gt;Dynamic dispatch is slightly slower than static dispatch, but the cost is usually negligible in real applications. Architecture clarity often matters more than micro-optimizations.&lt;/p&gt;
&lt;h4&gt;“Protocols are slow”&lt;/h4&gt;
&lt;p&gt;Protocols are only dynamically dispatched when used as types.&lt;/p&gt;
&lt;p&gt;Protocols used with generics are statically dispatched and highly optimized.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;Dispatch is a foundational concept in Swift’s performance and abstraction model.&lt;/p&gt;
&lt;p&gt;Understanding how and when Swift chooses static versus dynamic dispatch helps you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Design better APIs&lt;/li&gt;
&lt;li&gt;Avoid accidental performance costs&lt;/li&gt;
&lt;li&gt;Build more predictable architectures&lt;/li&gt;
&lt;li&gt;Reason about optimization behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You don’t need to optimize every call site—but knowing how dispatch works lets you make intentional design choices instead of accidental ones.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions, feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support my work, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt; ☕️&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Copy-on-Write(CoW) in Swift - How It Works and Why It Optimizes Memory]]></title><description><![CDATA[Swift is designed around two core principles: safety and performance. At first glance, these goals often appear to conflict. Value types…]]></description><link>https://www.sagarunagar.com/blog/copy-on-write-swift/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/copy-on-write-swift/</guid><pubDate>Sat, 14 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Swift is designed around two core principles: &lt;strong&gt;safety&lt;/strong&gt; and &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;At first glance, these goals often appear to conflict. Value types provide safety and predictability, but copying large values repeatedly can be expensive. Reference types provide efficiency through shared storage, but they introduce shared mutable state.&lt;/p&gt;
&lt;p&gt;Swift solves this tension elegantly through a memory optimization technique called &lt;strong&gt;Copy-on-Write (CoW)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you’ve used &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Dictionary&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Set&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;String&lt;/code&gt;, you’ve already relied on Copy-on-Write — even if you didn’t realize it.&lt;/p&gt;
&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is Copy-on-Write&lt;/li&gt;
&lt;li&gt;Why Swift uses it&lt;/li&gt;
&lt;li&gt;How it works internally&lt;/li&gt;
&lt;li&gt;The role of &lt;code class=&quot;language-text&quot;&gt;isKnownUniquelyReferenced&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;How &lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt; preserves value semantics&lt;/li&gt;
&lt;li&gt;How to implement your own Copy-on-Write type&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What Is Copy-on-Write?&lt;/h3&gt;
&lt;p&gt;Copy-on-Write is a strategy where:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A value is only copied when a mutation occurs — not when it is assigned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This allows multiple variables to share the same underlying storage until one of them attempts to modify it.&lt;/p&gt;
&lt;p&gt;Instead of eagerly copying data during assignment, Swift delays copying until mutation is required.&lt;/p&gt;
&lt;p&gt;This achieves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Value semantics externally&lt;/li&gt;
&lt;li&gt;Shared storage internally&lt;/li&gt;
&lt;li&gt;Efficient memory usage&lt;/li&gt;
&lt;li&gt;Predictable behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Problem Copy-on-Write Solves&lt;/h3&gt;
&lt;p&gt;Consider this example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1_000_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; copy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; numbers&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If Swift eagerly copied one million integers during assignment, performance would suffer significantly.&lt;/p&gt;
&lt;p&gt;Instead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;numbers&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;copy&lt;/code&gt; share the same storage.&lt;/li&gt;
&lt;li&gt;No duplication happens yet.&lt;/li&gt;
&lt;li&gt;A copy is only created if one of them mutates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This lazy copying is the essence of Copy-on-Write.&lt;/p&gt;
&lt;h3&gt;Observing Copy-on-Write in Action&lt;/h3&gt;
&lt;h4&gt;Example 1 — Assignment Without Mutation&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this moment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt; share the same storage.&lt;/li&gt;
&lt;li&gt;No copy has been made.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example 2 — Mutation Triggers Copy&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now Swift performs a check:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is the underlying storage uniquely referenced?&lt;/li&gt;
&lt;li&gt;If not, create a copy before mutating.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Final result:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Value semantics are preserved, but copying only happens when necessary.&lt;/p&gt;
&lt;h3&gt;How Swift Knows When to Copy&lt;/h3&gt;
&lt;p&gt;Even though &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;struct&lt;/code&gt;, it stores its elements in a hidden reference-type buffer internally.&lt;/p&gt;
&lt;p&gt;Before mutating that buffer, Swift performs a runtime check:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token function&quot;&gt;isKnownUniquelyReferenced&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This function determines whether the underlying storage is exclusively owned.&lt;/p&gt;
&lt;h3&gt;Deep Dive: &lt;code class=&quot;language-text&quot;&gt;isKnownUniquelyReferenced&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The function signature is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;isKnownUniquelyReferenced&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;inout&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnyObject&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It returns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; → if exactly one strong reference exists&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt; → if multiple strong references exist&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In practical terms:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Is this storage exclusively owned?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If yes → mutate in place.&lt;/p&gt;
&lt;p&gt;If no → create a copy first.&lt;/p&gt;
&lt;h4&gt;Why the Parameter Is &lt;code class=&quot;language-text&quot;&gt;inout&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;You may wonder why the parameter is marked &lt;code class=&quot;language-text&quot;&gt;inout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is deliberate and essential.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Avoiding Temporary Retains&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the parameter were passed normally, Swift might temporarily increase the reference count while passing it into the function. That temporary retain would falsely indicate the object is not unique.&lt;/p&gt;
&lt;p&gt;Using &lt;code class=&quot;language-text&quot;&gt;inout&lt;/code&gt; prevents that extra reference increment and ensures the check reflects the true ARC count.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Enforcing Memory Exclusivity&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Swift enforces strict memory access rules. By requiring &lt;code class=&quot;language-text&quot;&gt;inout&lt;/code&gt;, the compiler guarantees exclusive access to the variable during the check.&lt;/p&gt;
&lt;p&gt;This prevents race conditions and overlapping access during mutation.&lt;/p&gt;
&lt;h4&gt;What “Known” Means&lt;/h4&gt;
&lt;p&gt;The name is precise:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;isKnownUniquelyReferenced&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It does not guarantee uniqueness under every conceivable concurrency scenario. It guarantees uniqueness when Swift can safely prove it under ARC and exclusivity rules.&lt;/p&gt;
&lt;p&gt;This is sufficient for implementing Copy-on-Write correctly in standard Swift usage.&lt;/p&gt;
&lt;h3&gt;Value Semantics Is Not Copy-on-Write&lt;/h3&gt;
&lt;p&gt;It is important to clarify a common misconception:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Value semantics is not the same as Copy-on-Write.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All structs in Swift have value semantics. That means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assignment creates a new value.&lt;/li&gt;
&lt;li&gt;Mutation does not affect the original instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, &lt;strong&gt;Copy-on-Write is not automatically applied to all structs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Copy-on-Write is a deliberate engineering decision made by the implementer of a type.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; uses Copy-on-Write.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Dictionary&lt;/code&gt; uses Copy-on-Write.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Set&lt;/code&gt; uses Copy-on-Write.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;String&lt;/code&gt; uses Copy-on-Write.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But a simple struct like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;does not use Copy-on-Write.&lt;/p&gt;
&lt;p&gt;When you assign &lt;code class=&quot;language-text&quot;&gt;Point&lt;/code&gt;, its stored properties are copied immediately because they are small and inexpensive.&lt;/p&gt;
&lt;h3&gt;Why Some Types Use Copy-on-Write&lt;/h3&gt;
&lt;p&gt;Copy-on-Write exists purely for performance optimization.&lt;/p&gt;
&lt;p&gt;It is applied when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The underlying storage is large&lt;/li&gt;
&lt;li&gt;Copying eagerly would be expensive&lt;/li&gt;
&lt;li&gt;Shared storage improves efficiency&lt;/li&gt;
&lt;li&gt;Value semantics must still be preserved&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Copy-on-Write is an optimization strategy, not a language rule.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The Architectural Distinction&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Value semantics&lt;/strong&gt; → language-level behavior&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copy-on-Write(CoW)&lt;/strong&gt; → storage optimization pattern&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ARC&lt;/strong&gt; → runtime mechanism enabling uniqueness checks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are related — but not identical.&lt;/p&gt;
&lt;p&gt;Understanding this distinction separates surface-level familiarity from architectural understanding of Swift’s design.&lt;/p&gt;
&lt;h3&gt;Implementing Copy-on-Write Manually&lt;/h3&gt;
&lt;p&gt;To understand the mechanism fully, let’s build our own CoW type.&lt;/p&gt;
&lt;h4&gt;Step 1 — Reference Storage&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use a &lt;code class=&quot;language-text&quot;&gt;final class&lt;/code&gt; because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Classes are reference types.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; avoids dynamic dispatch overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Step 2 — Struct Wrapper&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;storage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;ensureUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newValue
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Externally, &lt;code class=&quot;language-text&quot;&gt;Counter&lt;/code&gt; behaves like a value type.&lt;/p&gt;
&lt;p&gt;Internally, it shares reference storage.&lt;/p&gt;
&lt;h3&gt;The Critical Mutation Gate: &lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;mutating&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;ensureUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isKnownUniquelyReferenced&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;storage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            storage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This function guarantees:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Before mutation occurs, the struct owns its storage exclusively.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Why &lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt; Is &lt;code class=&quot;language-text&quot;&gt;mutating&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;If the storage is shared, we assign a new instance to &lt;code class=&quot;language-text&quot;&gt;storage&lt;/code&gt;. That modifies &lt;code class=&quot;language-text&quot;&gt;self&lt;/code&gt;, so the method must be marked &lt;code class=&quot;language-text&quot;&gt;mutating&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;What &lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt; Actually Does&lt;/h4&gt;
&lt;p&gt;It does not mutate the value directly.&lt;/p&gt;
&lt;p&gt;It only ensures that mutation can occur safely.&lt;/p&gt;
&lt;p&gt;Think of it as a safety checkpoint before modification.&lt;/p&gt;
&lt;h3&gt;Step-by-Step Execution Flow&lt;/h3&gt;
&lt;p&gt;Consider:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a

b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Step 1 — Assignment&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;a ──┐
    ├── &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b ──┘&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reference count = 2.&lt;/p&gt;
&lt;h4&gt;Step 2 — Mutation Begins&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;b.value = 20&lt;/code&gt; calls:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ensureUnique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Swift checks:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token function&quot;&gt;isKnownUniquelyReferenced&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;storage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result: &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Step 3 — Copy Created&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;storage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now each instance has its own storage.&lt;/p&gt;
&lt;h4&gt;Step 4 — Safe Mutation&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Final state:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token comment&quot;&gt;// 10&lt;/span&gt;
b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token comment&quot;&gt;// 20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Value semantics preserved.&lt;/p&gt;
&lt;h4&gt;Why This Pattern Is Essential&lt;/h4&gt;
&lt;p&gt;If you skipped &lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newValue&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You would accidentally mutate shared storage.&lt;/p&gt;
&lt;p&gt;Your struct would behave like a class.&lt;/p&gt;
&lt;p&gt;Value semantics would be broken silently.&lt;/p&gt;
&lt;p&gt;The uniqueness check is what guarantees correctness.&lt;/p&gt;
&lt;h4&gt;Performance Characteristics&lt;/h4&gt;
&lt;p&gt;The uniqueness check:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is O(1)&lt;/li&gt;
&lt;li&gt;Reads ARC metadata&lt;/li&gt;
&lt;li&gt;Does not allocate memory unless needed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Copy-on-Write performs best when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data is large&lt;/li&gt;
&lt;li&gt;Reads are frequent&lt;/li&gt;
&lt;li&gt;Mutations are relatively rare&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, repeated copying inside tight mutation loops can reduce performance.&lt;/p&gt;
&lt;p&gt;Understanding this helps you design more efficient systems.&lt;/p&gt;
&lt;h3&gt;Why Swift Uses Copy-on-Write&lt;/h3&gt;
&lt;p&gt;Copy-on-Write gives Swift the best of both worlds:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Struct + CoW&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Value semantics&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared storage&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Predictable behavior&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory efficiency&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Safer APIs&lt;/li&gt;
&lt;li&gt;Better SwiftUI data modeling&lt;/li&gt;
&lt;li&gt;Efficient large collections&lt;/li&gt;
&lt;li&gt;Scalable architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Key Design Principles for Custom CoW Types&lt;/h3&gt;
&lt;p&gt;When implementing Copy-on-Write:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use a &lt;code class=&quot;language-text&quot;&gt;final class&lt;/code&gt; for storage.&lt;/li&gt;
&lt;li&gt;Keep storage private.&lt;/li&gt;
&lt;li&gt;Gate every mutation behind ensureUnique().&lt;/li&gt;
&lt;li&gt;Never expose the reference storage directly.&lt;/li&gt;
&lt;li&gt;Ensure copying is deep enough to preserve isolation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These rules are non-negotiable.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;Copy-on-Write is not just a performance trick. It is a foundational design pattern in Swift.&lt;/p&gt;
&lt;p&gt;It allows Swift to deliver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Value semantics&lt;/li&gt;
&lt;li&gt;High performance&lt;/li&gt;
&lt;li&gt;Memory efficiency&lt;/li&gt;
&lt;li&gt;Predictable behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The partnership between:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;isKnownUniquelyReferenced&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ensureUnique()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ARC&lt;/li&gt;
&lt;li&gt;Struct wrappers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;is what makes Swift’s standard library both elegant and powerful.&lt;/p&gt;
&lt;p&gt;Mastering Copy-on-Write deepens your understanding of how Swift balances safety with efficiency — and equips you to design high-performance abstractions in your own code.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions, feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support my work, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt; ☕️&lt;/p&gt;</content:encoded></item><item><title><![CDATA[AsyncStream & AsyncThrowingStream in Swift - Real-Time Data Sync Explained]]></title><description><![CDATA[Modern apps are no longer single-device experiences. Users expect their data to stay perfectly in sync across iPhone, iPad, and Mac, with…]]></description><link>https://www.sagarunagar.com/blog/asyncstream-asyncthrowingstream-swift/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/asyncstream-asyncthrowingstream-swift/</guid><pubDate>Wed, 04 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Modern apps are no longer single-device experiences.&lt;/p&gt;
&lt;p&gt;Users expect their data to stay perfectly in sync across iPhone, iPad, and Mac, with updates appearing instantly—no refresh button, no manual sync. This expectation becomes even stronger in productivity apps like invoicing, accounting, or note-taking, where consistency and correctness matter.&lt;/p&gt;
&lt;p&gt;In my invocing app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, users can sign in on multiple devices and continue their work seamlessly. To support this, I needed a real-time data synchronization system that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reacts immediately to remote changes&lt;/li&gt;
&lt;li&gt;Integrates cleanly with Swift’s &lt;code class=&quot;language-text&quot;&gt;async/await&lt;/code&gt; model&lt;/li&gt;
&lt;li&gt;Cancels automatically when views disappear&lt;/li&gt;
&lt;li&gt;Avoids callback-heavy, hard-to-maintain code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To achieve this, I built the entire real-time sync layer using &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This article explains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;What is &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When to use each&lt;/li&gt;
&lt;li&gt;How they work internally&lt;/li&gt;
&lt;li&gt;And how I used them to implement real-time multi-device syncing in Reckord&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Problem with Callback-Based Real-Time APIs&lt;/h3&gt;
&lt;p&gt;Most real-time systems—including Firebase Firestore—are built around callbacks.&lt;/p&gt;
&lt;p&gt;A typical Firestore listener looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;listener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addSnapshotListener &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; snapshot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Called every time data changes&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While functional, this approach has drawbacks in modern SwiftUI apps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard to integrate with async/await&lt;/li&gt;
&lt;li&gt;Manual listener cleanup&lt;/li&gt;
&lt;li&gt;Complex cancellation logic&lt;/li&gt;
&lt;li&gt;Business logic scattered across closures&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What we want is something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; update &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; updates &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is exactly what &lt;code class=&quot;language-text&quot;&gt;AsyncSequence&lt;/code&gt; enables—and &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; is how we create one.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncSequence&lt;/code&gt;: The Foundation&lt;/h3&gt;
&lt;p&gt;Both &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; conform to &lt;code class=&quot;language-text&quot;&gt;AsyncSequence&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An &lt;code class=&quot;language-text&quot;&gt;AsyncSequence&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Produces multiple values over time&lt;/li&gt;
&lt;li&gt;Is consumed using &lt;code class=&quot;language-text&quot;&gt;for await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Integrates naturally with&lt;code class=&quot;language-text&quot;&gt;Task&lt;/code&gt; and SwiftUI lifecycles&lt;/li&gt;
&lt;li&gt;Supports structured cancellation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can think of it as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;async/await&lt;/code&gt; equivalent of a data stream.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;What is &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; is a Swift type that allows you to create an asynchronous sequence of values that are produced over time, rather than all at once.&lt;/p&gt;
&lt;p&gt;In simple terms:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; lets you manually feed values into an async &lt;code class=&quot;language-text&quot;&gt;for await&lt;/code&gt; loop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can find the official Apple documentation here: &lt;a href=&quot;https://developer.apple.com/documentation/swift/asyncstream&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AsyncStream&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Why &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; Exists&lt;/h4&gt;
&lt;p&gt;Before Swift Concurrency, when values arrived over time, we usually relied on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Closures&lt;/li&gt;
&lt;li&gt;Delegates&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Combine publishers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These approaches don’t integrate naturally with async/await.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; exists to bridge non-async, callback-based APIs into Swift’s structured concurrency world.&lt;/p&gt;
&lt;h4&gt;How &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; Works (Conceptually)&lt;/h4&gt;
&lt;p&gt;An &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; has two sides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Producer&lt;/strong&gt;:
This is where values are generated using a &lt;code class=&quot;language-text&quot;&gt;Continuation&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consumer&lt;/strong&gt;:
This is where values are consumed using &lt;code class=&quot;language-text&quot;&gt;for await&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The producer and consumer can live in completely different parts of your app.&lt;/p&gt;
&lt;h4&gt;Anatomy of &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AsyncStream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; continuation &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Element&lt;/code&gt; → type of values emitted&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;continuation.yield(_:)&lt;/code&gt; → sends a value to consumers&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;continuation.finish()&lt;/code&gt; → ends the stream&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once finished, no more values can be emitted.&lt;/p&gt;
&lt;h4&gt;A Very Simple Example&lt;/h4&gt;
&lt;p&gt;Let’s say you want to emit numbers over time.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;numberStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AsyncStream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;AsyncStream&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; continuation &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Consume it like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; number &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;numberStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is not a loop returning values — it’s a stream pushing values asynchronously.&lt;/p&gt;
&lt;h4&gt;Important Characteristics of &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Can emit multiple values&lt;/li&gt;
&lt;li&gt;Works naturally with &lt;code class=&quot;language-text&quot;&gt;async/await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cannot throw errors&lt;/li&gt;
&lt;li&gt;Must be manually finished&lt;/li&gt;
&lt;li&gt;Supports cancellation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because it cannot fail, &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; is best suited for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UI events&lt;/li&gt;
&lt;li&gt;Timers&lt;/li&gt;
&lt;li&gt;State changes&lt;/li&gt;
&lt;li&gt;In-memory signals&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What is &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; is the error-capable sibling of &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It represents an async sequence that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emits values over time&lt;/li&gt;
&lt;li&gt;Can fail with an error&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; + error handling.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can find the official Apple documentation here: &lt;a href=&quot;https://developer.apple.com/documentation/swift/asyncthrowingstream&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AsyncThrowingStream&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Why &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; Exists&lt;/h4&gt;
&lt;p&gt;Most real-world asynchronous systems can fail:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Network requests&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;File IO&lt;/li&gt;
&lt;li&gt;Permissions&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; for such systems would mean:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Errors must be hidden&lt;/li&gt;
&lt;li&gt;Or sent as values (bad idea)&lt;/li&gt;
&lt;li&gt;Or handled outside the stream (messy)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; solves this cleanly.&lt;/p&gt;
&lt;h4&gt;Anatomy of &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AsyncThrowingStream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; continuation &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;throwing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Key differences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can call &lt;code class=&quot;language-text&quot;&gt;finish(throwing:)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Consumers must use &lt;code class=&quot;language-text&quot;&gt;for try await&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Simple Example with Errors&lt;/h4&gt;
&lt;p&gt;Imagine a stream that emits random numbers but fails sometimes.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RandomError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; unlucky
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;randomNumberStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AsyncThrowingStream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;AsyncThrowingStream&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; continuation &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;throwing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RandomError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;unlucky&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Consume it like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; number &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomNumberStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Stream failed:&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Stream&lt;/span&gt; failed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unlucky&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It generates random numbers between 1 and 10 and prints them. If the generated number is 7, it stops generating numbers and throws an error.&lt;/p&gt;
&lt;h4&gt;Key Characteristics of &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Emits multiple values&lt;/li&gt;
&lt;li&gt;Can terminate with an error&lt;/li&gt;
&lt;li&gt;Natural error propagation&lt;/li&gt;
&lt;li&gt;Structured cancellation&lt;/li&gt;
&lt;li&gt;Ideal for networked systems&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes it perfect for real-time databases like Firestore.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; vs &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; (Mental Model)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;AsyncStream&lt;/th&gt;
&lt;th&gt;AsyncThrowingStream&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Can this operation fail?&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Needs &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; to consume?&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI / in-memory events&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network / database&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you’re unsure, ask yourself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Can this realistically fail at runtime?&lt;/em&gt;&lt;br&gt;
If yes → use &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;How I Implemented Real-Time Multi-Device Sync in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In Reckord, users can sign in on multiple devices and expect their data to stay perfectly in sync.&lt;/p&gt;
&lt;p&gt;This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any change on one device&lt;/li&gt;
&lt;li&gt;Must instantly appear on all other devices&lt;/li&gt;
&lt;li&gt;Without refresh, polling, or manual sync&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Firestore already provides real-time updates via snapshot listeners, but those APIs are callback-based.&lt;/p&gt;
&lt;p&gt;My goal was to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convert Firestore listeners into &lt;code class=&quot;language-text&quot;&gt;async/await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Automatically manage lifecycle and cancellation&lt;/li&gt;
&lt;li&gt;Keep UI code clean and predictable&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Step 1: Model Firestore as an &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Firestore snapshot listeners:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emit initial data&lt;/li&gt;
&lt;li&gt;Emit updates continuously&lt;/li&gt;
&lt;li&gt;Can fail&lt;/li&gt;
&lt;li&gt;Must be removed manually&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That maps exactly to &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;invoicesStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AsyncThrowingStream&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;AsyncThrowingStream&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; continuation &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; listener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firestore
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;invoices&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whereField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isEqualTo&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addSnapshotListener &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; snapshot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;throwing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; snapshot &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
                    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;throwing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FirestoreServiceError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invalidPath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; 
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invoices&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; document &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; snapshot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;documents &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; parsedInvoice &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FirestoreParser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Invoice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        invoices&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parsedInvoice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;yield&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;invoices&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;throwing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FirestoreServiceError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parseError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        continuation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onTermination &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            listener&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This single function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Turns Firestore into an async sequence&lt;/li&gt;
&lt;li&gt;Handles real-time updates&lt;/li&gt;
&lt;li&gt;Cleans up listeners automatically&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Step 2: Consume the Stream in SwiftUI&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@MainActor&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;observeInvoices&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; invoices &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;invoicesStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invoices &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; invoices
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errorMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;localizedDescription
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And attach it to the view lifecycle:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;task &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;observeInvoices&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Step 3: Automatic Multi-Device Sync&lt;/h4&gt;
&lt;p&gt;Now the flow looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Device A updates data&lt;/li&gt;
&lt;li&gt;Firestore emits a snapshot update&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; yields new values&lt;/li&gt;
&lt;li&gt;Device B receives changes instantly&lt;/li&gt;
&lt;li&gt;SwiftUI view updates automatically&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No polling.&lt;br&gt;
No manual refresh.&lt;br&gt;
No Combine.&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Just structured concurrency.&lt;/p&gt;
&lt;h3&gt;Where &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; Fits in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While Firestore uses &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt;, I use &lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; internally for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authentication status changes&lt;/li&gt;
&lt;li&gt;Subscription state changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This keeps error handling where it belongs and avoids overusing throwing streams.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AsyncStream&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;AsyncThrowingStream&lt;/code&gt; are foundational tools for modern Swift development.&lt;/p&gt;
&lt;p&gt;They allow you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Model real-time systems cleanly&lt;/li&gt;
&lt;li&gt;Embrace structured concurrency&lt;/li&gt;
&lt;li&gt;Write predictable, maintainable code&lt;/li&gt;
&lt;li&gt;Build true multi-device experiences&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They form the backbone of &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Reckord&lt;/a&gt;
’s real-time sync system—and once you adopt them, callback-heavy designs start to feel outdated.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions, feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support my work, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt; ☕️&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Designing a Scalable App-Wide Theming System in SwiftUI]]></title><description><![CDATA[Theming is one of those features users notice instantly — and one of the easiest places to introduce inconsistency if it’s not designed…]]></description><link>https://www.sagarunagar.com/blog/app-wide-theming-swiftui/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/app-wide-theming-swiftui/</guid><pubDate>Mon, 26 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Theming is one of those features users notice instantly — and one of the easiest places to introduce inconsistency if it’s not designed carefully.&lt;/p&gt;
&lt;p&gt;In my invocing app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, users can choose an app theme directly from Settings. Once changed, that theme needs to apply everywhere: text, backgrounds, surfaces, outlines — instantly and consistently.&lt;/p&gt;
&lt;p&gt;SwiftUI gives us powerful tools to solve this cleanly. Instead of passing theme objects through view initializers or relying on global singletons, Reckord uses a SwiftUI-native, environment-driven approach, backed by a token-based design system.&lt;/p&gt;
&lt;p&gt;This article walks through the exact implementation used in Reckord, while also highlighting which parts are implementation choices, not hard requirements.&lt;/p&gt;
&lt;h3&gt;Goals of the Theming System&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A single source of truth for UI styling&lt;/li&gt;
&lt;li&gt;App-wide access without prop drilling&lt;/li&gt;
&lt;li&gt;Instant UI updates when the user changes theme&lt;/li&gt;
&lt;li&gt;First-class support for System Light/Dark Mode&lt;/li&gt;
&lt;li&gt;A foundation that can expand beyond colors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last point is important:
this system is intentionally &lt;strong&gt;abstract&lt;/strong&gt;. It is designed to grow into fonts, spacing, corner radius, and other design tokens — not just colors.&lt;/p&gt;
&lt;h3&gt;High-Level Architecture&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;SwiftUI View
   ↓
EnvironmentValues.theme
   ↓
Theme abstraction
   ↓
Design tokens (colors, fonts, spacing…)
   ↓
User-selected theme (persisted)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Views never know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;where the theme comes from&lt;/li&gt;
&lt;li&gt;how it’s stored&lt;/li&gt;
&lt;li&gt;which implementation is used under the hood&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They only consume &lt;strong&gt;semantic values&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Understanding SwiftUI Environment&lt;/h3&gt;
&lt;p&gt;Apple uses it internally for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;color scheme&lt;/li&gt;
&lt;li&gt;dynamic type size&lt;/li&gt;
&lt;li&gt;locale&lt;/li&gt;
&lt;li&gt;accessibility settings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can extend the same mechanism for app-wide theming.&lt;/p&gt;
&lt;p&gt;Before diving into the implementation, it’s important to understand the two building blocks that make this possible:
&lt;code class=&quot;language-text&quot;&gt;EnvironmentKey&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;EnvironmentValues&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;What Is &lt;code class=&quot;language-text&quot;&gt;EnvironmentKey&lt;/code&gt;?&lt;/h4&gt;
&lt;p&gt;An &lt;code class=&quot;language-text&quot;&gt;EnvironmentKey&lt;/code&gt; defines a custom value that can live inside SwiftUI’s environment.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeEnvKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnvironmentKey&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeToken&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppTheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppTheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeToken&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; spacing &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpacingTokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; colors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ColorTokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This does two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Declares the type of value stored in the environment&lt;/li&gt;
&lt;li&gt;Provides a default value so views never crash due to missing data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SwiftUI uses this default unless the value is overridden higher in the view hierarchy.&lt;/p&gt;
&lt;h4&gt;What Is &lt;code class=&quot;language-text&quot;&gt;EnvironmentValues&lt;/code&gt;?&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;EnvironmentValues&lt;/code&gt; is a type-safe container that SwiftUI uses to store environment data.&lt;/p&gt;
&lt;p&gt;We extend it to expose a clean API:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnvironmentValues&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeToken&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ThemeEnvKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ThemeEnvKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newValue &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After this, &lt;code class=&quot;language-text&quot;&gt;theme&lt;/code&gt; behaves just like a built-in SwiftUI environment value.&lt;/p&gt;
&lt;h4&gt;Reading from the Environment&lt;/h4&gt;
&lt;p&gt;Any SwiftUI view can now access the theme like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; theme&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;SwiftUI automatically re-renders the view whenever the theme changes — no manual observation required.&lt;/p&gt;
&lt;h3&gt;Defining a Theme Abstraction&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;ThemeToken&lt;/code&gt; protocol defines &lt;strong&gt;what a theme provides&lt;/strong&gt;, not how it is implemented.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeToken&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ColorTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpacingTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This abstraction is intentional.&lt;/p&gt;
&lt;p&gt;Later, this can evolve into:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ThemeToken&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ColorTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpacingTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; typography&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TypographyTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RadiusTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nothing in the view layer would need to change.&lt;/p&gt;
&lt;h3&gt;Centralizing Styling with Design Tokens&lt;/h3&gt;
&lt;p&gt;All UI styling in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; flows through &lt;strong&gt;semantic tokens&lt;/strong&gt;, not raw values.&lt;/p&gt;
&lt;p&gt;For colors, this is done using ColorTokens.&lt;/p&gt;
&lt;p&gt;Instead of scattering &lt;code class=&quot;language-text&quot;&gt;Color(...)&lt;/code&gt; throughout the app, every color flows through semantic properties such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;foregroundPrimary&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;backgroundSecondary&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;surfacePrimary&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;outlineTertiary&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example: Colors&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ColorTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentTheme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentTheme
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Foreground colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for primary text, selected icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foregroundPrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;label&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundPrimary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary text like subtitles, unselected icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foregroundSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondaryLabel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundSecondary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary text like placeholders, disabled icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foregroundTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondaryLabel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundTertiary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for placeholder text like placeholders in text fileds and text views etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foregroundPlaceholder&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;placeholderText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundTertiary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Inverted colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for primary text on inverted backgrounds, selected icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedForegroundPrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;white&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedForegroundPrimary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary text on inverted backgrounds, unselected icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedForegroundSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedForegroundSecondary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary text on inverted backgrounds, disabled icons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedForegroundTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedForegroundTertiary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Background colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for main content background, app background, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; backgroundPrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;systemGroupedBackground&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundPrimary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary backgrounds, cards, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; backgroundSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondarySystemGroupedBackground&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundSecondary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary backgrounds, inactive buttons, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; backgroundTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tertiarySystemBackground&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundTertiary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Surface colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for surfaces with opacity. Cards, pills, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; surfacePrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;surfacePrimary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary surfaces with opacity. Scrims, overlays, tooltips, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; surfaceSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;surfaceSecondary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary surfaces with opacity. Tooltips, popovers, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; surfaceTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;surfaceTertiary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Inverted surface colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for elements that need dark backgrounds, like cards, sheets, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedSurfacePrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedSurfacePrimary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for elements that need slightly less darker backgrounds, like panels, dialogs, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedSurfaceSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedSurfaceSecondary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Inverted background colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for main content background on dark backgrounds, app background, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedBackgroundPrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedBackgroundPrimary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary content background on dark backgrounds, card background, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedBackgroundSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedBackgroundSecondary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary content background on dark backgrounds, modal background, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; invertedBackgroundTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; currentTheme &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;systemBlue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invertedBackgroundTertiary
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: - Outline colors&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for primary outlines, borders, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; outlinePrimary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;outlinePrimary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for secondary outlines, borders, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; outlineSecondary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;outlineSecondary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/// Used for tertiary outlines, borders, etc.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; outlineTertiary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentTheme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;outlineTertiary
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Example: Spacing&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpacingTokens&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;///2&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xxxs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///4&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xxs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///8&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///12&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; sm&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///16&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; md&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///24&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; lg&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///32&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xl&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///48&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xxl&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;///64&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; xxxl&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This ensures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;consistent usage across the app&lt;/li&gt;
&lt;li&gt;easy refactoring&lt;/li&gt;
&lt;li&gt;readable UI code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Modeling Theme Choices with &lt;code class=&quot;language-text&quot;&gt;Theme&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Users can choose from the following themes in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System&lt;/li&gt;
&lt;li&gt;Graphite&lt;/li&gt;
&lt;li&gt;Sky&lt;/li&gt;
&lt;li&gt;Tomato&lt;/li&gt;
&lt;li&gt;Gold&lt;/li&gt;
&lt;li&gt;Grass&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These options are modeled using a strongly typed enum:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CaseIterable&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; system &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;System&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; graphite &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Graphite&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; sky &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Sky&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; tomato &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Tomato&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; gold &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Gold&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; grass &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Grass&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; ruby &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Ruby&quot;&lt;/span&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LCHColor&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proBlue
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;graphite&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proGray
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sky&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proSky
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tomato&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proTomato
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gold&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proGold
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;grass&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proGrass
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ruby&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;proRuby
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why an Enum?
Using an &lt;code class=&quot;language-text&quot;&gt;enum&lt;/code&gt; provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compile-time safety&lt;/li&gt;
&lt;li&gt;Easy iteration for Settings UI&lt;/li&gt;
&lt;li&gt;Clean persistence using raw values&lt;/li&gt;
&lt;li&gt;A single source of truth for available themes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Mapping Themes to Color Palettes&lt;/h3&gt;
&lt;p&gt;In &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, each &lt;code class=&quot;language-text&quot;&gt;Theme&lt;/code&gt; maps to an &lt;code class=&quot;language-text&quot;&gt;LCHColor&lt;/code&gt; palette:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LCHColor&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These palettes are sourced from &lt;strong&gt;ColorTokensKit-Swift&lt;/strong&gt;, a library created by the talented designer Siddhant Mehta, offering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LCH-based color tokens&lt;/li&gt;
&lt;li&gt;Built-in Light/Dark Mode handling&lt;/li&gt;
&lt;li&gt;Perceptually balanced color values&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://github.com/metasidd/ColorTokensKit-Swift&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/metasidd/ColorTokensKit-Swift&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ColorTokensKit is &lt;strong&gt;not required&lt;/strong&gt; for this system.&lt;/p&gt;
&lt;p&gt;You can replace it with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;system colors&lt;/li&gt;
&lt;li&gt;custom Color values&lt;/li&gt;
&lt;li&gt;asset catalog colors&lt;/li&gt;
&lt;li&gt;your own token structs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The system does not depend on any specific color library — only on the idea of semantic color tokens.&lt;/p&gt;
&lt;h3&gt;Persisting the Selected Theme&lt;/h3&gt;
&lt;p&gt;In &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, the selected theme is persisted using Point-Free’s Sharing library, backed by UserDefaults.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SharedKey&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppStorageKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currentTheme&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;currentTheme&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;system&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;👉 &lt;a href=&quot;https://github.com/pointfreeco/swift-sharing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/pointfreeco/swift-sharing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This gives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;persistence across launches&lt;/li&gt;
&lt;li&gt;reactive updates&lt;/li&gt;
&lt;li&gt;type safety&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Using the Sharing library is optional.&lt;/p&gt;
&lt;p&gt;You can implement the same system using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@AppStorage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;a custom observable state&lt;/li&gt;
&lt;li&gt;any persistence layer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What matters is that the selected theme is &lt;strong&gt;reactive&lt;/strong&gt;, not how it’s stored.&lt;/p&gt;
&lt;h3&gt;Using the Theme in Views&lt;/h3&gt;
&lt;p&gt;From a view’s perspective, theming is intentionally simple:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InvoiceRow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; theme

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Invoice #1024&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundPrimary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Paid&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;caption&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foregroundSecondary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Views don’t care:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how the theme is stored&lt;/li&gt;
&lt;li&gt;which library is used&lt;/li&gt;
&lt;li&gt;whether it’s system or custom&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They only care about meaningful tokens.&lt;/p&gt;
&lt;h3&gt;Visual Result&lt;/h3&gt;
&lt;p&gt;Below are screenshots from &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; app showing different themes applied to the same screens:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACYklEQVR42k2SiXKaYBSFff/HaZamWbokanBD1qBBFkNMRFwQRCNJ/XqD007vzGUZ/jl899xTG408Tk5Oub6+wfcDsixj7LtcnJ9y9e2c0HNJ05Rx5HN59ZWvF2e43oD1ek34FHF5850vp2cM3BH5ZkPNdUPqdQVVNfGDiJZyz9S30Zs3DHp1Jq6JaWg8Bho9446OcYs71ulrKo6cVzSLX0oXN3rFFdFammZst2+U5Tt5vq0Ei3GfcmJwSIZkYw3bNhk8K7zkJvHWIUhUdKOP/ZLirt/x1yWj1R4vCKhNpwlFsWO//2C5yrhv1km9HvtnE2YDUl8TQh07aIqgxUwE/VhF7XfRw7gS+hR05wWu2FcLglAId3zWOstRmg0i9YrCa0DcJx02sCyDpnGOm4joTsOZ1NFk5Fs7RH3dMMhBj7firU9tNltUhGX5wUoIu+22UH0S6jB3WYcGDw8Wzlhhkpkku0eCmYZh6phRwmDxRpi94y2K48ibTVFtrNgWsqWCTkthF3bJhncVZTZqHT2cNBnGdYZT6ddm5aH1mqFON3SfU6xkx0hSUlssltXIn4RpmtNpt8hD7UiYPP4jHEZtIbQqwlAITSG0n5cMl/sj4XJ3JHyJVyyWKZt8w2Kxqgjnzh1p0CYf92TqNobERvN+4CUtwmWPh6dG5WFPlmJM10KaYsvd9WQpHclfo6lwf9/CcY6BNVSFriKZU+o4tlEFWzM7NJSftHsNdLMn51L0B4e60kbpdOW7JbHLqZVlSRRFTCYTDoff/K35fF71/xVPY6bSh4O8VBdJhvwsmc2q58PhwB+cKhu2dm+scgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;thumbnail&quot; title=&quot;&quot; src=&quot;/static/84f314b41416ce3b6a7e70b3d0e82991/5a190/thumbnail.png&quot; srcset=&quot;/static/84f314b41416ce3b6a7e70b3d0e82991/772e8/thumbnail.png 200w,
/static/84f314b41416ce3b6a7e70b3d0e82991/e17e5/thumbnail.png 400w,
/static/84f314b41416ce3b6a7e70b3d0e82991/5a190/thumbnail.png 800w,
/static/84f314b41416ce3b6a7e70b3d0e82991/c1b63/thumbnail.png 1200w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;Theme changes apply instantly and consistently across the app.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;SwiftUI’s environment system is a powerful but often underused tool for app-wide concerns like theming.&lt;/p&gt;
&lt;p&gt;By combining:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;EnvironmentKey&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;EnvironmentValues&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;an abstract theme model&lt;/li&gt;
&lt;li&gt;semantic design tokens&lt;/li&gt;
&lt;li&gt;reactive persistence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; achieves a theming system that is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Declarative&lt;/li&gt;
&lt;li&gt;Flexible&lt;/li&gt;
&lt;li&gt;Library-agnostic&lt;/li&gt;
&lt;li&gt;Easy to evolve&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether you use ColorTokensKit, system colors, or your own palette, this system gives you room to grow — from colors and spacings today to a full design system tomorrow.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any suggestions or a better approach, feel free to connect with me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SwiftUI Observation Framework Explained - Using @Observable in iOS 17]]></title><description><![CDATA[SwiftUI’s rendering system is built around a single core idea: views are cheap to recreate, but state must be preserved. To support this…]]></description><link>https://www.sagarunagar.com/blog/swiftui-observation-framework/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/swiftui-observation-framework/</guid><pubDate>Mon, 19 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SwiftUI’s rendering system is built around a single core idea: views are cheap to recreate, but state must be preserved. To support this model, SwiftUI needs a reliable way to observe changes in data and update only the parts of the UI that depend on those changes.&lt;/p&gt;
&lt;p&gt;Prior to iOS 17, this responsibility was handled primarily by &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt;. While effective, that approach introduced boilerplate, relied heavily on Combine, and triggered view updates at the object level rather than the property level.&lt;/p&gt;
&lt;p&gt;With iOS 17, Apple introduced the &lt;strong&gt;Observation framework&lt;/strong&gt;, centered around the &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; macro. This new system provides a lighter, more precise way to model observable state in SwiftUI.&lt;/p&gt;
&lt;p&gt;This article explains how the Observation framework works, how to use &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; correctly in SwiftUI, how it differs from &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;, and how to migrate existing code safely.&lt;/p&gt;
&lt;h3&gt;Why Apple Introduced a New Observation System&lt;/h3&gt;
&lt;p&gt;Before iOS 17, observable state in SwiftUI typically looked like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ObservableObject&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isPremium&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This approach worked, but it had several drawbacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Boilerplate everywhere:&lt;/strong&gt;
Every observable type had to conform to &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;, and every changing property required &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Over-notification:&lt;/strong&gt;
A change to any &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt; property invalidates all dependent views, even if they don’t use that property.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manual correctness:&lt;/strong&gt;
Forgetting &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt; silently breaks UI updates.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apple’s answer to these problems is the &lt;strong&gt;Observation framework&lt;/strong&gt;, which introduces a compiler-driven observation system.&lt;/p&gt;
&lt;h3&gt;Introducing &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;At the core of the new system is the &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; macro.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isPremium&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s it.
No &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;.
No &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Every stored property becomes observable by default.&lt;/p&gt;
&lt;h4&gt;Key Design Goals&lt;/h4&gt;
&lt;p&gt;Apple designed &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; with three principles in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Explicit at the type level&lt;/strong&gt;:
You mark what is observable, not how each property behaves.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fine-grained dependency tracking&lt;/strong&gt;:
Views only re-render when the specific properties they read change.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minimal runtime overhead&lt;/strong&gt;:
Observation metadata is generated at compile time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How Observation Actually Works&lt;/h3&gt;
&lt;p&gt;This is where the new system truly shines.&lt;/p&gt;
&lt;h4&gt;Property-Level Dependency Tracking&lt;/h4&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt;, SwiftUI tracks which properties are read during view evaluation.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProfileView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SwiftUI records that &lt;code class=&quot;language-text&quot;&gt;ProfileView&lt;/code&gt; depends on &lt;code class=&quot;language-text&quot;&gt;user.name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Changing &lt;code class=&quot;language-text&quot;&gt;user.isPremium&lt;/code&gt; does not invalidate this view&lt;/li&gt;
&lt;li&gt;Only updates to &lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt; trigger a re-render&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a major improvement over &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;, where any &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt; change triggers &lt;code class=&quot;language-text&quot;&gt;objectWillChange&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Initializing Observable Models in SwiftUI&lt;/h3&gt;
&lt;p&gt;SwiftUI view structs are ephemeral and may be recreated frequently. For this reason, observable models must be initialized in stable storage.&lt;/p&gt;
&lt;h4&gt;Incorrect Initialization&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SettingsView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; settings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InvoiceSettingsModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;settings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currencyCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This may appear correct, but the model can be recreated whenever the view is reinitialized.&lt;/p&gt;
&lt;h3&gt;Correct Initialization Using &lt;code class=&quot;language-text&quot;&gt;@State&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Observable models should be initialized using &lt;code class=&quot;language-text&quot;&gt;@State&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Observation&lt;/span&gt;

&lt;span class=&quot;token attribute atrule&quot;&gt;@Observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InvoiceSettingsModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; currencyCode&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;USD&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; includeTax&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SettingsView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InvoiceSettingsModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Form&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Toggle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Include Tax&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isOn&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;includeTax&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Currency: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currencyCode&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@State&lt;/code&gt; guarantees stable model lifetime&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; enables fine-grained updates&lt;/li&gt;
&lt;li&gt;SwiftUI updates only when accessed properties change&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;To understand why an &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; class must be initialized using &lt;code class=&quot;language-text&quot;&gt;@State&lt;/code&gt; within the SwiftUI hierarchy, refer to this excellent article by Natalia Panferova:&lt;br/&gt;
&lt;a href=&quot;https://nilcoalescing.com/blog/InitializingObservableClassesWithinTheSwiftUIHierarchy/?utm_medium=blog&amp;#x26;utm_source=sagarunagar.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Initializing @Observable classes within the SwiftUI hierarchy&lt;/a&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Excluding Properties from Observation&lt;/h3&gt;
&lt;p&gt;Not every property should trigger UI updates.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnalyticsModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; visibleCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservationIgnored&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; internalCache&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code class=&quot;language-text&quot;&gt;@ObservationIgnored&lt;/code&gt; to exclude properties that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Are derived or transient&lt;/li&gt;
&lt;li&gt;Don’t affect UI rendering&lt;/li&gt;
&lt;li&gt;Are performance-sensitive&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Comparison: Old vs New Observation&lt;/h3&gt;
&lt;h4&gt;Old (&lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ObservableObject&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isLoading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservedObject&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;New (&lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt;)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ViewModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isLoading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Key Differences&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;&lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Boilerplate&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Property annotations&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependency tracking&lt;/td&gt;
&lt;td&gt;Object-wide&lt;/td&gt;
&lt;td&gt;Property-level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compile-time safety&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Performance and Predictability&lt;/h3&gt;
&lt;p&gt;Because dependencies are tracked at the property level:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Views re-render less often&lt;/li&gt;
&lt;li&gt;Complex screens scale better&lt;/li&gt;
&lt;li&gt;Large observable models no longer cause global invalidation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes the Observation framework particularly useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Settings screens&lt;/li&gt;
&lt;li&gt;Dashboards&lt;/li&gt;
&lt;li&gt;Forms with many fields&lt;/li&gt;
&lt;li&gt;State-heavy business apps&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Migration Strategy&lt;/h3&gt;
&lt;p&gt;You don’t need to migrate everything at once.&lt;/p&gt;
&lt;h4&gt;Recommended Approach&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Keep existing &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt; models working&lt;/li&gt;
&lt;li&gt;Introduce &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; for new features&lt;/li&gt;
&lt;li&gt;Gradually refactor models with heavy &lt;code class=&quot;language-text&quot;&gt;@Published&lt;/code&gt; usage&lt;/li&gt;
&lt;li&gt;Remove &lt;code class=&quot;language-text&quot;&gt;@ObservedObject&lt;/code&gt; where possible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SwiftUI fully supports mixing both systems.&lt;/p&gt;
&lt;h3&gt;Common Pitfalls&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mutating outside the main actor:&lt;/strong&gt;
Observation does not automatically enforce threading rules.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assuming all mutations trigger updates:&lt;/strong&gt;
Only observed properties that are read by views cause re-renders.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Over-modeling:&lt;/strong&gt;
Don’t make everything observable—prefer smaller, focused models.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;When Should You Use &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;Use it when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Targeting iOS 17+&lt;/li&gt;
&lt;li&gt;You want cleaner state management&lt;/li&gt;
&lt;li&gt;You care about fine-grained view updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avoid it if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You must support older OS versions&lt;/li&gt;
&lt;li&gt;You rely heavily on Combine publishers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;The Observation framework is not just a syntactic improvement—it’s a fundamental shift in how SwiftUI tracks state changes.&lt;/p&gt;
&lt;p&gt;By moving observation to the compiler level, Apple has made SwiftUI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More efficient&lt;/li&gt;
&lt;li&gt;More predictable&lt;/li&gt;
&lt;li&gt;Easier to reason about&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re building modern SwiftUI apps targeting iOS 17 and later, &lt;code class=&quot;language-text&quot;&gt;@Observable&lt;/code&gt; should be your default choice for shared state.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Xcode Templates Explained - Speed Up iOS Development by Eliminating Boilerplate]]></title><description><![CDATA[While building production apps, efficiency rarely comes from writing less code. It comes from writing the same code fewer times. This…]]></description><link>https://www.sagarunagar.com/blog/xcode-file-templates-ios-development/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/xcode-file-templates-ios-development/</guid><pubDate>Mon, 12 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While building production apps, efficiency rarely comes from writing less code. It comes from &lt;strong&gt;writing the same code fewer times&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This article explains how &lt;strong&gt;Xcode Templates&lt;/strong&gt; can be used to automate repetitive setup, improve consistency, and significantly speed up everyday development. The ideas apply to any architecture or project style.&lt;/p&gt;
&lt;p&gt;To ground the discussion, I’ll start with a real problem I encountered while working on my invocing app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, and then walk through how Xcode File Templates became a practical solution.&lt;/p&gt;
&lt;h3&gt;The Problem I Faced While Building Reckord&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; is a production iOS app built with a strong emphasis on structure and consistency. The app follows &lt;strong&gt;The Composable Architecture (TCA)&lt;/strong&gt;, which encourages explicit, well-defined components.&lt;/p&gt;
&lt;p&gt;This structure is powerful, but it comes with a tradeoff.&lt;/p&gt;
&lt;p&gt;Every time I added a new screen or feature, I had to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new SwiftUI view&lt;/li&gt;
&lt;li&gt;Create a corresponding reducer file&lt;/li&gt;
&lt;li&gt;Add standard imports&lt;/li&gt;
&lt;li&gt;Define state, actions, and reducer structure&lt;/li&gt;
&lt;li&gt;Wire everything together correctly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of this was difficult. But all of it was &lt;strong&gt;repetitive&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I found myself copying boilerplate code from an existing feature, pasting it into a new file, and carefully renaming types. Over time, this workflow started to slow me down and introduced small but avoidable risks—missed renames, leftover references, or minor inconsistencies.&lt;/p&gt;
&lt;p&gt;The problem wasn’t TCA. The problem was &lt;strong&gt;manual repetition&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;That’s when I decided to move this repetition into the tooling itself.&lt;/p&gt;
&lt;h3&gt;Why Xcode File Templates Are the Right Tool&lt;/h3&gt;
&lt;p&gt;Xcode already provides a mechanism to solve this exact problem: &lt;strong&gt;File Templates&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Instead of manually creating files and pasting code, Xcode File Templates allow you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Define a reusable file structure&lt;/li&gt;
&lt;li&gt;Encode your project’s conventions&lt;/li&gt;
&lt;li&gt;Automatically replace placeholders like file names&lt;/li&gt;
&lt;li&gt;Generate ready-to-use files in seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my case, I created:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A template for views&lt;/li&gt;
&lt;li&gt;A template for reducers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From that point onward, adding a new feature in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; became a predictable, low-friction operation.&lt;/p&gt;
&lt;h3&gt;What Are Xcode Templates?&lt;/h3&gt;
&lt;p&gt;Xcode Templates are &lt;strong&gt;customizable file blueprints&lt;/strong&gt; that appear in:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;File → New → File…&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A template can include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One or more Swift files&lt;/li&gt;
&lt;li&gt;Predefined imports&lt;/li&gt;
&lt;li&gt;Standardized structure&lt;/li&gt;
&lt;li&gt;Placeholder tokens replaced by Xcode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you select a template and provide a name, Xcode generates the file exactly according to the template definition.&lt;/p&gt;
&lt;p&gt;This allows Xcode to work with your workflow instead of against it.&lt;/p&gt;
&lt;h3&gt;Why This Matters Beyond Reckord&lt;/h3&gt;
&lt;p&gt;Although my motivation came from working with TCA, file templates are &lt;strong&gt;architecture-agnostic&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;They are equally useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SwiftUI views&lt;/li&gt;
&lt;li&gt;Feature modules&lt;/li&gt;
&lt;li&gt;View models or controllers&lt;/li&gt;
&lt;li&gt;Test files&lt;/li&gt;
&lt;li&gt;Design system components&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any time you notice repeated setup, file templates are worth considering.&lt;/p&gt;
&lt;h3&gt;How Xcode Templates Work&lt;/h3&gt;
&lt;p&gt;At a high level, a template consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code class=&quot;language-text&quot;&gt;.xctemplate&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;One or more template source files&lt;/li&gt;
&lt;li&gt;A &lt;code class=&quot;language-text&quot;&gt;TemplateInfo.plist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Placeholder tokens such as &lt;code class=&quot;language-text&quot;&gt;___FILEBASENAME___&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Where Custom Templates Live&lt;/h3&gt;
&lt;p&gt;Custom templates are stored locally at:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;~/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Library&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Developer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Xcode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Templates&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each folder inside this directory becomes a category in Xcode.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: If you do not find &lt;code class=&quot;language-text&quot;&gt;Templates&lt;/code&gt; directory then create by your self.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Example: Creating Templates for the &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; Workflow&lt;/h3&gt;
&lt;p&gt;To support my workflow, I created a dedicated template group:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Templates/
└── The Composable Architecture(TCA)
    ├── TCAView.xctemplate
    └── TCAReducer.xctemplate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This keeps arcitecture-specific templates organized and easy to find.&lt;/p&gt;
&lt;h4&gt;TCAView Template&lt;/h4&gt;
&lt;p&gt;Inside The Composable Architecture(TCA) folder, I added a template folder named: &lt;code class=&quot;language-text&quot;&gt;TCAView.xctemplate&lt;/code&gt;. It contain two files:  &lt;code class=&quot;language-text&quot;&gt;___FILEBASENAME___.swift&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;TemplateInfo.plist&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TIP: Xcode already ships with well-structured, production-ready templates that can be reused as a foundation. A practical approach is to copy the existing Swift file template provided by Xcode and customize it for your own needs. The standard Swift file template is located at: &lt;em&gt;/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates/MultiPlatform/Source/Swift File.xctemplate&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Contains of &lt;code class=&quot;language-text&quot;&gt;___FILEBASENAME___.swift&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//___FILEHEADER___&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComposableArchitecture&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;___FILEBASENAMEASIDENTIFIER___&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Bindable&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; store&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StoreOf&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;___FILEBASENAMEASIDENTIFIER___Domain&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;___FILEBASENAMEASIDENTIFIER___&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token other-directive property&quot;&gt;#Preview&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;___FILEBASENAMEASIDENTIFIER___&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        store&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Store&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            initialState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ___FILEBASENAMEASIDENTIFIER___Domain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            reducer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;___FILEBASENAMEASIDENTIFIER___Domain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Contains of &lt;code class=&quot;language-text&quot;&gt;TemplateInfo.plist&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;plist&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;PUBLIC&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-//Apple//DTD PLIST 1.0//EN&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;plist&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;SupportsSwiftPackage&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Kind&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Xcode.IDEFoundation.TextSubstitutionFileTemplateKind&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Description&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;A SwiftUI Custom TCA View with Preview&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Summary&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;TCA View&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;SortOrder&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Image&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;FileTypeIcon&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;swift&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;AllowedTypes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;public.swift-source&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Platforms&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;DefaultCompletionName&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;TCAView&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;MainTemplateFile&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;___FILEBASENAME___.swift&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Options&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NotPersisted&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Type&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;text&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Description&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;The name of the view to create&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Name&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Name of View:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Required&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Identifier&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;productName&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;plist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;TCAReducer Template&lt;/h4&gt;
&lt;p&gt;Similarly, the &lt;code class=&quot;language-text&quot;&gt;TCAReducer.xctemplate&lt;/code&gt; contains a predefined structure.&lt;/p&gt;
&lt;p&gt;Contains of &lt;code class=&quot;language-text&quot;&gt;___FILEBASENAME___.swift&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//___FILEHEADER___&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComposableArchitecture&lt;/span&gt;

&lt;span class=&quot;token attribute atrule&quot;&gt;@Reducer&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;___FILEBASENAMEASIDENTIFIER___&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservableState&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Equatable&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Equatable&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Reducer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Reduce&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; action &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Contains of &lt;code class=&quot;language-text&quot;&gt;TemplateInfo.plist&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;plist&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;PUBLIC&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-//Apple//DTD PLIST 1.0//EN&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;plist&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;SupportsSwiftPackage&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Kind&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Xcode.IDEFoundation.TextSubstitutionFileTemplateKind&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Description&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;A TCA View Reducer&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Summary&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;TCA View Reducer&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;SortOrder&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Image&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;FileTypeIcon&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;swift&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;AllowedTypes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;public.swift-source&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Platforms&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;DefaultCompletionName&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;TCAView&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;MainTemplateFile&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;___FILEBASENAME___.swift&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Options&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NotPersisted&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Type&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;text&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Description&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;The name of the reducer to create&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Name&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Name of Reducer:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Required&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Identifier&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
			&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;productName&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;plist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All boilerplate is generated automatically, leaving only feature-specific logic to implement. After creating or updating templates, restarting Xcode is required.&lt;/p&gt;
&lt;h3&gt;Output: Using the Templates in Xcode&lt;/h3&gt;
&lt;p&gt;Once Xcode restarts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select New File&lt;/li&gt;
&lt;li&gt;Choose the template&lt;/li&gt;
&lt;li&gt;Enter a name&lt;/li&gt;
&lt;li&gt;Xcode generates the file instantly&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Using the Templates in Xcode&quot; style=&quot;max-width: 750px&quot;&gt;
    	&lt;source src=&quot;/static/8deec001f641ecb45820efd997d536f5/using-templates-in-xcode.mp4&quot; type=&quot;video/mp4&quot; /&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;No copy-paste. No cleanup.&lt;/p&gt;
&lt;h3&gt;Benefits Observed in Practice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Faster Feature Creation - New screens are scaffolded in seconds.&lt;/li&gt;
&lt;li&gt;Consistent Structure - Every file follows the same conventions.&lt;/li&gt;
&lt;li&gt;Reduced Errors - No leftover identifiers or missed renames.&lt;/li&gt;
&lt;li&gt;Better Focus - Time is spent on behavior, not setup.&lt;/li&gt;
&lt;li&gt;Scales With the Project - Templates grow alongside the codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Best Practices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Keep templates focused and minimal&lt;/li&gt;
&lt;li&gt;Avoid embedding feature-specific logic&lt;/li&gt;
&lt;li&gt;Revisit templates as conventions evolve&lt;/li&gt;
&lt;li&gt;Treat templates as part of your tooling&lt;/li&gt;
&lt;li&gt;Share templates with the team when possible&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Xcode Templates are a small investment with long-term impact.&lt;/p&gt;
&lt;p&gt;By moving repetitive setup into Xcode itself, you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improve development speed&lt;/li&gt;
&lt;li&gt;Enforce consistency&lt;/li&gt;
&lt;li&gt;Reduce mental overhead&lt;/li&gt;
&lt;li&gt;Create a smoother daily workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For me, solving this problem while building &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; made templates an essential part of my development environment—and once set up, they quietly pay dividends every day.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[InlineArray in Swift - Memory Efficient Fixed-Size Arrays]]></title><description><![CDATA[Swift 6.2 introduces , a new low-level data structure designed to improve performance and memory efficiency in specific scenarios. While…]]></description><link>https://www.sagarunagar.com/blog/inlinearray-in-swift/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/inlinearray-in-swift/</guid><pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Swift 6.2 introduces &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt;, a new low-level data structure designed to improve performance and memory efficiency in specific scenarios. While most developers will continue using &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; in everyday code, &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; fills an important gap for performance-critical paths where allocation cost, cache locality, and predictable memory layout matter.&lt;/p&gt;
&lt;p&gt;In this article, we’ll explore what &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is, why Apple added it, how it works internally, and when you should (and should not) use it. We’ll also walk through practical examples to understand its behavior and limitations.&lt;/p&gt;
&lt;h3&gt;Why Was InlineArray Introduced?&lt;/h3&gt;
&lt;p&gt;Swift’s standard &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; is powerful and flexible, but that flexibility comes with overhead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heap allocation for storage&lt;/li&gt;
&lt;li&gt;Reference counting&lt;/li&gt;
&lt;li&gt;Capacity growth logic&lt;/li&gt;
&lt;li&gt;Indirection when accessing elements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In performance-sensitive systems—such as SwiftUI internals, compiler tooling, numeric code, or tight loops—this overhead can become measurable.&lt;/p&gt;
&lt;p&gt;Apple introduced &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; to solve a very specific problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Store a small, fixed number of elements directly inline, without heap allocation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This design enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better cache locality&lt;/li&gt;
&lt;li&gt;Fewer allocations&lt;/li&gt;
&lt;li&gt;More predictable performance&lt;/li&gt;
&lt;li&gt;Lower memory overhead&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What Is InlineArray?&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is a fixed-size, value-type collection whose elements are stored inline within the value itself, rather than in heap-allocated storage.&lt;/p&gt;
&lt;p&gt;Conceptually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Array&amp;lt;T&gt;&lt;/code&gt; - dynamically sized, heap-allocated&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;InlineArray&amp;lt;T, N&gt;&lt;/code&gt; - fixed size &lt;code class=&quot;language-text&quot;&gt;N&lt;/code&gt;, stack-like inline storage&lt;/li&gt;
&lt;li&gt;Once created, the size of an InlineArray cannot change.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Declaring an InlineArray&lt;/h3&gt;
&lt;p&gt;An InlineArray is defined with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An element type&lt;/li&gt;
&lt;li&gt;A compile-time constant size&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; numbers&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Key points:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The size (4) is part of the type&lt;/li&gt;
&lt;li&gt;You must provide exactly that many elements&lt;/li&gt;
&lt;li&gt;No resizing is allowed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Accessing Elements&lt;/h3&gt;
&lt;p&gt;Element access is similar to &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; values&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 10&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 20&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Indexing is bounds-checked, just like &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt;, ensuring safety.&lt;/p&gt;
&lt;h3&gt;Mutating an InlineArray&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is a value type, so mutation works as expected:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; scores&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

scores&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;95&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, you &lt;strong&gt;cannot&lt;/strong&gt; append or remove elements:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ❌ Not allowed&lt;/span&gt;
scores&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;110&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The size is fixed at compile time.&lt;/p&gt;
&lt;h3&gt;InlineArray vs Array&lt;/h3&gt;
&lt;p&gt;Let’s compare the two side by side:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Array&lt;/th&gt;
&lt;th&gt;InlineArray&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;Dynamic&lt;/td&gt;
&lt;td&gt;Fixed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Heap&lt;/td&gt;
&lt;td&gt;Inline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allocation&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resizable&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;General-purpose&lt;/td&gt;
&lt;td&gt;Optimized for small sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API richness&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;Intentionally minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Memory Layout and Performance Benefits&lt;/h3&gt;
&lt;p&gt;The biggest advantage of &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is memory layout predictability.&lt;/p&gt;
&lt;p&gt;Because elements are stored inline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The entire collection lives contiguously&lt;/li&gt;
&lt;li&gt;No pointer chasing is required&lt;/li&gt;
&lt;li&gt;CPU cache usage improves&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is especially beneficial in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Math / geometry types&lt;/li&gt;
&lt;li&gt;Small buffers&lt;/li&gt;
&lt;li&gt;Internal framework data structures&lt;/li&gt;
&lt;li&gt;Hot paths in performance-critical code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example: Representing a 3D Vector&lt;/h3&gt;
&lt;p&gt;Instead of:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vector3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; values&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vector3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; values&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; position &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vector3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No heap allocation&lt;/li&gt;
&lt;li&gt;Better cache locality&lt;/li&gt;
&lt;li&gt;Clear semantic intent (exactly 3 values)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Iterating Over InlineArray&lt;/h3&gt;
&lt;p&gt;You can iterate using standard loops:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Red&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Green&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Blue&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; color &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; colors &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This feels familiar while preserving the fixed-size guarantees.&lt;/p&gt;
&lt;h3&gt;Interoperability with Array&lt;/h3&gt;
&lt;p&gt;You can convert an &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; to a standard &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; when needed:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; inline&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InlineArray&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; array &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful when interacting with APIs that expect &lt;code class=&quot;language-text&quot;&gt;[T]&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;When Should You Use InlineArray?&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is &lt;strong&gt;not a replacement&lt;/strong&gt; for &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt;. It shines in narrow, well-defined cases.&lt;/p&gt;
&lt;h4&gt;Good Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Small, fixed-size collections&lt;/li&gt;
&lt;li&gt;Performance-critical code paths&lt;/li&gt;
&lt;li&gt;Math and geometry types&lt;/li&gt;
&lt;li&gt;Internal framework or library implementations&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Avoid Using InlineArray When&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Collection size is dynamic&lt;/li&gt;
&lt;li&gt;API ergonomics matter more than performance&lt;/li&gt;
&lt;li&gt;You rely heavily on &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; functions like &lt;code class=&quot;language-text&quot;&gt;append()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;filter()&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;map()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;API Design Philosophy&lt;/h3&gt;
&lt;p&gt;Apple intentionally kept &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; minimal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No resizing&lt;/li&gt;
&lt;li&gt;Limited mutation&lt;/li&gt;
&lt;li&gt;Strong compile-time guarantees&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes misuse harder and intent clearer—an important principle in Swift’s evolution.&lt;/p&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is a powerful addition to Swift, but it’s a specialized tool, not a general-purpose collection. For most application-level code, &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; remains the best choice. However, when you need precise control over memory layout and performance, &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; provides a safe, expressive alternative without sacrificing Swift’s core principles.&lt;/p&gt;
&lt;p&gt;If you’re building frameworks, performance-sensitive components, or low-level abstractions, &lt;code class=&quot;language-text&quot;&gt;InlineArray&lt;/code&gt; is well worth understanding and adopting thoughtfully.&lt;/p&gt;
&lt;p&gt;Thank you for reading. If you have any questions feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Zoom Navigation Transitions in SwiftUI]]></title><description><![CDATA[SwiftUI continues to evolve with powerful APIs that help developers build fluid, delightful user experiences with very little code. One such…]]></description><link>https://www.sagarunagar.com/blog/swiftui-zoom-navigation-transitions/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/swiftui-zoom-navigation-transitions/</guid><pubDate>Mon, 29 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SwiftUI continues to evolve with powerful APIs that help developers build fluid, delightful user experiences with very little code. One such addition is zoom-style navigation transitions, introduced to make navigation feel more spatial, contextual, and intuitive.&lt;/p&gt;
&lt;p&gt;Recently, I added a zoom navigation transition to the Settings view in my invocing app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; using the &lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt; modifiers. In this article, we’ll explore these APIs in detail—what they are, why they matter, and how to use them correctly in real-world SwiftUI apps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Zoom navigation transitions using &lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt; are supported on iOS 18 and later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Why Navigation Transitions Matter&lt;/h3&gt;
&lt;p&gt;Navigation is one of the most frequent interactions in any app. Poor transitions can feel abrupt and disorienting, while well-designed transitions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provide visual continuity&lt;/li&gt;
&lt;li&gt;Help users understand where they came from&lt;/li&gt;
&lt;li&gt;Make the UI feel polished and native&lt;/li&gt;
&lt;li&gt;Reduce cognitive load&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Traditional push/pop animations are functional—but they don’t always communicate context. Zoom transitions solve this by visually linking the source and destination views.&lt;/p&gt;
&lt;h3&gt;What Is a Zoom Navigation Transition?&lt;/h3&gt;
&lt;p&gt;A zoom navigation transition animates a view so it appears to expand into the next screen (or collapse back when navigating back). This is commonly seen in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Settings screens&lt;/li&gt;
&lt;li&gt;Profile details&lt;/li&gt;
&lt;li&gt;Media viewers&lt;/li&gt;
&lt;li&gt;Card-based layouts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SwiftUI enables this behavior by matching views across navigation boundaries using a shared identity.&lt;/p&gt;
&lt;h3&gt;Core Concepts You Need to Understand&lt;/h3&gt;
&lt;p&gt;Before writing any code, it’s important to understand the three key building blocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@Namespace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’ll explore each one in isolation first.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;.@Namespace&lt;/code&gt;: Creating a Shared Animation Space&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;@Namespace&lt;/code&gt; creates a shared animation context that allows SwiftUI to relate views across different parts of the view hierarchy.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Namespace&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; settingsNamespace&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Think of a namespace as a bridge that tells SwiftUI:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“These views are related—animate between them.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Why Is It Required?&lt;/h4&gt;
&lt;p&gt;SwiftUI navigation views are recreated during transitions. Without a namespace, SwiftUI has no way to know that two views (in different screens) represent the same UI element.&lt;/p&gt;
&lt;h4&gt;Key Rules&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;A namespace must be declared once, typically at the parent level.&lt;/li&gt;
&lt;li&gt;The same namespace must be used in both source and destination views.&lt;/li&gt;
&lt;li&gt;Namespaces are lightweight and safe to reuse for related transitions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt;: Creating a Shared Animation Space&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt; marks the starting point of a navigation transition.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matchedTransitionSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; settingsNamespace
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This modifier tells SwiftUI:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“When navigating, animate from this view.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Important Parameters&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;id&lt;/code&gt;: A unique identifier that matches the destination view.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt;: The namespace that connects source and destination.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Where Should You Apply It?&lt;/h4&gt;
&lt;p&gt;Apply &lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt; to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buttons&lt;/li&gt;
&lt;li&gt;Cards&lt;/li&gt;
&lt;li&gt;List rows&lt;/li&gt;
&lt;li&gt;Any tappable UI that triggers navigation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, this is applied to the Settings icon on the dashboard screen.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt;: Defining the Destination Animation&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt; defines how the destination view appears when navigated to.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigationTransition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sourceID&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; settingsNamespace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This modifier belongs on the &lt;strong&gt;destination view&lt;/strong&gt;, not the source.&lt;/p&gt;
&lt;h4&gt;How Zoom Works&lt;/h4&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;.zoom&lt;/code&gt; transition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Animates size&lt;/li&gt;
&lt;li&gt;Animates position&lt;/li&gt;
&lt;li&gt;Maintains visual continuity&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SwiftUI automatically calculates the animation path between the source and destination views.&lt;/p&gt;
&lt;h3&gt;Putting It All Together: Step-by-Step Implementation&lt;/h3&gt;
&lt;h4&gt;Step 1: Declare the Namespace&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@Namespace&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; navigationNamespace&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Place this in the parent view that manages navigation.&lt;/p&gt;
&lt;h4&gt;Step 2: Mark the Source View&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;NavigationLink&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;SettingsView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; navigationNamespace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; label&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;systemName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gear&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matchedTransitionSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; navigationNamespace
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells SwiftUI where the zoom animation should start.&lt;/p&gt;
&lt;h4&gt;Step 3: Apply the Navigation Transition in Destination&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SettingsView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; namespace&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ID&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;SettingsContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigationTransition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sourceID&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; namespace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now SwiftUI knows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where the animation starts&lt;/li&gt;
&lt;li&gt;Where it ends&lt;/li&gt;
&lt;li&gt;How to animate between them&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Real-World Example: &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt; Settings Screen&lt;/h3&gt;
&lt;p&gt;In Reckord, the Settings screen includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App preferences&lt;/li&gt;
&lt;li&gt;Business details&lt;/li&gt;
&lt;li&gt;Invoice configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using a zoom transition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Makes the Settings feel connected to the dashboard screen&lt;/li&gt;
&lt;li&gt;Improves perceived performance&lt;/li&gt;
&lt;li&gt;Matches Apple’s system apps behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; adding zoom navigation for settings screen:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Flowers are in bloom&quot;&gt;
    &lt;source src=&quot;/static/44f6707e8a7eb4e9f5181c86e12ffa7f/before-zoom-navigation.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; adding zoom navigation for settings screen:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Flowers are in bloom&quot;&gt;
    &lt;source src=&quot;/static/c4ff26a78f02286fe395e341be76f134/after-zoom-navigation.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;h3&gt;Accessibility Considerations&lt;/h3&gt;
&lt;p&gt;SwiftUI automatically respects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce Motion system settings&lt;/li&gt;
&lt;li&gt;Dynamic Type scaling&lt;/li&gt;
&lt;li&gt;VoiceOver focus changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You don’t need extra code—but always:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test transitions with Reduce Motion enabled&lt;/li&gt;
&lt;li&gt;Ensure the app remains usable without animations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;SwiftUI’s &lt;code class=&quot;language-text&quot;&gt;.navigationTransition&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.matchedTransitionSource&lt;/code&gt; APIs make it easier than ever to create high-quality, native-feeling navigation animations—without complex gesture handling or custom animation code.&lt;/p&gt;
&lt;p&gt;By understanding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How @Namespace connects views&lt;/li&gt;
&lt;li&gt;How source and destination roles differ&lt;/li&gt;
&lt;li&gt;Where each modifier belongs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can confidently add polished transitions to production apps like &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thank you for reading. Stay safe and Happy holidays! 🎄&lt;/p&gt;
&lt;p&gt;If you have any questions feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SwiftUI Fonts Explained - System Styles, Modifiers and Accessibility]]></title><description><![CDATA[Fonts define the visual structure and readability of text in a SwiftUI interface. SwiftUI provides a typography system that adapts…]]></description><link>https://www.sagarunagar.com/blog/swiftui-fonts-guide/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/swiftui-fonts-guide/</guid><pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Fonts define the visual structure and readability of text in a SwiftUI interface. SwiftUI provides a typography system that adapts automatically to user settings, supports accessibility, and maintains consistency across Apple platforms.&lt;/p&gt;
&lt;p&gt;This blog describes how to use system font styles, apply font modifiers, and integrate custom fonts in SwiftUI.&lt;/p&gt;
&lt;h3&gt;Why Fonts Matter in UI/UX&lt;/h3&gt;
&lt;p&gt;Fonts influence how users scan, read, and understand information in your app.&lt;/p&gt;
&lt;p&gt;Good typography helps with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Establishing visual hierarchy&lt;/li&gt;
&lt;li&gt;Improving readability&lt;/li&gt;
&lt;li&gt;Creating a consistent brand identity&lt;/li&gt;
&lt;li&gt;Supporting accessibility features like Dynamic Type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SwiftUI encourages the use of semantic font styles instead of fixed font sizes. Semantic styles adapt to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dynamic Type&lt;/li&gt;
&lt;li&gt;Accessibility settings&lt;/li&gt;
&lt;li&gt;Platform-specific typography guidelines&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Using System Font Styles&lt;/h3&gt;
&lt;p&gt;System font styles describe the purpose of text rather than its size. SwiftUI adjusts the actual font size automatically.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Large Title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;largeTitle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title 2&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//available in iOS 14 and onwards&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title 3&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//available in iOS 14 and onwards&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Headline&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Sub Headline&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subheadline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Body&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// default&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Callout&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;callout&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Footnote&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;footnote&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Caption&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;caption&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Caption 2&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;caption2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//available in iOS 14 and onwards&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADg0lEQVR42s2Xz0sbQRTHF7wXWqq5ePbiXyA2iYiiGH9UDCShEsGb0IrQi6FQaKF/hUeNhxzaQinahJigpY1ZAkVREBR//9b4A38kZtfp+052Skw22VVz6MAjk92Zz7x5782bt5KUbZaamppP3d0vI/39/fG+Pq/c2/tKHhwclH3vfPLw8DAXn89Hz97wd16vV6ZxcafTOVVbW/uRGJUaS3rW0tLyhxq7uLhQj46O2NXVFUMbHx9nAwMDbGhoiAv6gUCAv0un0+z09JTt7OyoMzMzrLm5OU6sJ1J1dfXbSCTCx6ytrSmzs7MqDVTpv0oLqTRIraio4IJ+Z2cnf5dKpdTt7W01GAwql5eX6XA4zCotltcSkccODg4AzKiqylcXv8lkks3Pz7OFhQUu6EMrMeb29pYL5pKmrL6+fkRqb2//TCvwh9pL0w3jtcUzWNxqtY4C+FWzWQFQTMgVvTGYe3JyAqBfIpsUBZrVEnNhCrvd7pc6Ojq+lBXY1dX1Q7OhUhag09nzk+KvfEByyoS25QKgcEKuM3JCRR9ITvlWDJjbFEXhYqDhmNSTt2UBxRFEIEPm5ubY6uoqi8ViLBQKsePj43xtFYRNQ0NDgGzo1AVikizLHIKjCQ02NjbY9PQ0Ozw8LABifFtbWwRenirlZWwTiSCTyZRyCgGTrLW1NQIbTugBxeqA4eBDtJ3oOUXB0SPgVIEN9Rq8DLDe+38aEpCyU1SipKoLFH3YDnZcXFxk5+fnRTWEUxobG78jDsNGNjw7O+MwPTvmho3NZhszPMvYKry9vLxcyoZ3TkrJbAPtEZN7e3scbubo6QJFf3d3l8XjcZZIJHj/URrCZisrK7iI2NLSEu/nH7+7QKvfMGPjBOzv73MoYk3cNw8CCi8jZNbX1w3TF78CjIA3Nzdsc3OTbW1t8f6jgfAsgEgMZQHiHYAQUVE8Cohn2C6cUuIsmwcidKhEYVR2FHi4CNBh6BSUKggZo7NsSsP73Hqmgfk3XUmgo9waOhyO/xOYrb5e+CW6+h5cH+YCEQVUcI5KTU1NfmQTUcEKB5gVUXAi8Ovq6kZ4jR2NRvEwRQOQ7NR7iKLNSU9OTjILamxqT0nLBDLy9fW1imSAYDYjVLjzOcjoNrs9xr8CxHcKtQ/koJDL7frt8XhiEBcXFxcP/80+8/D/npjb7f5FPghWVVW9J8ZzkP4CkEQ+wC/peGcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font styles&quot; title=&quot;&quot; src=&quot;/static/adf3fa43f97dd1a0da06194bf8f07983/88c73/system-font-styles.png&quot; srcset=&quot;/static/adf3fa43f97dd1a0da06194bf8f07983/772e8/system-font-styles.png 200w,
/static/adf3fa43f97dd1a0da06194bf8f07983/88c73/system-font-styles.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.largeTitle&lt;/code&gt; for main screen titles.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.title&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.title2&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.title3&lt;/code&gt; for primary section titles.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.headline&lt;/code&gt; for emphasized labels.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.subheadline&lt;/code&gt; for secondary headings.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.body&lt;/code&gt; use for readable body text.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.callout&lt;/code&gt; for quote, important information, or a benefit statement.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.footnote&lt;/code&gt; for secondary text, such as disclaimers, or legal information&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.caption&lt;/code&gt; for small, secondary text such as descriptions accompanying images, disclaimers, or subtitles.&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.caption2&lt;/code&gt; for alternate, smaller captions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All system styles automatically support Dynamic Type it means these styles scale automatically when users change text size in Settings.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 65.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABuUlEQVR42nWS6YoCQQyE5/2fS/FAUFTU8b6v8b5PavkKen4suwOhe5JKpdJJ1G63lc1mNRgMtFwulc/nVa1WNZ/P1Wq1lMvlNBwONR6Pfe90OppOp6rVasauVivnwtHtdhUtFgvxbbdbA9/vt77fr+I41u12cwwyYnzEG42GPp+Pns+n/ZvNxjHITXi9Xu3kvtvtdD6f1ev1dDgcdLlcnIRi7hhdcYYcTv5TQhThDEmPx8PyIUZRIHy9Xrrf7ybk3O/3KSHYlPB3y7TzX8uQ0jIiQsvkpi2PRiO3iQLIca7X61QV4MlkkiYSpwAY8CEPDnDRbDbztMJblstlNZtNt807FgoFt4aVSiVPlBiYSqXiHEgzmYyLRrDiYGUgpToq+v2+T0B0AY41AkshiFkv8sgpFovOiQDwFkmSGIx0BsNQmDJGAjHUYOwiiiHDaB/j7qGcTidPCgeqIKEa5PhRydNAzDuiEMW0DZ57vV63ahMy2bBTkDFdko7Ho//DgIL6vxRS0Ap5HwjD+0HATrE2qIGAyuD4h5QYBfBDhNER+RGScaAQMoipiDpiGERYWCtwqCGPO3g6Yg9/APJPxSBCMy8rAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font styles dynamic type&quot; title=&quot;&quot; src=&quot;/static/7f40389127bfafff24ba19fd86f01262/5a190/system-font-styles-dynamic-type.png&quot; srcset=&quot;/static/7f40389127bfafff24ba19fd86f01262/772e8/system-font-styles-dynamic-type.png 200w,
/static/7f40389127bfafff24ba19fd86f01262/e17e5/system-font-styles-dynamic-type.png 400w,
/static/7f40389127bfafff24ba19fd86f01262/5a190/system-font-styles-dynamic-type.png 800w,
/static/7f40389127bfafff24ba19fd86f01262/c1b63/system-font-styles-dynamic-type.png 1200w,
/static/7f40389127bfafff24ba19fd86f01262/fe238/system-font-styles-dynamic-type.png 1401w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Applying Font Weight&lt;/h3&gt;
&lt;p&gt;Font weight determines the thickness of characters, ranging from very light to very heavy. Use it to establish hierarchy without changing font size.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Ultra Light&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ultraLight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Thin&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thin&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Light&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;light&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Regular&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;regular&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Medium&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;medium&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Semi Bold&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;semibold&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Bold&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bold&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Heavy&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;heavy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Black&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADqUlEQVR42q2Xz0sbQRTHF7wXWlpz8ezFv0BsEhFFMf6IGEhCJYI3oRWhF0Oh0EL/A0FBPZl4CNJUa9UmxAQtqSYGC6IH8aDgbzT+wB+J2XU632e2bGN2E2MGHjO7O/OZN++9mXkrCPdFV15e/sVsNge7uroijk5HtKPjTbSnpyfq/OCM9vX1kTidTv7uHX1zOBzRzk5HxGKxzFVUVHzmjFdplvCivr7+Dy8skUhI8XgcNUMZGxtj3d3drLe3lwRtj8dD35LJJDs7O2N7e3vSwsICq6uri3DWM6GsrOx9KBSiPhwmrqysSDc3NxJ/lvhEEu8klZSUkKDd0tJC3zD57u6u5PP5xKurq2QgEGCvdLq3Aie7jo6OAExJkkSzyzW0XV1dZWtrayRoQyu5z93dHQnGck1ZVVXVkNDU1PSVz0Av0x/zLuifnjyFyfV6/SiA366vr7MC5QFKydYHY09PTwF0C9wmqsB8tcRYmMJoNLqF5uZmb1GBra2tP9M2FIsCtFjaf11eXhYPyJ0yk16yqOYU+b0iTNSB3Cnf1YAXFxdsc3OT7e/vM8TqxsbGvzhUTqIAuoR2jSVDu1QqRbUoiozvIDUNRYRNdXW1h9vQomlDALe2tkhLQFVsKJ6cnLDGxsYgvDyn5WW8Q+fj42OCqwPjrKGhIQgbzmgBAbm9vaXlagGx9ThwTtWGchvOCIfDbH5+/oFD/tOQA/npFBLa2sw54xC2y2a/TKfU1NT8QBwGMpcs15gI59zy8jJbWlpisVjsAVgZNgaDwaW5lzH44OCA4o8fpix9bubcKQ9OG7k+Pz8nEEJmZ2eHPC1fDwUBDw8P2fT0NPP7/Wxqaoocg92jsVPcmgesfBVk8352DfXawMnJSeb1eklL3Hbj4+NsYmJCQ8McQCwPHRHUCG48y0vOpiFdAWpAub29vc2CwSAFNzyuYoL8gfAyYhECJxUMlJ2CjohHLDkzZB4NBGhgYID19/ezkZERcors+YKAmUXjgFUCTZrAwcFBNjw8zFwuFwX4k2yIsr6+TodCNBql++VJNnzsNUpAUw6gVl6THWgyFVnDIgHvs6/XboFffQXnh0ogLimecI4KtbW17vSWSimz0nxFTjiRwVZWVg4pc+wE74ALQ3qEiOkxydnZWaZDjs3Lc65lDLGGZB3ZPfZtPoK9jTGRSIQZjMZF+guQ/1N4+cQd5LfarL/tdvsixEpiJbFTff/OTs/2RZvNFuY+8JWWln7kjJcg/QV/ejGsQvycqwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font weights&quot; title=&quot;&quot; src=&quot;/static/8befe338c910d08fa0ecda07d8b05ce2/88c73/system-font-weights.png&quot; srcset=&quot;/static/8befe338c910d08fa0ecda07d8b05ce2/772e8/system-font-weights.png 200w,
/static/8befe338c910d08fa0ecda07d8b05ce2/88c73/system-font-weights.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.regular&lt;/code&gt; for body text&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.medium&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;.semibold&lt;/code&gt; for labels&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;.bold&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;.heavy&lt;/code&gt; sparingly for emphasis&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Combining Font Style and Weight (Best Practice)&lt;/h3&gt;
&lt;p&gt;Instead of using only weight or size, combine font style + weight.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Invoices&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// title font style&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;heavy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// heavy weight&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Invoice Summary&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// headline font style&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontWeight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;semibold&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// semibold weight&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC5ElEQVR42u1XT0sbQRQf8F5oqebiOZd8gmDzB4koSYyKgWSpRDwGWhF6MRQKLfRTeFGS9ZCDLZRimpLdQEoruwaK0Y+QgEJihBjzZ8fpe5OsxNZsY5lDoR14zOzMm997M2/mN28J6RWb3W5/u7gYUtfW1rRYLKavrDzV19fX9cTLhL65ucklkUhA33M+hjqrqzEtHA4rDofjDWCM97HIo9nZ2e9QWKvVorVajbXbbYZld3eXxeNxtrGxwQXb6XSaj6FOvV5nlUqFFgoFNjMzowHWAzI5OflCVVWuc3FxYRwdHdFut0vhm4IhCkp0bGyMC7ZDoRAfQ+Plcplms1nj8vKyncvl2LjN9owAcurs7AwBu5RSbt2s0dtSqcROTk64YBu9MnWur6+54FzwlE1NTW2RYDC4BxZ454DCSAV1+8a7aNzlciUR8H2z2bwBvGvCoNylg3PPz88RUCawJ0MBR/US5+JWeDwemczPz78TCriwsPCpv4eGEMBwePlLo9EQBwhB2e8vWQwgBOWDQMAUWRazZAOPjdfrTcMehoUAVqtV5vf7VYyyIiDKAFhjc3NzKu7hvghAvHoAqAjbwyoAAjvlydLS4lBAkyysSGMwKNPT0x/xHOZE3RS3252yvMtoFUiXC+4RGjbZ3Oqm/MI2Zq0oCtvZ2WGyLLNkMsm2t7fZ4eHhLZ2RAE1GBppnOHZ1dcVr9BDb9/LQBMXJ8L6wYrHIjo+Pma7r3DvsM5c9+AT0AF2yJWNbBGGIh78B/PnY3HV8BgH5E3BfD62OzX9AYYCBf23JAeGAgcDfCdjLvp7IBJ6+W/nhnwIiAUPCmSQ+n08+PT29yWCHEcIwMRNOzGCdTucWz7Hz+Tx2tkDBQG69hxj9Oe1MJsNsmGNDeQheFpFIgY0pkmen0xlJkNFxjqZpzO3xHPC/APM/BcprCNDnSDTyTZKkA5QIlwgXide9Pol/SwfRaPQrxCA7MTHxCjAeI9IPBxhLdxebzUYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;combine system font weights&quot; title=&quot;&quot; src=&quot;/static/25a0b729a0aeb5cec047fa3e6361470c/88c73/combine-system-font-weights.png&quot; srcset=&quot;/static/25a0b729a0aeb5cec047fa3e6361470c/772e8/combine-system-font-weights.png 200w,
/static/25a0b729a0aeb5cec047fa3e6361470c/88c73/combine-system-font-weights.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Why this works&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Keeps typography adaptive&lt;/li&gt;
&lt;li&gt;Maintains Apple’s visual consistency&lt;/li&gt;
&lt;li&gt;Works perfectly with accessibility&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Font Design&lt;/h3&gt;
&lt;p&gt;SwiftUI allows you to change the design of system fonts.&lt;/p&gt;
&lt;p&gt;Available Designs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.default&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.rounded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.monospaced&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.serif&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Default Design&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Rounded Design&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontDesign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rounded&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Monospaced Design&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontDesign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;monospaced&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Serif Design&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fontDesign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;serif&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADj0lEQVR42s1XW0sbQRRe8L3QUs2Lz774C8QmEVEU4yViIAmVSH0TWhH6YigUWuiv8FHjQx5qoRRNQmLEmMTEaL2B9xteUDTeNTG7np4zZmTTbGyq++DAx+zOznznzJwz38wKwl3RlJSUfDMajcPt7e8itjZbtLX1bbSzszNq/2SPdnd3M9jtdmz7wL7ZbLZoW5stYjKZfKWlpV+RozDNJbyqqan5jQWur6+lo6MjqoFKf38/dHR0QFdXFwM9O51O9i2ZTMLJyQns7u5Ko6OjUF1dHUGuF0JxcfFHv9/P+iCZODExIRExvktoSMJOUkFBAQM9NzY2sm+JRELa2dmR3G63eHl5mfR6vVCo0bwXkLnv4OCACFOSJDHrvI7H4zA7Owvz8/MM9Exe8T63t7cMNBY9hfLy8h6hvr7+O1pgjemPeRfqnzaeIuNarbaXCH9cXV0pEvIBcij1obHHx8dE6BBwTXIS5usljaWl0Ov1DqGhoWFAVcKmpiZXeg1FVQhNppbAxcWFeoQYlMH0lNUhxKD8VJGwT2hRZ8oipU1FRYUT19CkCiFpQF1d3TBF2acU5RwJ/ABhHGpra4dpDQdzpY1sr2a8KxgWaeshoU9xDakmeRJFkW03qlFdssgyPERCVCe/0NxszCK8ubmBQCAAHo+H1SMjIxAOhyEYDILL5WJtqVQqKyiVlZW/KA+9SlMmkT0/P2egtCJQP1r809NTxbTR6XR9GXuZpkZlY2MDFhYWYH9/H9bX12F1dZVhbW0Ntra2YGVl5Z5UaadkqQ0J7tTUFMzNzcHMzAygisPy8jIsLi6ydp/PB4eHh/8mJKu0+HI15kZ4YAj8TOEByyLkik3WKRB0YI2Pj7NghEIhiMVirN7e3maBGRsbY17jeQKbm5v3AqvXazM9JIsUPQ6u0jxl5CpOmUDZkemhNnsN+cC9vT2Ynp6+x+TkJFs/8pYfVPJDitrYEZCL8OzsjEWbpkRBouguLS0xwnTe5kf4FPl6kFAe5b/xKELVPXwCoeHZe6gyoUF1QoPheRLe3b7eOAQ8+h59P5QT0iGFF85eoaqqykHKzNXmoR2iBH7hpBtsWVlZj/yOncAOpEXSf0BMj0kODQ2Bhu7YWF6ilzFSEbqskxKT1uUD0kkaE4lEQKfXh9lfAP9PwfIFA+QxW8whq9UaJpgZzAxWVt+1Wdm7NWyxWIIYA3dRUdFn5HhNTH8Av1I2RqjZzhAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font design&quot; title=&quot;&quot; src=&quot;/static/02889489232629997794c86160311dda/88c73/system-font-design.png&quot; srcset=&quot;/static/02889489232629997794c86160311dda/772e8/system-font-design.png 200w,
/static/02889489232629997794c86160311dda/88c73/system-font-design.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Monospaced - Numbers, invoices, codes&lt;/li&gt;
&lt;li&gt;Rounded - Friendly UI&lt;/li&gt;
&lt;li&gt;Serif - Reading-heavy apps&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Italics, Underline and Strikethrough&lt;/h3&gt;
&lt;p&gt;You can further adjust the system font’s style by using modifiers such as &lt;code class=&quot;language-text&quot;&gt;.italic()&lt;/code&gt; to italicize the text, &lt;code class=&quot;language-text&quot;&gt;.underline()&lt;/code&gt; to add an underline, and &lt;code class=&quot;language-text&quot;&gt;.strikethrough()&lt;/code&gt; to draw a line through the text.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Note: This feature is experimental&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;italic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Privacy Policy&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;underline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$49.99&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strikethrough&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADAUlEQVR42uWXzUsbQRTAF7wXWqq5ePaSvyDYZEUMBqNRMZAslRWPQhuEXgyFQgv9KzxqPOTQFkrRpkQDllZ2qdaPYC7iRYMf5NOvxOz6+t64K5uahrWdQ2kfvMzszJvffL95EYRrcXR0dLweGgosjY+PK/KYrI6OPlYjkYgafR5Vp6ammEajUSx7yupkWVbHxmQlGAwuOp3OV8hoNVjCg97e3u8oUKlU9EKhQCmQzM3NwcTEBExOTjKlfDweZ3XVahWKxSJks1l9eXkZvF6vgqx7Qnt7+7NUKsVsjo+PtXQ6rRMYv3XsSEcjvaWlhSnlA4EAqyOb/f19PZFIaGdnZ9VkMgmtDscTAcmzR0dHBKzpus56N9N8Pg+bm5uAnTClPI3KtLm6umJKbXGk0NnZOS309/e/wR5YoVFpW8je6LxGnbvd7hkCvjs/P28INBtYtZENtaW1R2BMwDX5JdDuKKktLYUoijFhYGDgLVfg4ODgR2MNNS7AYHDk8+npKT8gbsq8MWU+QNyU9xyBs8IInylrdGy6urriuIZBLsBcLgd9fX1LtMuLHHYZgXnw+XxLtIbzPIB09RC4yG0NcwhE75QShoeHuG1Kd3f3BzqHSeuUrVDz26oWyK1j4/F4ZuvuMv1kMhnY2tqC3d1d2N7eZnkq29nZYbqxscHK1tfXWbkhdTelzttomgaXl5esZzJCrwzkgA8ODmBvbw9OTk6YG6vVakwbXb1b7stM8UmAtbW1mxGqqgqlUqnOxhbQ2oAMaZqrq6tQLpebrqEoumNNPTYJvYA0UlJ66ZrfZRvAuzgH9gTYAf58nP4YyH2E/xzQ/79N2c8d6Pf/ncDr6OtRTMCn77fjQyuQHikMOGeEnp6e2OHh4U0E28jtN1Mz4KQI1uVyTVtj7AoaaBTt3kE1o011YWEBHBRjo9zHUX5DgYuLC518Hj0BdpR8JbVRFAU8orjC/gWY/1NQXuIGfQqFQ18lSVohDTENMZVYel0msW9pJRwOf8E9SLS1tb1AxkMi/QDK9Up/7Qw4JgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font italic underline strikethrough&quot; title=&quot;&quot; src=&quot;/static/dbb6fc526e849fdc59dd863ee1f10fdf/88c73/system-font-italic-underline-strikethrough.png&quot; srcset=&quot;/static/dbb6fc526e849fdc59dd863ee1f10fdf/772e8/system-font-italic-underline-strikethrough.png 200w,
/static/dbb6fc526e849fdc59dd863ee1f10fdf/88c73/system-font-italic-underline-strikethrough.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;Starting with iOS 16, you can customize the &lt;code class=&quot;language-text&quot;&gt;.underline&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.strikethrough&lt;/code&gt; by changing the line’s pattern and color. Pattern has these options: &lt;code class=&quot;language-text&quot;&gt;.dash&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.dashDot&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.dashDotDot&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.dot&lt;/code&gt;,&lt;code class=&quot;language-text&quot;&gt;.solid&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Custom Underline&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;underline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pattern&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dash&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Custom Strikethrough&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strikethrough&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pattern&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mixed Styles&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;underline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pattern&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dashDot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strikethrough&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pattern&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;solid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADdUlEQVR42uWXS0tbQRTHL7gvtFSzce3GTyBWI6IoxicGYqhEcCe0InRjKBRa6KdwaSIli7ZaYmwkMaKNMWlMYrQptS015q15+Uw0N6fnTHKL1qix3IXQgT937p2Z35x5nTmX4wpJUlNT87q3t3dheHjYrhpSOQYHHztGR0cd6udqx/j4OJNarcZvT1mZSqVyDA2p7HK53FxbW/sKGZVFFvegra3NjQkymQwfj8fh5OQEKE1NTcHIyAiMjY0xUV6n07GybDYLqVQKQqEQv7S0BK2trXZk3eOqq6ufWSwWVicWi+WcTid/dHTE4zuPHfFYia+oqGCifHd3NyujzoPBIG80GnNYP2symaBSInnCIVmDIAKe8TzPeheeiUQCvF4vbG5uMlGerBLq5PN5JmqLlkJ9ff0E19nZ+RZ7YB+LhWUnql/s/Iw6b2homCTg++Pj45JAocF5lapDbZPJJAG1HM7JlcByraS2NBVSqVTLdXV1vRMV2NPT87E4hzlRgHJ5//Lh4aF4QFwUQ3HI4gBxUT6ICNRw/eIMOUfbpqmpSYdzKBcFSD6go6NjgVbZLMIqIzAB7e3tCzSHBjGAdPQQaC45h8Khv0kXLEQgeicL19fXK9qiNDc362kfms4PmeRcW4PPTidYrVZYw7zP5wO32wXLy8uwumqHlZUVWF/3Eu7CtmlsbNRcOstU/CuShG/+KNOPYAwCe/vwMxyHLX8EtnaiqBh8D8SAWKVOyh9vgwmikQik0PxddLr76TTE93YhGAhALBqFGJbt7Ra+pxEQCYcgX/SHpYF4T/hcLnDhkGyLi+Cx2+GrxwNWsxns+P4J3bwHh+yy2cA0Owvu1VXIoRFXAq9wniXT31dAAdhwGSjcJ182NuCNRgMmoxHmDQbQz8yAQa8H/fQ07GxvX4BeC4SiVZlUGlI7AUj4/ZDGOdwPhyGCoDgqe3BwYb8KQHYFXDfk23qba4E3nZBbA0W38C4BZf/bkGWiA2WyuwksRF+PtBxeff8cH54H0iWFAeck19LSoo2i8xQi2HIvKEFCwEkRbF1d3cT5GDuDFXLklW6hXLFNdm5uDiQUY2O6j1ZirO6k6J+n6P709LQsYeDO2tjRszdKpTb2FyD8p2B6iQs0rxhQrCiVShtJwaRgUrJn4ZuSvSttAwMDVlwDY1VV1QtkPCTSb7J1Ogha5AZFAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font italic underline strikethrough customization&quot; title=&quot;&quot; src=&quot;/static/5668465d2948a5fdc72e174cc7bc5224/88c73/system-font-italic-underline-strikethrough-customization.png&quot; srcset=&quot;/static/5668465d2948a5fdc72e174cc7bc5224/772e8/system-font-italic-underline-strikethrough-customization.png 200w,
/static/5668465d2948a5fdc72e174cc7bc5224/88c73/system-font-italic-underline-strikethrough-customization.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.italic()&lt;/code&gt; - Quoting text, scientific names, subtitles or captions, thoughts or narration in text content&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.underline()&lt;/code&gt; - Links, key terms or definitions, items requiring user attention&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.strikethrough()&lt;/code&gt; - Completed tasks in a to-do list, Discounted prices, Deprecated or unavailable items&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Letter Spacing: Kerning&lt;/h3&gt;
&lt;p&gt;Kerning adjusts the spacing between specific pairs of letters to improve visual balance and readability.&lt;/p&gt;
&lt;h4&gt;Example letter pairs:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;AV&lt;/li&gt;
&lt;li&gt;To&lt;/li&gt;
&lt;li&gt;Wa&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Characteristics&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Applies to individual letter pairs&lt;/li&gt;
&lt;li&gt;Often handled automatically by the font&lt;/li&gt;
&lt;li&gt;Improves visual consistency, not uniform spacing&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AV&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AV&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;kerning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACtklEQVR42u2XzWsaQRTAF7wXWpp48ewlf4FYNYiiRKOGCCoNCt6EVgK9KIVCC/0rcox68NAGSom1GAVLK0qxEHKTxIuCCWpA49fuOH1v3AULadyGORTaB4+dnXnzmzdfb98KwkK0er3+rc/nK0aj0Wo4Eq7t7T2txePxWvJlspZIJJgmk0moe87awuFwLRIJV/1+/8nGxsYbYKzJLOGRw+H4AUInkwnpdrt0PB5TlEwmQ2OxGN3f32eK5Ww2y9qm0ym9vr6m7XablMtlarfbq8B6IOh0uhelUonZXF1dSdVqlQyHQwLvBAYiYEQ0Gg1TLHs8HtaGg7daLZLP56Wbm5tpoVCga1rtMwHIqcvLSwSKhBA2+nw+Z89er0dPT0/p2dkZUyyjVyhoi3ayrQieUqPReCC43e53MAKrVEBqBe1lJ0Qc3GQyHSLwaDQa3QpUOizrbTbYt9/vIzAtwJr8FqjWS+yLS2GxWNLC9vb2e65Ar9f7SV5DiQvQ79/9AseEHxA25VieMh8gbMoHjsCUsMtnyhIem83NzSysoZ8LEGPA1tZWEXf5hMMuA7BHnU5nEdfwmAcQrx4AT7itYReAEJ1Kws6ObyVwKarcuSlWq/UjnsMCr5tiNptTd95l5b3RaNDz83PVN2VltLm4uKCdTueXQe4NlCSJYjuE/FvXUTVQKQ8GA1qv12mz2VQxZdNqD7FOFEXmKRegymPDgOwToAao9tj8B3IDuv61Kbu4A12uvxO4yL6epAX49N07P1wG4kcKEs5DwWazpeXgKS5npWpVSTgxgzUYDAfLOfYEDDBGkT9QSe4zzeVyVIs5NshD8PI7CGb/BLP72WymSjGKYx9I9KnZYqmwvwDlPwXkNWzQ50Aw8C0UClVQA0wDTEPsuagLsfdQJRgMfoU9yK+vr78CxmMk/QTXdFNIx9tobQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font kerning&quot; title=&quot;&quot; src=&quot;/static/d9d13d714db7e187e612293a46c8ea97/88c73/system-font-kerning.png&quot; srcset=&quot;/static/d9d13d714db7e187e612293a46c8ea97/772e8/system-font-kerning.png 200w,
/static/d9d13d714db7e187e612293a46c8ea97/88c73/system-font-kerning.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Logos or branding text&lt;/li&gt;
&lt;li&gt;Headlines where visual polish matters&lt;/li&gt;
&lt;li&gt;Short strings of text&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Letter Spacing: Tracking&lt;/h3&gt;
&lt;p&gt;Tracking adjusts the spacing uniformly across all letters in a word or block of text.&lt;/p&gt;
&lt;h4&gt;Characteristics&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Applies even spacing to all characters&lt;/li&gt;
&lt;li&gt;Often used for stylistic or readability purposes&lt;/li&gt;
&lt;li&gt;Affects the entire text range equally&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WELCOME&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WELCOME&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;tracking&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC+ElEQVR42u2XS0tbQRTHL7gvtFSzce3GTyA2D0SJGI0RA0moRLIUWgl0YygUWuincKlxkUUrlKJNiQlY0pCQUHziRnCR4INEER+JuePp+Y+5EDQJscyi0A4cZu7cM785c+bOmXM17a6Yenp6PrpcznggEEj7p/2ZqamXmdnZ2UzobSgzNzcnJRQKcd9r+c7v92emp/1pt9u91tvb+4EZnTWW9sxut//iQuVyWZyenqImlKWlJZqZmaFgMCgF7UgkIt9VKhU6OzujQqEg1tfXaWhoKM2sJ1p3d/ebeDwudU5OTvStrS1RrVYFPwueSLCS6OjokIK20+mU7zB5Pp8X0WhUv7y8rMRiMeo0mV5pTF48Pj4GsCqEoNvbWykopVKJNjc3aXt7WwrasArlnm6VLaX+/v55bXR09BPPIDsNULsF+gBjLCY3m80LAC5fXV01BBoD6qWRDsbC9wwMa+yTpsB2rcRYuMJqtYa1sbGxz0qB4+Pj32o+1JUA3e7JHxcXF+qAvCkrtSWrAfKmfFEIXNQm1SxZx2djs9ki7EO3EmCxWKSRkZE4dnlNwS4zsETDw8Nx+HBFBRBHj4FrynxYZCBHp4Q2MeFqCjSiyX1ptikDAwNf8R3GVJ0Ui8Wy2PQsIyLncjna2NggDqS0s7NDiOrZbJY4ALc8KQ2jDdp7e3sysB4cHND+/j5xNKfd3V3Sdf1xwJubG4JP4ApYc319LduooXt+fm4E1tZAQ+nw8JBSqZRcLiyDhbAM1iaTSVlj0odAc2MLAYZlRm0IlmqIodsWsE6x2a429KG8AlrdKY/9bP4DlQEd/9qSHcqBDsffCbzLvl6ENb76/jg/rAfikuKEc0EbHBwMHx0dPchg2xUj4UQG29fXNy9z7EQigc4yKyAUi0eIXhtTWV1dJRNybC5P2cos7gqOyAJ3CYJnO4K/BYxJp9NksVpT8i/A+E/h8p436LvH6/np8/lSEI8UjxSfrO/6fPLZl/J6vUneg2hXV9c7ZjwH6Tc8KUq7RFhEZgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font tracking&quot; title=&quot;&quot; src=&quot;/static/ea75d1e7ab18bbf9411e6b8aa2f1fd59/88c73/system-font-tracking.png&quot; srcset=&quot;/static/ea75d1e7ab18bbf9411e6b8aa2f1fd59/772e8/system-font-tracking.png 200w,
/static/ea75d1e7ab18bbf9411e6b8aa2f1fd59/88c73/system-font-tracking.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;All-caps text (improves readability)&lt;/li&gt;
&lt;li&gt;Buttons and labels&lt;/li&gt;
&lt;li&gt;UI headings&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Line Spacing for Multiline Text&lt;/h3&gt;
&lt;p&gt;Line spacing is the distance from one line of text to the next.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Default spacing is determined by the font&lt;/li&gt;
&lt;li&gt;Increasing spacing makes text easier to read&lt;/li&gt;
&lt;li&gt;Decreasing spacing makes text more compact&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&quot;
    SwiftUI automatically wraps text
    onto multiple lines when needed.
    Line spacing controls the vertical
    distance between those lines.
    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&quot;
    SwiftUI automatically wraps text
    onto multiple lines when needed.
    Line spacing controls the vertical
    distance between those lines.
    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineSpacing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The value is measured in &lt;strong&gt;points&lt;/strong&gt; and is added to the font’s default line height.&lt;/p&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADrUlEQVR42s2XW0sbQRTHF3wvtFTz4rMvfgKxSUQUxXjFQBIqEXwTWhH6YigUWuin8FHjQx7aQinalGjA0krWYL3h/X6/JN41MbtOz/+4G5LWNGq30IGzMzs785sz58ycmZWk62QqKCh4W19fP9DS0hJyN7vlpqancltbm+x56ZE7OjpYPB4P1T3nb263W25udofsdnt/YWHhG2LkaizpUUVFxQ9KIhaLqZFIBLlA6unpEa2traK9vZ0FZZ/Px9/i8bg4PDwUm5ub6uDgoCgvLw8R64GUn5//IhgMcpvd3V1leHhYPT8/V+ldpYFUaqTm5OSwoFxbW8vfMPjGxobq9/uVs7OzeCAQELkm0zOJyN0EAjChqiqPfnV1xXk0GhXj4+NicnKSBWVohYS2aKe1TZCmori4uFOqrq5+RyNwZUqDWyW01ZRIYHCz2dwF4AeaYhJ4U4dUuakN+h4cHADolcgmGYG31RJ9YQqr1eqVampq3hsKrKur+6zZUDEEaLc3fj09PTUOSE7p1aZsDJCc8tFAYLfUaMyUFSybkpISH9nQnga8j6AvYkBVVdUAvNxvgJcJGBWVlZUDsGGvDsTj5ORE7O3t8T4+OjoSmArK+/v74vj4mPcyBPWIOFpS0IaA/Wk2xGN5eVmMjIyIiYkJzhEQkENmZma4fmxsTIyOjvJAOjBCZYpOQamhoT4NSCGJoSsrKwyZm5tj0OrqqpienuYc7xhIi1JJp5SWln7COgykTnl9fZ076pqgDAA0mp2dZdD8/LwIh8NiaWlJB/KysVgs3Wl7GQ9oIMsyQwCDloiFgGAQXTvYN9NOSYs2iURC4B0Gv7y8TOaQi4sLfocoipIdiMf29jZPbXFxkacEWy4sLLBmiMqwL+rxXbP9n4FYHoDAOQABgM6oW1tbY5PoUCyjdKD5d+DW1hZ3QEfYDDB4GgMgBxQ57JuybDIDsRQAhHZwhK4VzAAtdfjU1BSviFQgHwG/ArFLAENn3X4A6mAI6tEOTsoKhOGx/jBVCJwB7QBEGbbDdLFF9eM0I/Bv4+GNQP3ozFa+NdAADW3/dsr/H9BmONBm+z+B17evJ16Jjr60++F9gQgUdOHsksrKyrw7OzvJG+xdz2R962HLFhUVdabesWPUAGFYvYMoWp94X1+fMOGOTekhaRnGoUPRQ00N+dkEfwvoEwqFhMVqHeK/AP0/hdJrctAXh9Px3eVyDUEcLA4WF+fXdS5+dw05nc5v5AN/Xl7eK2I8BuknkBclN698xaYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font line spacing&quot; title=&quot;&quot; src=&quot;/static/1f04a7fc996fcc4cc657a32cb0cade4d/88c73/system-font-line-spacing.png&quot; srcset=&quot;/static/1f04a7fc996fcc4cc657a32cb0cade4d/772e8/system-font-line-spacing.png 200w,
/static/1f04a7fc996fcc4cc657a32cb0cade4d/88c73/system-font-line-spacing.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Use Cases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Body Text (Articles, Descriptions)&lt;/li&gt;
&lt;li&gt;Headlines with Subtext&lt;/li&gt;
&lt;li&gt;Compact UI Text&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Baseline Offset&lt;/h3&gt;
&lt;p&gt;Baseline offset controls how text is shifted vertically relative to its baseline. The baseline is the invisible line on which most letters sit (like a, e, o), while letters such as g or y extend below it.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;.baselineOffset(_:)&lt;/code&gt; modifier lets you move text up or down without changing its font size or layout space.&lt;/p&gt;
&lt;h4&gt;What Does Baseline Offset Do?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Positive values move text up&lt;/li&gt;
&lt;li&gt;Negative values move text down&lt;/li&gt;
&lt;li&gt;Measured in points&lt;/li&gt;
&lt;li&gt;Affects vertical alignment, not spacing&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;HStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;caption&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;baselineOffset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;HStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;H&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;caption&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;baselineOffset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACn0lEQVR42u2XzWsaQRTAF7wXWpp4yTkX/wKxfiBKRBM1ZEGlYcWj0Aahl0ih0EL/ihyjHjy0gVKSWvwASysrhYL4DxgMJqCGxO/sOH1v3C0WUt2UOQTaB4+dnXnzm5n3dmbfCMJMjOvr62+DwWAxFovJUlSq7u4+re7t7VWTL5PV/f19pslkEuqeszZJkqrRqCSLolgwmUxvgLGisoRHGxsbP0DoYDAg3W6XjkYjipLJZGg8HqeJRIIplrPZLGsbj8f08vKSnp2dkXK5TN1utwysB8La2tqLUqnEbFqtllKv1wkACbwTGIiAETEYDEyx7Pf7WRvaNJtNksvllH6/P87n83TFaHwmADl1cXGBwBtCCBtde3Y6HVqr1SgMwhTLOCvNZjqdMsW+MFNqsVgOhM3NzXcwAqtUG3UL2quD3+DgVqv1EIFH4LtbgVqHeb3NBvui7wGYFsAnfwTqnSX2RVfY7fa0sLW19Z4rMBAIfFJ9qHABiuLOl16vxw8IQTlWl8wHCEH5wBGYEnb4LFnBz8bhcGTBhyIXYLvdpl6vt4hRLnCIMgA71OPxFNGHxzyAuPUAWODmwzYA4XQqCdvbQW5BcTqdH/E7zC9b8typsvCzsdlsqYV7WXtvNBoUDtPf6hbtlKWnjaIoumaoG3jXvbwUeHp6ynQ50KoPeHV1Ra+vr/kB9S6Z/QL+A+8l0PevLdnHHejz3U/gLPt6khbg1/fX+eE8EH9SkHAeCi6XK31+fv4rg9WyUr2qJZyYwZrN5oP5HHsEBgpmu3dQRe0zPjk5oUbMsUEewiy/g9DhcEgwu59MJroUbwvYR5ZlarPbK+wWoN1TQF5DgD6HwqFvkUikghpiGmIaYc9ZXYS9RyrhcPgrxCC3urr6ChiPkfQTDK5UmxTrRMQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font baseline offset&quot; title=&quot;&quot; src=&quot;/static/b41fb2d54924e9070b7e531450443c87/88c73/system-font-baseline-offset.png&quot; srcset=&quot;/static/b41fb2d54924e9070b7e531450443c87/772e8/system-font-baseline-offset.png 200w,
/static/b41fb2d54924e9070b7e531450443c87/88c73/system-font-baseline-offset.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Supporting Dynamic Type (Accessibility)&lt;/h3&gt;
&lt;p&gt;Dynamic Type allows users to choose larger or smaller text sizes in iOS Accessibility settings. Supporting it properly ensures your app remains readable, usable, and inclusive for everyone.&lt;/p&gt;
&lt;p&gt;System fonts is designed to work well with Dynamic Type by default—but there are important best practices to follow.&lt;/p&gt;
&lt;h4&gt;Use System Text Styles (Best Practice)&lt;/h4&gt;
&lt;p&gt;System text styles automatically scale with Dynamic Type.&lt;/p&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Body text&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Headline&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;These fonts scale automatically&lt;/li&gt;
&lt;li&gt;Follow Apple’s typography guidelines&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC20lEQVR42s2XzWtaQRDAH+ReaGn0krOX/AXBqkESDH5EQwSVBsVjoBWhl0ih0EL/ihyjHjy0gVJiLX5ASitqsZDk5C0QSQSNEI2a99bpzOZZLKhR2UMGhvfefvx2dnZ3dp4k3YtWp9N9dLlc2WAwWPAH/MWdnZfFUChUjLyNFPf29rhGIhEse83r/H5/MRDwF9xud2Z5efkDMhZVlvTMYrH8QYHb21t2fX0N3W4XSOLxOOzu7kI4HOZK74lEgtf1ej1oNptQrVbZ8fExrK+vF5D1RFpaWnqTzWZ5m8vLS+Xs7IzJsszwm+FADBuxhYUFrvS+ubnJ63BQdnFxwVKplNJut3vpdBoWtdpXEpKjtVqNgDJjDPr9PtCTpNFowMnJCeAgXOmdrCIZtCWlvmgp6PX6fclut3/CEXihWjm1DA0u0+AGg+GAgIfou5HAQYdhHdWG+pLvERiT0CdjgdNaSX3JFSaTKSY5HI7PQoFOp/Ob6kNFCNDt3v7RarXEAXFRjtQpiwHionwRCIxK22KmrNC2WV1dTaAP3UKA9XodrFZrllY5I2CVEdiAjY2NLPnwSASQjh4CMw/6cNRxG2khAjE65aStLddEYKVSgXK5DKenp3B+fj5xUcxm81fah+lJU6ayu7s7UBTlX1gbt22MRmNU/FkeF74G7xQ4S6USFAoFuLq6+q9uJuBAyL8Y6jns5uZmfgvnm7LhYSAtCDWmpzBgJpMBvN1A3Q1jfcivgGmmTNuFwOO21czAKU7KbMBJ0LmBwi2cAWh79BYKBtqEA222xwm8z75exCS8+ubOD4eBdElhwnkgra2txdTAKQ9npdPqIOGkQLyysrLPc+xcLkeFXWygUCyYQRW1Ty+ZTIKWcmyUp2jlbxTodDqMsnuKLNMo/S1QH7oejCZTnv8FDP5TUN7jAn33eD2/fD5fntTD1cPVx5/3ZT7+7ct7vd6fuAYpjUbzDhnPifQX53tPi7yB2GoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font accessibility best practice&quot; title=&quot;&quot; src=&quot;/static/0fac5068aa4b5605803068ed7a7f97e8/88c73/system-font-accessibility-best-practice.png&quot; srcset=&quot;/static/0fac5068aa4b5605803068ed7a7f97e8/772e8/system-font-accessibility-best-practice.png 200w,
/static/0fac5068aa4b5605803068ed7a7f97e8/88c73/system-font-accessibility-best-practice.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Avoid Fixed Font Sizes (When Possible)&lt;/h4&gt;
&lt;p&gt;Use system text styles whenever possible. Avoid fixed font sizes.&lt;/p&gt;
&lt;h4&gt;Example(Not Dynamic Type–friendly)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fixed size&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fixed size&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fixed size&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADPklEQVR42uWXzUtbQRDAH3gvtFRz8ezFv0BsEhFFMX5EDCShEvEotCHQS0Kh0EL/Cg8eYjxEaSolmKbkA61NSCgWJUEUT+JXSOK3Juat05k1C882PmN5B6EDw/ua/e3szO7sPkm6EV1LS8tHs9kcGx8fTznGHOnR0Zdpp9OZ9rz1pN1uN1ePx4PvXvNvDocjPTbmSFkslmhra+sHZDRWWdKznp6eXyhwcXHBisUilEolIJmZmYGJiQlwuVxc6d7v9/Nv5XIZjo6OYHd3ly0tLUF3d3cKWU+k5ubmN/F4nNvs7e3JKysr7PLykuEzw44YGrGGhgaudD84OMi/YadsZ2eHhcNh+fz8vByJRKBRp3slIXk6l8sRsHJ9fc17Z4zxK3m7trYGmUyGK92TV8KG7KttKugptLe3T0r9/f2fsIdbwHqF7KudV6hzvV7vJeBnjF1NoGig1Fo21Pbw8JCAPgljciewXi+pLYXCaDT6pIGBgYCmwKGhoa/VGMqaAC2Wke9nZ2faATEpC9UhawPEpHzREDgtjWgzZJmmTUdHhx9jaNEEWCgUoK+vL0ZZjmqQZQQWobe3N0YxXFADivWqWLc1gbT0EBjVLIYFBGJ1ikvDw2ZVIFWi7e1trhQntaR0dnYGaR5G1IZ8cnICWCdhf38fqJHatDEYDNN3ruVKpQIHBweAxRZoBKenp1yPj4/vXSk1qw15vby8DNFolGsikYDFxUWIxWJwdXV1K2F1AYXIsswBVAvJa1KlnSpQlP58Pg9bW1scRkKbFg2bvpOtsPsbqL8NFIDV1VWYm5uD+fl58Hq9MDs7C8lkEgKBAASDQZiamoL19XXl/lMbKIZCiRBeZrNZ2NjY4NOHrpubm3yzElNICeRbwH0xfEi1UQWKDCq3S+W9sK0bqLmHjwlo+t+GbNIcaDI9TuDN6euFT8Kt75/Ph0ogbVJ44PRKXV1dPqrMonz9ucvdp6I40Am2ra1tUnnGLqEB1S/2AJWrbcqhUAh0dMZGeYpe/kShssXodE8Vuh6lwkttUqkUGIzGJP8LEP8pKO8xQd+sNmvCbrcnSa1crVzt/Hrzzs6f7UmbzfYDcxBuamp6h4znRPoNJ99BS7HerDcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font accessibility not friendly&quot; title=&quot;&quot; src=&quot;/static/86b3dc8b6a8d938eb13ddc0492e455ba/88c73/system-font-accessibility-not-friendly.png&quot; srcset=&quot;/static/86b3dc8b6a8d938eb13ddc0492e455ba/772e8/system-font-accessibility-not-friendly.png 200w,
/static/86b3dc8b6a8d938eb13ddc0492e455ba/88c73/system-font-accessibility-not-friendly.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h4&gt;Example(Dynamic Type–friendly)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Scalable title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Scalable headline&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Scalable body text&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Output&lt;/h4&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 253px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADHklEQVR42uWXzUsbQRTAF3IvtFRz8ezFv0BsEpGIkg+NGEhCJWJvgVYCvRgKhRb6V3g08ZBDK5RimhINWJuYNdBEEg9iFESJQj4kms9dX98bd0uKWTVloUIHHjM7H795M2/mzVuOu07a/v7+DzabbX3uxVzCPevmZ2ae8/Pz87zvjY9fWFhg4vP5sO4Va3O73fzsrDtht9vXBgYG3iOjR2JxT8bGxn5igmq1KhYLRajX6kBpeXkZPB4PeL1eJlQOBoOsrdFoQLlchpOTE3FjYwNGR0cTyHrE9fX1vY5Go6xPPp8XksmkSGD8FnEiETuJGo2GCZUnJiZYW71eF4+Pj8VwOCxcXl42IpEI9Gi1Lzkk+8/OzgjYEkWRzS7nxWIRdnZ2IJPJMKEyaSX3ubq6YkJjUVMYGhpa5CwWy0ecgVVKjfdO1F+avEWT63S6JQKu4BI7AuUB7dKpD40tlUoEDHC4J4rA+2pJY2krDAZDgLNarZ9UBU5OTn6V9lBQBWi3T3+/uLhQD4hGWZWWrA4QjfJZRaCfm1ZnyQIdm+Hh4SDuoV0VYKFQAJPJtE5WXlPByggswvj4+Drt4aoaQLp6CFxT3EP54neSjhoiEL1TlJuasqlmlJGRkS90DiPtS5ahp6ensL+/D4eHh7C7uwsHBwdwdHQE6XQaKpXKH6uQj41er/ffuMsykHwkz/OwtbUFsVgMUqkU7O3tsbLkP28A5Ztyq7dR2LNbr95KJw1pWdvb20DvBeX05mxubkI8Hgd0/91rSGVBEKDVav12rnJZWUOdsoZUR8YgI9DeZbNZyOVyrE5ZQ52yhqTJ+fk50HGg5dMA+qa8Xct2IHsC7jJKN97mTmAXN+UfafhQgOb/bclm1YFm88MEXkdfzwIcPn1/HR+2A+mRwoBziTMajQFy93IEe9vj1EnkgJMi2MHBwcX2GLuOHQRyNF2III1phEIh0FKMjekxaomxehJqtZpI0X2z2byXkF+kMYlEAvQGQ5z9Bcj/KZjeoYG+OZyOmMvlipM4mDiYuFh+Xedi36640+n8gTYI9/b2vkXGUyL9AvpxRthe50wzAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;system font accessibility friendly&quot; title=&quot;&quot; src=&quot;/static/0d151b9639251a09a766f7e7abea433c/88c73/system-font-accessibility-friendly.png&quot; srcset=&quot;/static/0d151b9639251a09a766f7e7abea433c/772e8/system-font-accessibility-friendly.png 200w,
/static/0d151b9639251a09a766f7e7abea433c/88c73/system-font-accessibility-friendly.png 253w&quot; sizes=&quot;(max-width: 253px) 100vw, 253px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;SwiftUI provides a typography system that is both powerful and opinionated. By using semantic system font styles, applying font modifiers intentionally, and respecting Dynamic Type and accessibility settings, you can create interfaces that remain readable, consistent, and adaptable across devices.&lt;/p&gt;
&lt;p&gt;Custom fonts can be layered on top when branding requires it, but system fonts should remain the foundation for most user interfaces. Understanding how each font modifier affects text allows you to make precise typographic decisions while preserving accessibility and platform conventions. When used correctly, SwiftUI fonts help your UI communicate hierarchy, clarity, and intent without additional complexity.&lt;/p&gt;
&lt;p&gt;If you have any suggestions, feel free to connect with me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to Create a Signature Canvas in iOS Using SwiftUI and PencilKit?]]></title><description><![CDATA[Creating a smooth and natural signature experience is a small feature that can add huge perceived value to an app—especially in business…]]></description><link>https://www.sagarunagar.com/blog/create-signature-canvas-in-ios/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/create-signature-canvas-in-ios/</guid><pubDate>Mon, 15 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Creating a smooth and natural signature experience is a small feature that can add huge perceived value to an app—especially in business, productivity, and document-related products.&lt;/p&gt;
&lt;p&gt;While building my invocing app &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, I recently added a Signature feature using Apple PencilKit. This post explains why digital signatures matter, introduces Apple PencilKit, and walks through how to build a custom signature canvas in SwiftUI step by step.&lt;/p&gt;
&lt;h3&gt;PencilKit&lt;/h3&gt;
&lt;p&gt;PencilKit is Apple’s native framework for handling handwriting, drawing, and annotations on iOS and iPadOS.&lt;/p&gt;
&lt;p&gt;Although it’s often associated with sketching or note-taking apps, PencilKit is an excellent choice for building signature capture features.&lt;/p&gt;
&lt;p&gt;Key benefits of using PencilKit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smooth, low-latency drawing experience&lt;/li&gt;
&lt;li&gt;Native support for Apple Pencil and finger input&lt;/li&gt;
&lt;li&gt;Pressure and tilt sensitivity (Apple Pencil)&lt;/li&gt;
&lt;li&gt;High performance and battery efficiency&lt;/li&gt;
&lt;li&gt;Fully on-device and privacy-friendly&lt;/li&gt;
&lt;li&gt;Actively maintained and optimized by Apple&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the core of is &lt;code class=&quot;language-text&quot;&gt;PKCanvasView&lt;/code&gt;, a UIKit view that provides a ready-to-use drawing surface for capturing handwritten input.&lt;/p&gt;
&lt;h3&gt;What Does PencilKit Provide?&lt;/h3&gt;
&lt;p&gt;PencilKit offers a small but powerful set of APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PKCanvasView&lt;/code&gt;– A drawing canvas for user input&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PKDrawing&lt;/code&gt; – A data model representing the drawing&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PKToolPicker&lt;/code&gt; – Pencil, pen, eraser, and tool selection&lt;/li&gt;
&lt;li&gt;Built-in support for exporting drawings as &lt;strong&gt;UIIMage&lt;/strong&gt;, &lt;strong&gt;PDF&lt;/strong&gt;, or &lt;strong&gt;Data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These components make it easy to build features like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Signature pads&lt;/li&gt;
&lt;li&gt;Handwritten notes&lt;/li&gt;
&lt;li&gt;Document annotations&lt;/li&gt;
&lt;li&gt;Markup tools&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Using PencilKit in SwiftUI&lt;/h3&gt;
&lt;p&gt;PencilKit is built on &lt;strong&gt;UIKit&lt;/strong&gt;, while many modern apps—including mine—are written in &lt;strong&gt;SwiftUI&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To use PencilKit inside SwiftUI, we rely on:
&lt;code class=&quot;language-text&quot;&gt;UIViewRepresentable&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UIViewRepresentable&lt;/code&gt; allows us to wrap a UIKit view and embed it seamlessly inside a SwiftUI layout.&lt;/p&gt;
&lt;p&gt;Using this approach, we can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create and configure a &lt;code class=&quot;language-text&quot;&gt;PKCanvasView&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Manage its lifecycle&lt;/li&gt;
&lt;li&gt;Sync the drawing state with SwiftUI&lt;/li&gt;
&lt;li&gt;Keep the rest of the app fully SwiftUI-based&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Step 1: Create a Signature Canvas Wrapper&lt;/h3&gt;
&lt;p&gt;The first step is to create a custom SwiftUI view that wraps &lt;code class=&quot;language-text&quot;&gt;PKCanvasView&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;UIViewRepresentable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This wrapper is responsible for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating the canvas view&lt;/li&gt;
&lt;li&gt;Configuring drawing behavior&lt;/li&gt;
&lt;li&gt;Exposing the drawing data back to SwiftUI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typically, this includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementing &lt;code class=&quot;language-text&quot;&gt;makeUIView()&lt;/code&gt; to initialize the canvas&lt;/li&gt;
&lt;li&gt;Implementing &lt;code class=&quot;language-text&quot;&gt;updateUIView()&lt;/code&gt; to keep state in sync&lt;/li&gt;
&lt;li&gt;Using a &lt;code class=&quot;language-text&quot;&gt;@Binding&lt;/code&gt; to store the PKDrawing&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PencilKit&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignatureCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIViewRepresentable&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@SwiftUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; theme
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colorScheme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; colorScheme
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; exportedImage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; exportRequested&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; clearRequested&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;makeUIView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; canvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;frame&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overrideUserInterfaceStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;light
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawingPolicy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;anyInput
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alwaysBounceVertical &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;white
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isOpaque &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawingPolicy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;anyInput
        canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKInkingTool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pen&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;coordinator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvasView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; canvas
        context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;coordinator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvasView&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;delegate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;coordinator
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; canvas
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;updateUIView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; uiView&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        uiView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overrideUserInterfaceStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;light
        uiView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKInkingTool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pen&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// handle export request&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; exportRequested &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// Export the whole canvas bounds (transparent background preserved)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; lightTraits &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UITraitCollection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userInterfaceStyle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;light&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scale &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scale
            lightTraits&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;performAsCurrent &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uiView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insetBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dx&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dy&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// small padding&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; drawingImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; uiView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;from&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scale&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; scale&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    exportedImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; drawingImage
                    &lt;span class=&quot;token comment&quot;&gt;// reset flag&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exportRequested &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// handle clear request&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; clearRequested &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            uiView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawing &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKDrawing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// reset drawing&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clearRequested &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;makeCoordinator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coordinator&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Coordinator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coordinator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasViewDelegate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; canvasView&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
        &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;canvasView&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Binding&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;canvasView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; canvasView
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_isCanvasEmpty &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; isCanvasEmpty
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;canvasViewDrawingDidChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; canvasView&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            isCanvasEmpty &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; canvasView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strokes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isEmpty
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Step 2: Configure the PencilKit Canvas&lt;/h3&gt;
&lt;p&gt;Inside the UIKit view setup, you configure how the signature behaves.&lt;/p&gt;
&lt;p&gt;Common configuration includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allowing both finger and Apple Pencil input&lt;/li&gt;
&lt;li&gt;Setting a clear or white background&lt;/li&gt;
&lt;li&gt;Enabling or disabling scrolling&lt;/li&gt;
&lt;li&gt;Choosing the default drawing tool&lt;/li&gt;
&lt;li&gt;Optionally displaying the tool picker&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; canvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;frame&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overrideUserInterfaceStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;light &lt;span class=&quot;token comment&quot;&gt;// light, dark&lt;/span&gt;
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawingPolicy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;anyInput &lt;span class=&quot;token comment&quot;&gt;// default, anyInput, pencilOnly&lt;/span&gt;
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alwaysBounceVertical &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;white
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isOpaque &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tool &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKInkingTool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pen&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These settings ensure the signature feels natural and distraction-free.&lt;/p&gt;
&lt;h3&gt;Step 3: Integrate the Signature Canvas into SwiftUI&lt;/h3&gt;
&lt;p&gt;Once the wrapper is ready, you can use it like any other SwiftUI view.&lt;/p&gt;
&lt;p&gt;At this stage, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Embed it inside a &lt;code class=&quot;language-text&quot;&gt;VStack&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Form&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Control its height and layout&lt;/li&gt;
&lt;li&gt;Add actions like &lt;strong&gt;Clear&lt;/strong&gt;, &lt;strong&gt;Save&lt;/strong&gt;, or &lt;strong&gt;Done&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;React to drawing updates using bindings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes the signature feature feel fully native within your SwiftUI app.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;ZStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Visual border to show area&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;RoundedRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cornerRadius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StrokeStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lineWidth&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dash&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// dashed border&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tint&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// The PencilKit canvas&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;SignatureCanvasView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            exportedImage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $exportedImage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            exportRequested&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $exportRequested&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            clearRequested&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $clearRequested&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            isCanvasEmpty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $isCanvasEmpty
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clipShape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;RoundedRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cornerRadius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;of&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exportedImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; oldValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newValue &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; imageData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pngData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//USE imageData TO DISPLAY IMAGE ON VIEW&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;220&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 294px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 217.49999999999997%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAsCAYAAABloJjNAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC/ElEQVR42u1WW0sbURA+vvtQ6G+zYH9DaP+E0CexiL4rpaBSKQgWKpq0RmO0ChWtSeOtqeZqspvLXkyyu9P5xqwmMbSmSZ/qwpeZM2fOd2ZOzs6OCoVCT8LhyPj6eiTLcMPhLWJJkDMzb2h8/DVNTEwKoMPm+zTh7uzsZTc3o+PgUkw2HYsdUzC47szOvqX375doe3uP5ucXaXh4mJRSNDQ0JIAO28LCIm1tfaHl5Y80N/eOxsZeOZHIDkWje9OKlRR2YkJ3ZSVIa2ufZefV1U8UCLykkZFnNDr6XAA9EHghc/AJhcLiv7T0wQ0Gw9gkpTY2oo2DgzgdH5/T6WlSAP3s7CdlMleUTt8BYwA+Jyc/xC+ROGM9SYeHcQKXOj+/IMO4plLJYJis1wTV6rXA1307YJp1KpdtWWOaNbKsBqNO4FIwJhKnvHOOisUK6bohC1KpPKewK2e1v/9N/gic0+7uV7q4yIqfrleYuEqFgkaViinrVTZboFyuKMjnNXaweNKWBfm8Lri6KlE2W2zqusxhcSZTYFkmTSszqS5jVSiUxTmX08QRZMBduvdTxhjHg43880Vg4FKIqBU+YSe6zXWuBdTvSHrFI+F/RVit8kX2L/Ttxe5ua5Wdc7eEeskWaCWLNB06y5IvYbM6bHZzTbtNCDGoGHUy7QaZXDUMVA77RmJs+nqnbPGDBEeRN1b4cVyX+n3AgWwUQnVcT4xei4PXM6HHEdqI8I6wn8dlDpzrwAhvI2xNuV/Cgj7gCHHlFPJ2B0X4b85wkCmXhNAi+9qhRsOl+oPhtY2xFhxFzcJ32ZJQ/ffz5l1ul7d6qV222fSOanOvenQpT93mulabx0/AI2EfhP2SNwnNZjd6h78lFkJNqzYYPDDktmtapa3x7A1WAymn0GfHYt+deDzh3bS35V6IPOZwDP6M2nY9hZZ4yuPqxV28g+jQ2iLihxKiPa7VPAclzDCsKXV0dPQ0nc5PXl7mktz519CYI2X00H+CdB26UeMMkywnwfULvJ4A11RpNK4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;create signature view&quot; title=&quot;&quot; src=&quot;/static/0c2b10942ed261782e0771c9d5ce73ee/04a86/create-signature-view.png&quot; srcset=&quot;/static/0c2b10942ed261782e0771c9d5ce73ee/772e8/create-signature-view.png 200w,
/static/0c2b10942ed261782e0771c9d5ce73ee/04a86/create-signature-view.png 294w&quot; sizes=&quot;(max-width: 294px) 100vw, 294px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Step 4: Extract and Use the Signature Output&lt;/h3&gt;
&lt;p&gt;After the user finishes signing, the captured PKDrawing can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Converted into a &lt;code class=&quot;language-text&quot;&gt;UIImage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Exported as a PNG or PDF&lt;/li&gt;
&lt;li&gt;Stored locally or uploaded&lt;/li&gt;
&lt;li&gt;Attached to invoices, documents, or records&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This step turns a visual signature into something usable in real-world workflows.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;of&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exportedImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; oldValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newValue &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; imageData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pngData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//USE imageData TO DISPLAY IMAGE ON VIEW&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;p&gt;By combining &lt;strong&gt;PencilKit&lt;/strong&gt; with &lt;strong&gt;SwiftUI&lt;/strong&gt;, you get:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A smooth, responsive signature experience&lt;/li&gt;
&lt;li&gt;Support for Apple Pencil and finger input&lt;/li&gt;
&lt;li&gt;Clean separation between UI and data&lt;/li&gt;
&lt;li&gt;A future-proof, Apple-maintained solution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the exact approach I used to implement the signature feature in &lt;a href=&quot;https://apps.apple.com/us/app/id6744819252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Reckord&lt;/strong&gt;&lt;/a&gt;, and it works great. Here is output:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Create signature flow in Reckord app&quot;&gt;
    &lt;source src=&quot;/static/e7c0fc370a21f6a25658f36d691c1165/reckord-create-signature-flow.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;h3&gt;Closing Thoughts&lt;/h3&gt;
&lt;p&gt;Signature capture might seem like a small feature, but when implemented well, it adds significant trust and professionalism to an app.&lt;/p&gt;
&lt;p&gt;With &lt;strong&gt;SwiftUI + PencilKit&lt;/strong&gt;, you can deliver a high-quality signature experience using native tools with minimal complexity.&lt;/p&gt;
&lt;p&gt;Thank you for reading! 😀 Stay safe and take care!&lt;/p&gt;
&lt;p&gt;If you have any suggestions or a better approach, feel free to connect with me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SwiftUI App Localization in Xcode — Easy, Scalable]]></title><description><![CDATA[Recently, I updated my invocing app Reckord to support 24 different languages as part of my ASO strategy. Localization not only makes your…]]></description><link>https://www.sagarunagar.com/blog/swiftui-app-localization-in-xcode/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/swiftui-app-localization-in-xcode/</guid><pubDate>Wed, 13 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, I updated my invocing app &lt;a href=&quot;https://reckord.app&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Reckord&lt;/a&gt; to support 24 different languages as part of my ASO strategy. Localization not only makes your app more accessible to a global audience but also increases your chances of ranking in non-English App Stores.&lt;/p&gt;
&lt;p&gt;Here’s exactly how you can do it — in 7 simple steps.&lt;/p&gt;
&lt;h3&gt;1. Create a String Catalog&lt;/h3&gt;
&lt;p&gt;First, Create a String Catalog in my Xcode project:&lt;/p&gt;
&lt;p&gt;In the Resources folder, right-click → New File → search for “String Catalog” → name it &lt;code class=&quot;language-text&quot;&gt;Localizable&lt;/code&gt;.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 71.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA00lEQVR42u1UfwuDIBT0+3/OMSpHv9TUrG6eQ6goWKw/d/C4eviuUzpF26vwlDXKokBZlqmqqkLXdXDOwXuPYRgQQsA8z5tiXykFrTXGcSR7YdyEx8uib1tYG7nvE1OMC3NvmiYsy7KppmnSx6WUyQDfBRdqrdApgzU4sOejWoOOxRwFQ7QvleUYjrAfPOsbYz4O27hdnh239guSw3w2POQzJ5cF78Jf8CbBGKnlLkEmS/B3yTm9gnVSMjOuItr0zGJd1+ki+LaYCl4MzDqfydGhewN5RFH8Y56XAAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;create string catalog&quot; title=&quot;&quot; src=&quot;/static/a077bda2ab926d3a8be801e67a9eeccf/5a190/create-string-catalog.png&quot; srcset=&quot;/static/a077bda2ab926d3a8be801e67a9eeccf/772e8/create-string-catalog.png 200w,
/static/a077bda2ab926d3a8be801e67a9eeccf/e17e5/create-string-catalog.png 400w,
/static/a077bda2ab926d3a8be801e67a9eeccf/5a190/create-string-catalog.png 800w,
/static/a077bda2ab926d3a8be801e67a9eeccf/5a6dd/create-string-catalog.png 802w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;This will serve as the central place for all your translated strings.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 64.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA2UlEQVR42u1TwQ6CMAzd/x/0G/wMNR78BzHRO5EYBwJjYx3jyaZEgsABPdrkpWnXvr1lLYuTO5HKcQo5TpFEIgm6lChKjaIo0Jwjy3NYayehlIIQgtguEFjtb1huEyzWVyw3HBHPYSoDVZYNmfDFWmukaQop5SBcjQO7JIRzZBCEGoeQcGy8Jou+1XWNqqq8H4MxBszJHWqeY47LE7r+Lqz9kvDnCv+Eg4Qu9/zA95jMJnTz57cmjsE598iyzM/dB+GYmn48hn4da26h9jktnKJu3DZP5V6bQg+r6gFQuWPBtAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;empty string catalog&quot; title=&quot;&quot; src=&quot;/static/cb97eb449a7a78a1eab911f7c0d9359c/5a190/empty-string-catalog.png&quot; srcset=&quot;/static/cb97eb449a7a78a1eab911f7c0d9359c/772e8/empty-string-catalog.png 200w,
/static/cb97eb449a7a78a1eab911f7c0d9359c/e17e5/empty-string-catalog.png 400w,
/static/cb97eb449a7a78a1eab911f7c0d9359c/5a190/empty-string-catalog.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;2. Convert Static Strings into Localised Strings&lt;/h3&gt;
&lt;p&gt;Next, Replace all hardcoded static strings in your SwiftUI views with &lt;code class=&quot;language-text&quot;&gt;String(localized:)&lt;/code&gt; so they are ready for translation.&lt;/p&gt;
&lt;p&gt;Here’s an example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    localized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create_organisation_view.create.title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;New Organisation&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Localizable&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    comment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title for create organisation screen&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;localized&lt;/code&gt; → The key for your string in the String Catalog.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;defaultValue&lt;/code&gt; → The text for your base language (English in my case).&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;table&lt;/code&gt; → The name of your String Catalog file.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;comment&lt;/code&gt; → Extra context for translators (and AI tools).&lt;/p&gt;
&lt;p&gt;💡 Pro Tip: Create a constants file to make localization scalable and maintainable.
Here’s how I structured mine:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Constants&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CreateOrganisationView&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; createOrganisationTitle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            localized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create_organisation_view.create.title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;New Organisation&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Localizable&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            comment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title for create organisation screen&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; editOrganisationTitle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            localized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create_organisation_view.edit.title&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Edit Organisation&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Localizable&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            comment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title for edit organisation screen&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; organisationNamePlaceholder&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            localized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create_organisation_view.organisation.name.placeholder&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            defaultValue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;What is organisation&apos;s name?&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Localizable&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            comment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Placeholder for organisation name filed in create/edit organisation screen&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;3. Build the Project to Populate the String Catalog&lt;/h3&gt;
&lt;p&gt;Once you replace all static strings, build the project(Product → Build).&lt;/p&gt;
&lt;p&gt;Now, when you open the Localizable String Catalog, you’ll see all your keys under the English column.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 39.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA9ElEQVR42o1Q7W6DMAzM+z/Y3mF/EKx8pUCgQIAByc32mhaxTqqlS2yffbGjdGW2wVpcyiu67gZd1ajqBvF1wMcn3bqHdw47Y98fcC/idV139ZUWKMoSLYmZtsU4TUICngo3eO8IHtu2SZ79IBaMcyGvpJBI756NdV2jMQbGtGiaRnJaa2RZFiaRmDmuHYZBhEXwd5qn8ctpmiKKIhRFgTzPsSwLiRsR7LoOfd8jSRLEcSw5FmZRxh9BjidaexxH8cOax7V4Yuan+/cc/1PR4c8NZzvyIX5l1OvVmfyv+B3jXmWtXeZ5lvEZFD/8d8E9rEH39w/GmXAx10+NYwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;full string catalog&quot; title=&quot;&quot; src=&quot;/static/9667600fde778406e371a9561ac59e8b/5a190/full-string-catalog.png&quot; srcset=&quot;/static/9667600fde778406e371a9561ac59e8b/772e8/full-string-catalog.png 200w,
/static/9667600fde778406e371a9561ac59e8b/e17e5/full-string-catalog.png 400w,
/static/9667600fde778406e371a9561ac59e8b/5a190/full-string-catalog.png 800w,
/static/9667600fde778406e371a9561ac59e8b/5a6dd/full-string-catalog.png 802w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;4. Add New Languages to Your Project&lt;/h3&gt;
&lt;p&gt;To prepare for translations, go to: &lt;strong&gt;Project Settings → Info Tab → Localizations → +&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add all the languages you want your app to support.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHklEQVR42oVSa2+DMAzM//+F+zpBNRVCCI8E8sL1pQR1dKyWTiTYPtvniJ+2j62e6eseqNaJYtqIto1SSpcIMZEPkbz3FPZvjJGMMU7MxvIlUDYmgnNdVz5ubyjmItFgA5l5zrHTNIEsQ3zfGqrqmrQecrWu6/is6WzoYBzH7LPW0l8GctFKySSKyUJG3/e/xiudFR+AKc4yIA6FhOU2l2U5xgr7yBh/8ayVD+Scy4SfLHd4aINF8LHVlqRsaWZ9GjVSp1QeFXcQIwkdXRIWZ+lQqZ6GYdhDntt+bjO8LedfwqJT0zSZoCSXZVRVdRS6egGQTrxWLISBSV7/owAI8QI+asisDtqA3TKkNqyhzMnoCEEASIuGZyAXfp5keQAtaQ/1iAngwgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;add localization language&quot; title=&quot;&quot; src=&quot;/static/5fa10db7a7b7b6451aa9a7c786030f12/5a190/add-localization-language.png&quot; srcset=&quot;/static/5fa10db7a7b7b6451aa9a7c786030f12/772e8/add-localization-language.png 200w,
/static/5fa10db7a7b7b6451aa9a7c786030f12/e17e5/add-localization-language.png 400w,
/static/5fa10db7a7b7b6451aa9a7c786030f12/5a190/add-localization-language.png 800w,
/static/5fa10db7a7b7b6451aa9a7c786030f12/adc48/add-localization-language.png 979w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;5. Export Localizations&lt;/h3&gt;
&lt;p&gt;Go to Product → Export Localizations… in Xcode.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 382px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 157.50000000000003%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAYAAAASYli2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEoklEQVR42n1WaW/bRhTUb8/3ov0SFAUMFEhSJECLAEY/tG7TFm6dRrZ1WrdIiocuipdIXZZlW9N5S8mWZbkCBtwlucN5782+Veb7j9n49Zvf8ea4sP7q6Be8+vo9Xn3zAUc/ZvHd+7/w+u0JPv7RwNvjc3z77jfiBD+ftvHumM9/OOH1M06y5vrowyf89Gs+zpSbPRTrFnKVDv48K+LT6SX++XKF82IbubKO80IDBT4rVAxk8w1cFJsoN2wUqjKv46LURt0YotJyUNe6yOh6e32zusEkSWBbFizTxGI+x3QyIaaYTaeb8YTjmboXJxME4zH6Iw+jIMBilmB9f4fZbIZMwodhxIeDIYauh37fhe9H8IMIwQYy345HxJBwvAAG19QdFyUrgZesMKOQzJysYeDDcbowDBOXl3lomoE4niiCMBw/gUe4hOOFMF0XZcfHqbbEaA7c3q6QGc1XKIYrdC0TluWgXK6g0WgdJNvCJ+yBC6M3gNHtQWu34ZL85uYGmcl8gWi+hO95Slk2e4FCoQSPIUVR/CKpPB8RkqZ4HFPdbUrYMQyYHQNtfmXAr4pK2+4yb+EDgp18biGk8kEhXi6XkJ8iXCwWWHIQBKHKYaVSU0pd10eSTNXClwhFgGBLuFoxh3d3d2oyoR3q9RbOzy9RLJY5bqJWa7Dqw2ehC+F4nKDHHArELhKyss2WMI5jtdhxeipkCV0UD4ejgwoFEq6sMendXq8HXdcfCcWPEmqxWFKKZrMFVc9eDNv3U7IBvWjbtqqyiNoj1JHPFxhqnfa5UvaRa7fbVx8JwugBkjshFIi6MAz5TrQbcqIWSpimabPq+sNV8rRL6LOAcq/fSxVKqBK2pmlPc+iqrTdUeRMFskjG+x7c5m808glPFeP+/l5V+4nClKT/QCjksvCQsbfW2fXhE9uIQvmiqBRLyF7eQua7hdkSybtSnBcIE2WVZrOt8tjpmKrqrZa2Mbq3U+FQRSGQkA8SJuyHnY6lDK3rHQWpeqvVVqSiXmykmgMJ05S4G8Lrw4QmCUVhu62hVq0r0iatY7HaGqtdZNMQojSPm9D5oevrQ4TsyBpDzeWLKJR4BFzmULqq4iJX4LyMMscWd5BHdSHzGkpeCY8WOhwyHwyorENlNsM2ee0xXKfR5FVT84k7QkQXRN1H+Mz7NRvM8+bArWOyKVQZli4dh6hQZY07p0mFAYnC/mCDYQrZ5yzYkufOc0IeNgYJc3+foZ7Lo8FQi2f/ovT5Cypsuh7zOJYds6Mu4tw3LSwPKYxZlD5DMrjQ4Ysm89VmUQwWqsN7Qybf37T/LQJpsLTRy7bZNNgqEXHBhJ0mZuK3xg7F1BvI84F0G6bgRUKxiXQXIW2wGGLm3W22C2kWacceqtZ/oGNPVGfJMX/StcXgYuD9LbfbsdP29T8KxfmWzU5NpbIz4nhKJWO1WLB/pkgELvO+T7je3XpV+k0aq4RcrdbUuSIpkB2037XTU+9xpzD0dUb6mPzm/BthWbbav4bRUdB1HrG0hVxlLmr24fu+OqDkJ1c5RiMJe7GYr6fyx2gH0tIkt7NZOk+S+BnkPhWuU45F9B+trUi5etVUNQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;select export localizations&quot; title=&quot;&quot; src=&quot;/static/d68b8ca21edcba0a330e0b2d3163c07e/77edc/select-export-localizations.png&quot; srcset=&quot;/static/d68b8ca21edcba0a330e0b2d3163c07e/772e8/select-export-localizations.png 200w,
/static/d68b8ca21edcba0a330e0b2d3163c07e/77edc/select-export-localizations.png 382w&quot; sizes=&quot;(max-width: 382px) 100vw, 382px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 64.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABrklEQVR42o2T+W6CQBDGef9n6Ks0Tf/oldiqYFcOBds0GixHUe5l+bqzEYq2mk4yWWB3fnxzrGbZTm1ZNmzbQRCEaNsWTdOotSxL5HmOKIqw3W5RFAXqugY/OJ0TQvSr3OPalHkYPY/BGJOBMcgI1oEJWpSVWtWPKJATRNBJDI2g2t1ohuubW9w/PMKXKgiUpin2+z1S6bVosY4SxFEo1RYUhveIY5dzNLxGlmVKNcE459CYuYBuzMBemUptqHColAK6dyF+fyejd82UtZvPTdiW06d8ahR07nsH61M2nCVexhOYpnUWSH/+N9Bhc7hLF97qDWH4kzJtXvIh8Chl93UKQ9exlNChQupqGHwiTHIYqwhJHCJJdojjWDWBxulUuVK4sF8wmYx/ATsrOGB9fCFPd716MpqCP4Ej2RDqsuet+i4PjQA0DqSKVNNzV5L+zMEVkBlybPQZXM/ra3g6OpWEVVWlbgqtw72haiGaVjOlwulUh+t6qj6HK3TUvXPWqkZwZJWAJ6v1mVKXnUVJc0hj4/u+VBlis9moolOKlzyjex74sNe79uqpxK2TVd9jr+xpKT4tjAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;export localization dialog&quot; title=&quot;&quot; src=&quot;/static/f540d8baa879dae65b6b777d9eeefdd9/5a190/export-localization-dialog.png&quot; srcset=&quot;/static/f540d8baa879dae65b6b777d9eeefdd9/772e8/export-localization-dialog.png 200w,
/static/f540d8baa879dae65b6b777d9eeefdd9/e17e5/export-localization-dialog.png 400w,
/static/f540d8baa879dae65b6b777d9eeefdd9/5a190/export-localization-dialog.png 800w,
/static/f540d8baa879dae65b6b777d9eeefdd9/5a6dd/export-localization-dialog.png 802w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;You can open this .xcloc file in Xcode to review it. It will contain all your string keys and their English values.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABTklEQVR42p1Sy07DMBDM/9+58AN8A4fe+QIk1AOHqmnzapw4ju34MXicFgICIVhpte/Z8cpFW5f+tRvxclKQk4KadbITtDFYliWpg1QzpJxgU2yshbVLrtnsr7FzHpdL7wqRAjEMWJzNauzaGGOE9z41OsQQEK5q0iKjNXRSgrKur/E0SRQPTwJ3jyXudw12zwpWKwgx5OZxHNG2LYa0kL4QIg1NUEqhrutcY86YBGgs2n5EIbVHJxecWgk5O1RVhf1+nzfetm+ZkCGZns9nHA4H9H0PSkzajzMKFnMixmy7rkNZlnmQTMiANZ6Bw7SUpmkyw3UunSdE1Be5AjIVwgrI5x2Px/VWV1AOkSGfS7ZbQOYJyPHLMH0w3LKkvfk/CeuZzKaPBD4Bbv3vgH9bwhsXwbv3wa+Af5XMsOrGYPScPvScN/Dv/Ud523R//wbxcAwtX+JsVgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;xcloc file opened in xcode&quot; title=&quot;&quot; src=&quot;/static/7d7daeeaf11e559c53d19fce11e5f70b/5a190/xcloc-file-opened-in-xcode.png&quot; srcset=&quot;/static/7d7daeeaf11e559c53d19fce11e5f70b/772e8/xcloc-file-opened-in-xcode.png 200w,
/static/7d7daeeaf11e559c53d19fce11e5f70b/e17e5/xcloc-file-opened-in-xcode.png 400w,
/static/7d7daeeaf11e559c53d19fce11e5f70b/5a190/xcloc-file-opened-in-xcode.png 800w,
/static/7d7daeeaf11e559c53d19fce11e5f70b/f5209/xcloc-file-opened-in-xcode.png 1061w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;6. Translate Your .xcloc File&lt;/h3&gt;
&lt;p&gt;Instead of translating manually, You can use AI-powered localization tools(strings.dev in my case).&lt;/p&gt;
&lt;p&gt;Some great tools include: &lt;a href=&quot;https://localizebot.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;localizebot.com&lt;/a&gt;, &lt;a href=&quot;https://www.strings.dev&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;strings.dev&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Upload your en.xcloc file.&lt;/li&gt;
&lt;li&gt;Select target languages.&lt;/li&gt;
&lt;li&gt;Download the translated .xcloc files.&lt;/li&gt;
&lt;/ol&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 72%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACB0lEQVR42n1Ty67TMBDNf8MPsEBs+YC7RUJsWCIkQGKFeAkBFbS5TdMmzdOx49fk3LHbXFWE3kmOHDvj4zkz40QbQ1mWYbVaoTo2cBqYpgmXFuYPAWd/55xPlLQYOne/2U+EuutwKKoIISSscwy/hPVM4tGOEs04wHmPRCmNdJtDaxMJiU9rRI/bLI84lEeMxsARb/buTO5grItrntFryVAhQiTjqJHvC4QxRmgniMrCjRPIAnZgKea01h8N7AiogUn1ea0yII5l6AyUNEikVNju9tgfSvSDgBIO2989ZEMYO4KqCXog/PhYoNhI6B6QrYPqPXbsV2UjtAC6o4UUTDiy1LYTUWpIMBGPPiSaXzqBeG45Su+mqGBeD4hp8gwug+OcJkSEfy3Pj0g3OTbrHfKsxMnlVMlRa6w36T3+/F2jKMu5ykvCEKUaLETDaE9jiG62kOufv1ZMUqGuW9QNo27ivlDx/xISa5kCzk/wCc4xHdOyT2e7Shh6rG8Nqr1GWQrUbQ9tHLynuYeXzf0QYegxpbjhWbqUGoplmgvCWJDpAuf5VcIplo+i1AgmCmSz5Gu2IJyd1yXhSxpuARb/qtzg5tEtXjzZ4eXTHK+e7XHzeIvXzw98KBNaayl8zCBuqIKrm5aGpdvYChGchnDNwo34+rbGt3cNvr9nfGjw+U2N1aeO02L8HfkgQA97SP/dAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;translation tool&quot; title=&quot;&quot; src=&quot;/static/1aa68251be063d83f2720f978fee033d/5a190/translation-tool.png&quot; srcset=&quot;/static/1aa68251be063d83f2720f978fee033d/772e8/translation-tool.png 200w,
/static/1aa68251be063d83f2720f978fee033d/e17e5/translation-tool.png 400w,
/static/1aa68251be063d83f2720f978fee033d/5a190/translation-tool.png 800w,
/static/1aa68251be063d83f2720f978fee033d/aa61c/translation-tool.png 1065w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;7. Import Translations Back into Xcode&lt;/h3&gt;
&lt;p&gt;Go to Product → Import Localizations… in Xcode.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 382px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 157.50000000000003%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAYAAAASYli2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEjUlEQVR42nVWa28aVxTkt+d71X6JqkqWKiWpEqlVJKsfWrdpqyhxgm2eBvPcZR+89s0uLBiwzfTMxTiAAWm0e1nu7Jxz5pxL5uf32fjlq7/x6rSw+u7kD7z4/i1e/PAOJ79m8dPb//Dy9Rne/1PH69ML/PjmL8EZfv/YwptTef7LmVzPcZY1VifvPuC3P/NxptzooVgzkat08O/nIj58vMKnr9e4KLaQK2u4KNRRkGeFio5svo7LYgPluoVClesaLkst1PQhKk0btXYXGU1rrRbLBcZJAss0YRoGZtMpJuOxYIJ0Mnm8H8t9qr6LkzGC0Qh914MbBJilCVYP90jTFJlEHoaRPBwMMXQ89PsOfD+CH0QIHsH15t4VDAW2F0CXPTXbQclM4CVLpCIkMxXWMPBh213ouoGrqzzabR1xPFYEYTjagSdwBLYXwnAclG0fH9tzuFPg7m6JjDtdohgu0TUNmKaNcrmCer15kGwDX2ANHOi9AfRuD+1WC46QLxYLZMbTGaLpHL7nKWXZ7CUKhRI8CSmK4qOkfO4KmKZ4FIu6uzVhR9dhdHS05C0DeStVWlZX8hY+IdjK5wYk5QtJPJ/PwY8inM1mmMtNEIQqh5XKjVLqOD6SZKI2HiOkAGJDuFxKDu/v79ViLHao1Zq4uLhCsViW+wZubupS9eGz0Ek4GiXoSQ4J2oUhK9tsCOM4Vpttu6dCZuhUPBy6BxUSDJd7DPFur9eDpmnfCOlHhloslpSiNJ2J6vRo2L6/JhuIFy3LUlWmqD1CDfl8QUKtiX2ulX147Xb76iVBGD2BuSMhQXVhGMpvou2QE7WRYRqGJVXXnq7M0zahLwXkd/3eWiFDZdjtdns3h45qvaHKGxVwE+/3PbjJn+v6Ak8V4+HhQVV7R+GapP9ESHJuPGTsjXW2fbhjGyrkG6mSlmAvb8D1dmE2RPwti3OEMFFWaTRaKo+djqGq3my2H43ubVU4VFEQDPkgYSLzsNMxlaE1raPAqjebLUVK9bSRGg5CuE6J80h4e4hwrKpKhawsrUNSWoffk5weJdHukPBxe3uEkKHlcnk1bdiC5dI1ri5zas2xxpTsF4mER3PYk6pq9CHbTsK3xJeGZcOmP2UdS9cELM4W+ILDCqXKuoRbFVXtegNtyWVFlFVLZdQrVfhDB4HjKoRSoA08MfZBwonropMrIPfpHDU5BupyX/z8BaXzr7iWoetJHkd96Rjx6RNkHUiaFmLs5+NLmtsRZYaMrJ5U1RKF+nUFneoNTCmQZ5iIZNzvQDop1IRwmh6xjVS1IsmvClEkfhvT2NLDRCRWCbfA5wNR2Rcc9SFtUhLCSrWm/OiI90I1FJ63HofF4LFFF4uDE3us/Efb0DIkpIH3W257Yq/H1+C4QjrfFJvoopSdEccTUTJSm4n9M4Xt6EjV9wlX261XlXDZHXUpUFUKwnOFBxc7aH9qr0+9b50ip94qwznGz1T+RpjmusV0vaOgSQUNqS6vXFPNPnzfVwcUP7zyGI0Y9mw2XU34x2gLHGnMbZqu10kSPwO/F4WrNccs+h+uZ0iy7wV/CgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;import localization dialog&quot; title=&quot;&quot; src=&quot;/static/3bd52878a973ccd750e114ad3a4aabaa/77edc/import-localization-dialog.png&quot; srcset=&quot;/static/3bd52878a973ccd750e114ad3a4aabaa/772e8/import-localization-dialog.png 200w,
/static/3bd52878a973ccd750e114ad3a4aabaa/77edc/import-localization-dialog.png 382w&quot; sizes=&quot;(max-width: 382px) 100vw, 382px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Select the .xcloc file you downloaded from the translation tool.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Xcode will merge these translations into your String Catalog.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, your Localizable catalog will show translations for each added language.&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;p&gt;Your app now supports 2 different languages(French, Japanese) — and You can easily add more in the future using this same process.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 27.999999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA10lEQVR42qWQzXKDMAyEef936aGvkVPPoTkyBDpgT2z8I4w3rBra5NBTxexYktcfspvBeHyZG9ox4moznHOIMYGxbduPaq0vtYhgXVcVc8rdXG3eThbvHx69cSgSkbIg5wzvva4MHooxKohRSoG1Fikl9XBPc8loQq6IAvgloD23OiFNXddhWRYF0Nz3PeZ5VhjBzMdxxDRN3zfYv1x2IB7BQ5+XC4wxaiAshKAAijl79LEehkGB9PM5KCnyCzya/wkO0vCPfANOwPUQ6+feUf/lI2e/wXYHZvzTUKXBdPUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;translated string catalog&quot; title=&quot;&quot; src=&quot;/static/1afd5c755752e95f37a6d3442b283184/5a190/translated-string-catalog.png&quot; srcset=&quot;/static/1afd5c755752e95f37a6d3442b283184/772e8/translated-string-catalog.png 200w,
/static/1afd5c755752e95f37a6d3442b283184/e17e5/translated-string-catalog.png 400w,
/static/1afd5c755752e95f37a6d3442b283184/5a190/translated-string-catalog.png 800w,
/static/1afd5c755752e95f37a6d3442b283184/c1b63/translated-string-catalog.png 1200w,
/static/1afd5c755752e95f37a6d3442b283184/d4b10/translated-string-catalog.png 1394w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;This way, you can scale your app and keep supporting new languages without a huge manual effort.&lt;/p&gt;
&lt;p&gt;Thank you for reading! 😀 Stay safe and take care!&lt;/p&gt;
&lt;p&gt;If you have any suggestions or a better approach, feel free to connect with me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and send me a DM. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to add SegmentedControl in List that scrolls with a List in SwiftUI?]]></title><description><![CDATA[When building apps with SwiftUI, you might need to add a SegmentedControl on top of a List that scrolls along with the list. Usually, you’d…]]></description><link>https://www.sagarunagar.com/blog/scrollable-segmentedcontrol-list/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/scrollable-segmentedcontrol-list/</guid><pubDate>Mon, 13 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When building apps with SwiftUI, you might need to add a &lt;strong&gt;SegmentedControl&lt;/strong&gt; on top of a List that &lt;strong&gt;scrolls&lt;/strong&gt; along with the list.&lt;/p&gt;
&lt;p&gt;Usually, you’d think of placing the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; inside a &lt;code class=&quot;language-text&quot;&gt;VStack&lt;/code&gt; and adding a &lt;code class=&quot;language-text&quot;&gt;Picker&lt;/code&gt; with the &lt;code class=&quot;language-text&quot;&gt;.segmented&lt;/code&gt; style above it, like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;spacing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Picker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Conact type&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selection&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $genre&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Genre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allCases&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; genre &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;genre&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;textCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pickerStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;segmented&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;horizontal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uiColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;systemGroupedBackground&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;songs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; song &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;primary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this approach doesn’t give the desired result:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Flowers are in bloom&quot;&gt;
    &lt;source src=&quot;/static/5ba01664678616c2f09fc5c9b764d437/scrollable-segmentedcontrol-list-1.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;h3&gt;The right way: Using a SegmentedControl in the List header&lt;/h3&gt;
&lt;p&gt;Instead of adding the &lt;code class=&quot;language-text&quot;&gt;Picker&lt;/code&gt; in a &lt;code class=&quot;language-text&quot;&gt;VStack&lt;/code&gt;, you can include it in the List&apos;s section header, like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;songs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; song &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;primary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; header&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token class-name&quot;&gt;Picker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Conact type&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selection&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $genre&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Genre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allCases&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; genre &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;genre&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;textCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pickerStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;segmented&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This gives a much better result:&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Flowers are in bloom&quot;&gt;
    &lt;source src=&quot;/static/d815500e4af7d6657923708b1f9eb9a7/scrollable-segmentedcontrol-list-2.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;h3&gt;Removing extra space&lt;/h3&gt;
&lt;p&gt;You might notice unwanted spacing around the &lt;strong&gt;SegmentedControl&lt;/strong&gt;. To fix this, apply the &lt;code class=&quot;language-text&quot;&gt;.listRowInsets(EdgeInsets())&lt;/code&gt; modifier to the Picker:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;songs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; song &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;primary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;song&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;foregroundStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; header&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Picker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Conact type&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selection&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $genre&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Genre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allCases&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; genre &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;genre&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;string&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;textCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pickerStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;segmented&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listRowInsets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;EdgeInsets&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vertical&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s the final output: a &lt;strong&gt;SegmentedControl&lt;/strong&gt; that scrolls seamlessly with the list.&lt;/p&gt;
&lt;div style=&quot;text-align: center; margin-bottom: 1.45rem;&quot;&gt;
    &lt;video controls muted alt=&quot;Flowers are in bloom&quot;&gt;
    &lt;source src=&quot;/static/3ad2233aeef3d3a4a0c4c0a5bb3e3e43/scrollable-segmentedcontrol-list-3.mp4&quot; type=&quot;video/mp4&quot;&gt;
    &lt;/video&gt;
&lt;/div&gt;
&lt;p&gt;Thanks for reading! If you have any questions or suggestions, feel free to send me DM on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt;. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sign in with Apple - SwiftUI, MVVM]]></title><description><![CDATA[Sign in with Apple is a new way to sign in to your app just like facebook and google with all apple privacy and security. Sign in with Apple…]]></description><link>https://www.sagarunagar.com/blog/sign-in-with-apple-swiftui-mvvm/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/sign-in-with-apple-swiftui-mvvm/</guid><pubDate>Wed, 17 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sign in with Apple is a new way to sign in to your app just like facebook and google with all apple privacy and security.&lt;/p&gt;
&lt;p&gt;Sign in with Apple is the fast, easy, and more private way to sign in to third-party apps and websites using the Apple ID that you already have.
Sign in with Apple is built from the ground up to secure your privacy and personal data. At your first sign-in, apps and website can ask only for your name and email address to set up an account for you.&lt;/p&gt;
&lt;p&gt;You can also hide your personal email address from the app or website. if you choose to hide your personal email address then a unique, random email address is generated so your personal email address isn&apos;t shared with the app or website developer during the account setup and sign in process. This address is unique to you and the developer and follows this format: &lt;strong&gt;&amp;#x3C;unique-alphanumeric-string&gt;@privaterelay.appleid.com&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s implement Sign in with Apple using SwiftUI by following MVVM architecture.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the signing &amp;#x26; capability pane, set the bundle id to unique identifier.&lt;/li&gt;
&lt;/ol&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 799px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 18.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAgElEQVR42o2PUQvCMAyE9///oz5I64NTC86kTdbmDBFBxh4W+BJyBwc3YTNmA9IaVAQ2ujMCN8L7//dm2gq1FOTzCY9rxmu+4Z4T5nTxP4HLE1YJg5a4hwJtVQgTioctHiD0diiuut5bdRimeizwW9tAzFh7j2YWdYHh68d+YeAD+6k65cGwTwcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;apple signin bundle identifier&quot; title=&quot;&quot; src=&quot;/static/f0082489d2b44b16628886c02fecd0aa/76cea/apple-signin-bundle-identifier.png&quot; srcset=&quot;/static/f0082489d2b44b16628886c02fecd0aa/772e8/apple-signin-bundle-identifier.png 200w,
/static/f0082489d2b44b16628886c02fecd0aa/e17e5/apple-signin-bundle-identifier.png 400w,
/static/f0082489d2b44b16628886c02fecd0aa/76cea/apple-signin-bundle-identifier.png 799w&quot; sizes=&quot;(max-width: 799px) 100vw, 799px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Add your apple id account and assign the target to the team so Xcode can enable sign in with Apple in your provisioning profile. You can also add this capability on the apple developer portal manually.&lt;/li&gt;
&lt;/ol&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 29.500000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqUlEQVR42oWRgQ7DIAhE/f9frXZVp1MUb2jjlnUuI3khkQtwqLz3MMYgpYScM1prL2rtVJRSwMwftV+oKVxFzBXWecQYZViS5ozKa+0MtXrsA0IIsNZCay3ZjS2LNMv1T8NWCPR4gImAWgZMGfu24djNyDe9ITiHKOdpUpu6K02GKpJN7seBHIOI6ZtywnJfFtucaa2jUyOWp4V2YXgfn9Lptz7vzQvtmycCcdksZwvd1QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;apple signin capabilities&quot; title=&quot;&quot; src=&quot;/static/ba31d9ffa9a9bb3a324e9fddb616913d/5a190/apple-signin-capabilities.png&quot; srcset=&quot;/static/ba31d9ffa9a9bb3a324e9fddb616913d/772e8/apple-signin-capabilities.png 200w,
/static/ba31d9ffa9a9bb3a324e9fddb616913d/e17e5/apple-signin-capabilities.png 400w,
/static/ba31d9ffa9a9bb3a324e9fddb616913d/5a190/apple-signin-capabilities.png 800w,
/static/ba31d9ffa9a9bb3a324e9fddb616913d/c1b63/apple-signin-capabilities.png 1200w,
/static/ba31d9ffa9a9bb3a324e9fddb616913d/d56b5/apple-signin-capabilities.png 1215w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Choose a run destination from the scheme pop-up menu that you&apos;re signed into with and apple id and that uses two factor authentication(TouchID or FaceID)&lt;/li&gt;
&lt;li&gt;If necessary, click register device in signing &amp;#x26; capabilities to create the provisioning profile.&lt;/li&gt;
&lt;li&gt;In the toolbar, click run or choose Product &gt; Run&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the project structure,&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 301px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 129.99999999999997%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAAAsTAAALEwEAmpwYAAADlklEQVR42oVVTY+jRhD1/79FipTkEu0hyS2HnGa10awy9hjbfIPB4LHNN82A7WFWq831bVVjEM5MZg6lbuPmUfXq1evJOU/xl1Xgfp0htC1s3DVsTYdrmNg4LjzLluHbDg7hFk0p3ozJucjwySqhmA48dYY1rY5uwKXQlEUHTnuH1q3n4zEvUNOLdVG+CAnY8CYT+Bb+BBHcYDFT4VsWdAJzDQPmciXDVjVYKxUP/gbnxxpPdSOj3/PKoJMySVDEKcokhktApqpCmysys+V0itXsHup8Lp/x3lyt6IM2rSr9P5Pn+ENcQUFYkzyKkUcRskOCwPwEz1Cg3M1kVvpiSS8YMC5ZMq8M4BGfvHLWTA/v16ZFGFEHWFBsN3s8Bz8j1G/wz61CB3UCXBDYUvJWZfkQIs2ufvfPGGsi0hQcVZYh2j7g7P+CzJtSQyhDRUEUhgSYX87k8pxImKJUrld7OjPp282EPuYlzofPUF0Hpm7LDPdBKA/z17mknKJ+SzbjH7Wo0VQtPqxbGN4OLjXI0jqedGXZyYj2TME7gCXyuMRT8CsS7xbWUiPCVew2AZ5PJxyrRxxFhdNlbd7PsESZCjyFvyHbTOEYrmyKZ9tyOoo4eVXIY0G/zDAp0YYfkIdTWDoBUqksE/V+LpvF4uXsWMCcaR/8e5z1wOFRCFTVv3guKqRhQHJRYZAOmb9ekzw9/GxFH1FJ6Cx2OaK0sgIYeAAUNH7H/UeIBx07P5QdjR92SPcHJLu9XPkZr+OQnScFXGV4pJKzuEC7/V2WvAsPaJtuPsfBJY5neFz6qyXX4oQ2zxBvNrLkbqY1Obf9+PU0KHfTwSjGjbnSYcPSSGMkNB3cEI/mc33xxYCC55U73sdrevzPpMQ4ZQmy3a7zRAJjkN5geeVzTD5HXb6UzsBhGhV49n9A5H7EYk7uQV5oq7oEYY6+nM4yev5kjPywl86oZPpqvsc53SN0HFiqLstlzmTZlKF/iXDtdTTQdcGzztRk1PEr2bC4m5I6Ro4RBQE0AuKX2DgZxFK1gQIG4lVeCwTOe5bOFSCXXYszBBkET0bfDDYDLvnrU4t2JJmx9Y+npeNQ8OjVpMM/kPp3WFselWEOJbLlS4unzjZvXFADIPugODhogj+RBCpdpb4sg285NgdeOVt25Xfd5iiNgbhzf0Tm/w1t6ZAhdJdPSiPXNscXnXzfvlhTZPPHsiC+quHFt2zq/wC/A+4wR1Dyln1TAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;apple singin project structure&quot; title=&quot;&quot; src=&quot;/static/5705e0331aa5ed74e6aad83e1159903d/fb933/apple-singin-project-structure.png&quot; srcset=&quot;/static/5705e0331aa5ed74e6aad83e1159903d/772e8/apple-singin-project-structure.png 200w,
/static/5705e0331aa5ed74e6aad83e1159903d/fb933/apple-singin-project-structure.png 301w&quot; sizes=&quot;(max-width: 301px) 100vw, 301px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Add a Sign in with Apple button&lt;/h3&gt;
&lt;p&gt;We can add the Sign in with Apple button in our view by importing AuthenticationServices. Using this button we can create authorization requests with the scope and also handle the results.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;SignInWithAppleButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    onRequest&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;requestedScopes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fullName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    onCompletion&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;didFinishAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above code snippet, Sign in with Apple button has three parameter as follows,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;label: This is the button title that displays title like Continue, Sign In or Sign up&lt;/li&gt;
&lt;li&gt;onRequest: Setup request and scope&lt;/li&gt;
&lt;li&gt;onCompletion: Handle the authorization result&lt;/li&gt;
&lt;/ol&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 251px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 216.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAArCAYAAAB4pah1AAAACXBIWXMAACE4AAAhOAFFljFgAAADOUlEQVR42u1US08TURSeXyHsXciKPnksjBH70DQxsuCXmLgt0GpMNC5q9B/YYBtNXLAgPEpLH/Q5jz7QKCZGJOEPkJRo8jnfHW6ZlilWw8qw+OaeOfecb879zpmreDwehEIhLCwsIBgMYnZ2Fl6vFz6f70IwLxAIYP7BPIL3wwhEQvB7fVC4MTc3h0gkItaZmZmRCcPhMCL3IrgZuoXbd+/AR0Juut1uTE5OinUUMsLv98Plcok8j8sNtwn6FbkpMQqZnVTk+H0WJOFl4orwivCK8D8i5JV1GRCE09PT4pa+DExNTUGZmJjA+Ph4D2NjY/+Aa2Ill5JIJBCNRrG4uCgQj8cFYrHYOVh+Ccu3vBzHEhF7jETiJZRms4l0Oo1UKoXNzU1omoZOp4N2u/1HdNotVNRPyJS/IlfdR7O1B6VcLiOfzyOXy6FQKDhiZ2dHgHFO+/k81yJ2d3eh1Ot11Go1VKvVc6hUKlBVFUdHRwK06evFVPrjyaUwqNFoOIIf4vG73S5OTk6ETd+weHIpuq6DOhKGYfRs+U6tDg8PBWjb9wdBLoVfzGazJnKneuQFpGbb29vY2trCxsYGMpmMeOfKHMZzlT0QFUpdKCh1YOLq6irW1tYEqdSYR6IttaKvVCqJPAlOiMIHj0a0Wi3hbNQbkH45ItwbhF0ivosj86Hrmii3VquLlRWwalYhu8oPDMLK1YXN8RMV9pyqhlKxJEiKxSLW19fFSs0IGTcM1LPX5cGvcoO2faWGTlWe5Rn9FTKhYFZUN4/Nr7GzsuO0eSQ5GoMgUdXM6yO0b1JgDrEdshHOR9bQNhr2ppyBneMIcGSoIavljA07ssHTaQZW8x+hakMI5ZGthmRFp1nd4G1j/U0aKvUmXnz4hrpqWHPoNA69sTD4a7aE6MP0003stVRnDfuCWfGpRobN50ysO2toR9sgkfnnaBZot5vahfPoSEhxP7dVLL3/Dv/zLuZfH+P+q2N4nnURfXdg7jVEzF8RfjGTHq0c4PqTnwglugI3nv7Cw5Uf2BeExuiE8o7cM+dPNcxLldAtm75hA+5IyE4xgf9yMplEOrWC9NtTmHYy+UbsMcZ+QUjC32cififk/FPuAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;apple singin popup&quot; title=&quot;&quot; src=&quot;/static/8b689785ff13e049021ed979d039593f/26abe/apple-singin-popup.png&quot; srcset=&quot;/static/8b689785ff13e049021ed979d039593f/772e8/apple-singin-popup.png 200w,
/static/8b689785ff13e049021ed979d039593f/26abe/apple-singin-popup.png 251w&quot; sizes=&quot;(max-width: 251px) 100vw, 251px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Handle authorization result&lt;/h3&gt;
&lt;p&gt;On completion of the request, we will get the authorization result whether the user successfully signed in or not.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;didFinishAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ASAuthorization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; authorization&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; credential &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; authorization&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;credential &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDCredential&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            shouldShowAlert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
            alertTitle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;/span&gt;
            alertMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Something went wrong. Please try again later.&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;token function&quot;&gt;saveUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fullName&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;givenName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        shouldShowAlert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        alertTitle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;/span&gt;
        alertMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;localizedDescription
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the user gets successfully signs in then store the user information in UserDefautls or Keychain and if it fails then show an alert to the user.&lt;/p&gt;
&lt;h3&gt;Revoke the permission and handle the changes&lt;/h3&gt;
&lt;p&gt;We can revoke the permission for the app from Settings &gt; Apple Id &gt; Password &amp;#x26; Security &gt; Apps using your Apple ID&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 251px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 216.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAArCAYAAAB4pah1AAAACXBIWXMAAAsTAAALEwEAmpwYAAAD80lEQVR42u1XWW7dOBDU/eELOJnLTBADmRPE9sTPb5NE7ftOqaerJcqyrQTJzNcAEVBoskkVyWZ16z1L64nSNKfz5UpK+dS2HVVVzb6M4jihKDKIBfBhrK4b8v2Arlebnp+P9PXrA40jkTWOE5VlSZ5yKeYXpokIPkDrcYPXPjwgD8OIbNt9IcwrTWkxUl4TlVUnq2KiUh4FQSh911X8kkPn80XanhdIHyfqul7IsZFhGMlKioFUNNDVHyiMS37pTBc+Po5xOp3peDzR/f0DHQ7P9O3bk/gfHh7p6elAj49/U5YVQtS2PfW9JqssG6pWtBybnmPYsx2kDTTNsECLxZjxFUVLOR8vzxsBE7bsbHilikwbFgvto30z7zUs2nm01hzg8R3gH4ZB7DRN6zy0zSOEQRDQzc3NOqCU4svwxWLMcRyO4UHia+zxeBRcr1dZ5BVhGIZ0e3u7EoIEPgOzu+1uQWLa28fabnd7ZGjNEP3MAx7AQnDDMCHPj1hfEe+OsyLOOCtSQRjO8P1Y+hj3POgzEh+A96tqvkgrTSuOhc2as8Wez+7Sh5Cd1Xc4XDheSuahH0W5IAwzsZBMltWcKTnytlxQiXxgX1DKxBnVMqcW/W2x6hCDtu0xcKshZ4mSFSFuTMzyeiU0An5Z4D2svh8oSVJ+ueTJhQDVBEDV2RYEpNgw6B9Cbtm2kbvPnJ9PojloCxqL40huues6ztP+nUT2HiGsqmpFXddC0LYt52ojpW0eq4V0KxGR3KK6XvezbLAqMsJ1XQEyZE+bb/Vm5qRdSh/v/6BjfqRWt/MOQYKjKjUTxnHMcU3E5nn+wyNmfUYfHj7SKT9ROzAhBKlUsIp6boe820DaruvzrWcyFgTxIvZEhB2wTVgRcZCRxynacKkT2SgVCYHjBCIf2OvVE78jcmI/i9pxPLqwqDEGqTmOLzJD33VDygvRYbXocNbiDE+yAtbzYrLdgi52Rmc75xTFx2vOkjguFptziAqpkbLDwE8EkkaMOXcTIYPPD1sKooaP1VCSNvKiyYwtRNglx7DuRobeWEY/ia3wGagaSf6aMReB78MilCrXoTFNSEdc+yBmDrD2FOmAJcSa/JXHGpFWLA/NMtFpSgPI0Ociq1kyExfSadUfrTCfzq0faSoxdLmmeZDMAo9jGHCg1RJHKAB1D9LCzcPCZ/zGonhIPZyloKT+QSa4tXhze+ZGtzC+JCnn+dxe6mEjzNsS9VLnmgXtG7vflnq4d/1z3fs3eEdY0/4CPw/rvxL8JvxN+L8iNL9l9lH/KmEtfzHMj/TX0DL2vTS19nZWlh3/ZTjQp093dHf3F33+/EWA9p/swxjm7O30HxEK4e13BZXyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;apple singin revoke&quot; title=&quot;&quot; src=&quot;/static/d67d90a2fdd7f4f70aafdce4441f671b/26abe/apple-singin-revoke.png&quot; srcset=&quot;/static/d67d90a2fdd7f4f70aafdce4441f671b/772e8/apple-singin-revoke.png 200w,
/static/d67d90a2fdd7f4f70aafdce4441f671b/26abe/apple-singin-revoke.png 251w&quot; sizes=&quot;(max-width: 251px) 100vw, 251px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;When we press &quot;Stop Using Apple Id&quot; we also need to handle that change in our app and we can handle it using &lt;code class=&quot;language-text&quot;&gt;ASAuthorizationAppleIDProvider.credentialRevokedNotification&lt;/code&gt; notification and we need to register for it in our ViewModel like this,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;NotificationCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addObserver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selector&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token other-directive property&quot;&gt;#selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;getAuthorizationState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;credentialRevokedNotification&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token attribute atrule&quot;&gt;@objc&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getAuthorizationState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; provider &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        provider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCredentialState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forUserID&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; state &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;authorized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// Credential are still valid&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
            case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;revoked&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//Credential is revoked. It is similar to Logout. Show login screen.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
            case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notFound&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//Credential was not found. Show login screen.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
            case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;transferred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;//The app is transfeered from one development team to another development team. You need to login again so show login screen.&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
            default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;SignInWithAppleDemoApp.swift&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;

&lt;span class=&quot;token attribute atrule&quot;&gt;@main&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignInWithAppleDemoApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservedObject&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationViewModel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@AppStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAuthorizationState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Scene&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;WindowGroup&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; email &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;AuthenticationView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;HomeView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;HomeView.swift&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HomeView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@AppStorage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, Have a good day!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;font&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;AuthenticationView.swift&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationServices&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservedObject&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationViewModel&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;SignInWithAppleButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                onRequest&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                    request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;requestedScopes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fullName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                onCompletion&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                    authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;didFinishAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scaledToFit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isPresented&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shouldShowAlert&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alertTitle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;authenticationViewModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alertMessage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dismissButton&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;OK&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;AuthenticationViewModel.swift&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foundation&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationServices&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticationViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token class-name&quot;&gt;ObservableObject&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; shouldShowAlert&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; alertTitle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; alertMessage&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//get notified when autherization state gets change&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;NotificationCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addObserver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selector&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token other-directive property&quot;&gt;#selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;getAuthorizationState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;credentialRevokedNotification&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//handle the authorization result that returned from the authorization request in Sign In with Apple button&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;didFinishAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ASAuthorization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; authorization&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; credential &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; authorization&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;credential &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDCredential&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                shouldShowAlert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
                alertTitle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;/span&gt;
                alertMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Something went wrong. Please try again later.&quot;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token function&quot;&gt;saveUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fullName&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;givenName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            shouldShowAlert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
            alertTitle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error&quot;&lt;/span&gt;&lt;/span&gt;
            alertMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;localizedDescription
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//store the user information in UserDefaults&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;saveUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//store nil for all user information in USerDefaults&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//this method gets call when the credential revoked notification has been arised in NotificationCenter&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@objc&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;getAuthorizationState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; provider &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASAuthorizationAppleIDProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; userId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            provider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCredentialState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forUserID&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; state &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;authorized&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// Credential are still valid&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
                case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;revoked&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//Credential is revoked. It is similar to Logout. Show login screen.&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
                case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notFound&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//Credential was not found. Show login screen.&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
                case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;transferred&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//The app is transfeered from one development team to another development team. You need to login again so show login screen.&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteUserData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token label important&quot;&gt;
                default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/sign-in-with-apple/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://developer.apple.com/sign-in-with-apple/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/documentation/authenticationservices/implementing_user_authentication_with_sign_in_with_apple&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://developer.apple.com/documentation/authenticationservices/implementing_user_authentication_with_sign_in_with_apple&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://support.apple.com/en-in/HT210318&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://support.apple.com/en-in/HT210318&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Sign in with Apple is more secure and easy to implement in any SwiftUI app. I hope that you like this article and also understood how to implement it by following MVVM architecture. If you have any questions consider following me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and DM me your questions. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thank you for reading! 😀 Stay safe and take care!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Understanding gradients using SwiftUI]]></title><description><![CDATA[What is the gradient? Apple says it is an array of color stops each having parametric location value. In simple word, it is a color ramp or…]]></description><link>https://www.sagarunagar.com/blog/understanding-gradients-using-swiftui/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/understanding-gradients-using-swiftui/</guid><pubDate>Tue, 12 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;What is the gradient?&lt;/h3&gt;
&lt;p&gt;Apple says it is an array of color stops each having parametric location value. In simple word, it is a color ramp or color progression that blends one into another and create a beautiful color effect.&lt;/p&gt;
&lt;h3&gt;Gradient in SwiftUI&lt;/h3&gt;
&lt;p&gt;SwiftUI allow us to apply gradient color to its View using three different ways,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Linear Gradient&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Radial Gradient&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Angular Gradient&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Before we discuss each into detail let&apos;s understand some SwiftUI struct that we are going to use in the code examples,&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Gradient&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It represents an array of color stops and each color having a parametric location value. Gradient will be initialized with an array or &lt;code class=&quot;language-text&quot;&gt;Color&lt;/code&gt; or an array of &lt;code class=&quot;language-text&quot;&gt;Color.Stop&lt;/code&gt;. Note that &lt;code class=&quot;language-text&quot;&gt;Color.Stop&lt;/code&gt; represents one color stop in gradient.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;white&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stops &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; location&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;white&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; location&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UnitPoint&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;UnitPoint is represented by X and Y position in bounding rectangle shape. It ranges from 0 to 1. SwiftUI gives us predefine UnitPoints such as:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zero &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0, y: 0)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0.5, y: 0.5)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0, y: 0.5)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trailing &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 1, y: 0.5)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0.5, y: 0)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottom &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0.5, y: 1)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topLeading &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0, y: 0)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topTrailing &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 1, y: 0)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottomLeading &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 0, y: 1)&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;UnitPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottomTrailing &lt;span class=&quot;token comment&quot;&gt;// UnitPoint(x: 1, y: 1)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Consider this image for better understanding.&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAABt0lEQVR42p2U6Y6CUAyFef+nMjFxAR1l3ILRuAYVFUdFcZ/5pKYiY4wz/aGl9PSU095rfD+zy+XC72KxCMMwEVfj0ZDo+XyWZ3nBI/58Pt9ut3FMguMKpny73R4Oh6fTKc78Fdl4PJZa2G63Wy6XdLRer29g13U/IqvValBtNpsgCPb7fbfbLZfLpVKJumFkrVbrMzIiNzA8q9Wq0+kUCgWQQghJsVis1+tEoCJCRdM0Z7MZVaQXQ5skiZb0C58KNp1O5dMeBMMoTHkR76lgOJ7nPYBVWzSAKg72fT8Bnkwmx+NRxTeEoVqtVioVaRsbDAaO46AKssX1h5lXZFL3ygyg1+uhcyaTQXCap7xt24BTqRQjREs/Mpx8Pg8Navf7fTo1ZAYUpira0hWtCiGDoa5EsMPhwOTQhYig7oK9qbYuzMOoVG0Fq2BqdPdnsG71K/B/lkQ89i6Xy0FOBgwUymazCEsJLzKcdDotR+IOpr1ms4nUlmUxCZLk3Wg0YqTg0ZxuGTu73Wg0SOYg3JaEP9QnlW3B0YPJYDlwjB1H0jgtRPhAOf/Gi5uEjn7fJMnL4P1rKHGT/ADXynt+ybD1SgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;unitpoint&quot; title=&quot;&quot; src=&quot;/static/f51b283a6653c0e55ae6d8993240e54d/0b533/unitpoint.png&quot; srcset=&quot;/static/f51b283a6653c0e55ae6d8993240e54d/772e8/unitpoint.png 200w,
/static/f51b283a6653c0e55ae6d8993240e54d/e17e5/unitpoint.png 400w,
/static/f51b283a6653c0e55ae6d8993240e54d/0b533/unitpoint.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;It was a basic understanding of &lt;code class=&quot;language-text&quot;&gt;Gradient&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;UnitPoint&lt;/code&gt;. Now let&apos;s discuss the main three gradients that SwiftUI provide us,&lt;/p&gt;
&lt;h3&gt;1. Linear Gradient&lt;/h3&gt;
&lt;p&gt;A linear gradient is the most common and popular method to add gradient color in your View.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The gradient applies the color function along an axis, as defined by its start and end points. The gradient maps the unit-space points into the bounding rectangle of each shape filled with the gradient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In simple words, a linear gradient is a progressive transition between two or more colors along with a straight line.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinearGradientView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;HStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottomLeading&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topTrailing&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.bottomLeading\nto\n.topTrailing&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottomTrailing&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topLeading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.bottomTrailing\nto\n.topLeading&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;HStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trailing&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.leading\nto\n.trailing&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trailing&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;leading&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.trailing\nto\n.leading&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;HStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alignment&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottom&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.top\nto\n.bottom&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;LinearGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bottom&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.bottom\nto\n.top&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Spacer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output will look like this,&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 200%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAG10lEQVR42pVXC1CUVRRemaSpVCRFLN8JJT7oMY1jg5qKQhkEDmqOiC9QkBCVGBNKZ7LHNGPlCxHMQCBtRFgU8MHbZylED8K3CMRjd2VZYIHdhd1/v869u/8vyq7Vnbn//eGc+91zz/nO+c/KZDRmzJg5n4Z81apVFWxGRkZWxMTESHPLli3S3LRpE183bNhQsXLlyoo1a9aU+/v758ycOdObYcmWLl0639vb27R7zx7I5XLzmTNn4OnpCRLBwcGBr9Ic4ACHpxz5u4eHB/Lz85Etzzbv3bcXPj4+xmXLls2TrVgRciw1NRU0DI0NDQKtQlpamkAnCr6+vsKCBQv4yiZtEt55910uS0lJ4bpKzQOBXgwZ6RmIiIj4UbZ+/fqyrOwcBih063pgNJpgNpvxb4PpmEwmmEifhqmwsBBhYWHFsvD1oRczjsmh6IJQozSBMElbgCCY+SZ7U2B2MSSTBfDcuXMgf5bKoqKiqrOysrmFRhKaSdHMVutEX2sZWB8Z07UCmwoKCkC3LZVt3bpVkZmZydWNRqOtu9l+tw7BaqEESPe+mpNj8SE7q632PhSXL6G9/Cr0FVdh7tQ+3N3TA8Pvlei49guUVy6j5eYNCJZDOOC6devKZNHR0VVZWVkcsLOjA7vnzsJ3Lk44NWk8KsaNQNu+byW87tO5+NNtFE5PGofE0S74wsMdzXfvSj7kFsbFxd3LPH6cX6hFqcRGz8nYOnIYEj1eQvbo4bj36TYJUJlxBLn0v0Mk2zHuBawdORy3Kso54JnTp0Fkv8p8eE/0oVKpwpIpHljx/BBsnzgWe0c4ofyTjyXAO2mpSHQdip1uYxH2ggveGe6MqnIOKOTn5YGyqlJGqL9mZ1uirGlrw5zJk/A6ZcIHzoOx0XEAyj7bIQFeP/4TYp8diGDnQfAa6IBpToNxo7raAkhZQ2lZKYuNjb0t+tBEYTlfUoL05GTkZ2SgIOUHKGtrJUCtphVlR39E7pFUZJBO3smTFKcevpelLLcwPj6+RryyVquFSqVCBwWno7MTrfR3Y3OzuAlt7e14oNFAQyuTq1tboVaruQ/Pnj0L4nS5jFBviVdmrDf29qKdNjXW18PQ3S3yzEJDukGvXg+VQgF1SwsM9G56nIf0uHKSTOc8JKHeYICqRQ01WfG36gH0Vuv4LuJck7oVKk0bl7fSwb1kgAgYHh5eKqPHzyKxGUUTdu3CtkUByApbjarQEBiKCx/y+kIp/lobghOhqxFPOnu//lo66xFAqoMckJ34ups7vCjKn40YikLnp6HdHCkBdsbHomjYM9hJ1JlNOp4TJqBdq7UPqKYovv3qNPgNHYRdHhNxnrKiMy5WAuz6fDvOvzwG30yeCH+i1eypU9BGAXwCoAZvuLlhDp3++SgXFLkM6mdhsesQfElpN490XiML+wFSlZV8aCIvbo+JQcRb05EW8B4q3/eFLuu4BKg/JUel3wKkk+xDr7cQF70R5sd9+AigyVKtGxoaUFtTAwWtfSs05yIxoJ7IXldXxykj1kNWsfsBsnrINmqpZDU1NaNbp+Pc61sPTUQTFRURLdGGyUQe2gVkg2VKU1MTdETsfhZ2duEOWa4kQLHC2wVkj3rKEFbbioqK+MrSjQPyqGhhuHwRXRfOo7OkGKb6Oljttw3IUmnxLC+MoQhOdRqCFxkft2yWABXffIUb7qNwd/o03J48AfeXvA+jocdGUKy06aBk/+jN1xDs9BxCR7liiaMDdlNWiONS7CYkj3TGEeLo9+NGInP2DOgtN7ANqGvT4Jj3LCSMfxHJU9yxx9UZBVEbJMCUqEisHfIMosePRriLM+Kmv8GDY5c2vRSEm/4++G3MMFRNeQmVroNQt+0jCXBndDSGkxtecXTk7vChTNGRm+zzkD2uV6P35Al0yTNhzMuBublRJC8aGxuRcvgwDh86hKTERJRfuyYVhyfSxkBcq3vQIn4iHxl6sogV1i5WK/t86G0DWjuFLuKhgnhoZLWwD6jYzzBiM0aIf9sFtAqhoIrMUsta3vsNJu+wFIX/Bvh/Rt8r80+ALUCxw3pSKyfK+/mQehu7Ftpr5WxZyNI0NDS0VEb99EURkH0uxZIk9K0yNq4pTvEjxXKfmoZCGaGmpaenc7ZYC4Q0dTqd0N3d3W8+rsf2Hj16lHVfqTLqnWctXLhQv3//fpSUlJjZSaWlpWA+SUpKQkJCAg4cOCDNgwcPcllZWRmKi4v5nmTqIhgGw+K/BLy8vOZ4e8/PpZ8Hf/j5+V8PCAi4FRQUdGf58uU1wcEralevXlNL7W5tSEjI/eDg4HtBQYtvBwYuukl61YGBgb8RmHzu3LmzGdg/pbq4uSvEtzsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;linear gradient&quot; title=&quot;&quot; src=&quot;/static/3aa4ee0175ad4960fd1dbc5dde002d76/63868/linear_gradient.png&quot; srcset=&quot;/static/3aa4ee0175ad4960fd1dbc5dde002d76/772e8/linear_gradient.png 200w,
/static/3aa4ee0175ad4960fd1dbc5dde002d76/63868/linear_gradient.png 250w&quot; sizes=&quot;(max-width: 250px) 100vw, 250px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;p&gt;You can use a different combination of UnitPoint to get your exact matched gradient color.&lt;/p&gt;
&lt;h3&gt;2. Radial Gradient&lt;/h3&gt;
&lt;p&gt;A radial gradient is a progressive transition between two or more colors that radiate from the center point.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The gradient applies the color function as the distance from a center point, scaled to fit within the defined start and end radii. The gradient maps the unit-space center point into the bounding rectangle of each shape filled with the gradient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RadialGradientView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;RadialGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startRadius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endRadius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;width: 200, height: 200\ncornerRadius: 20\nstartRadius: 0.0\nendRadius: 100.0&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output will look like this,&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 252px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 198.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEx0lEQVR42s2Xa0wcVRTHR2Lwkfqokqa0sMUuUKAFY0M/NEBiIMsCQhc0iDUpLI+APFICX0y0bUKVNiq2BpuUmGhII3RRipR3eVOlFbZgq9YgukBhYQkRKIVl2d2Z+XtmdiAbobw/eJN/7r1z7vz2nLv33HuHYagEBAQoQkNDKxISErRqtVqbkZGhzc3NXVJOTo6dssU6PT1dGx8fr1UnqLVRUVHXg14PUgosJjY2VhESEsJeuHgRFRUVfG1dHXx9fUEmODg4iPWSnnCAw5OOYtvDwwM1NTUov1bOF176EmFKJRcXFxfO0K+UXLlyBVQWDIYxjmqO+lxgYCBHXnMKhUKsbe1QTqkM4ygirqioSBw7NmngzGAXyjRlSE5O/o5RqxOaamvrBSBrnDfDYmUBnsdahacxLMvCarEIXa6ltRWpqak3mUT1iVbNtToYjGB1BhbEpNEcOHqBX0Ucx4lgq9VqA7a0IDExsZNJSUnpqa2tFR9a6Rc3WljbO1wreUghdzJZWVm6qqoqMQp2O4C0VG7W19dLtq0BKdpOhiayezHkbfEwOzv7t+rq6i0Dm5ubkZaWdk+Yw20BNjY2gjLoT4b+6lt1lB1bBTY1NQnAPoby9p6QQtvm4cmT2b8vC1nIFI5dXVI22c9hZmbmfYZ2jbvLPJQGr5SA/FrLhrar9qV1aEsj4OFDoL2V1CKKa7Npsc8L7alJG1BKvZWBZrPNi8uFgLcLFo74YNRPjj983HCfpPeVw+TvLdr4gnM2oMW8CtBmBD7Lh+lVd/zqfwiVPnJ847kPX3vK8IPPftz1Pwgj2XD2QwloWRvIf34OOi8Zvj8ox0cyZ7zn7IS03U7Io7aGoP1k4z4+vTbQKgHN5GGX+x4Uesig3vUyjux4Fod3PIMTu17CF+4y3JLvgUny0LoqUJrD+U/z8ZPcGQXurnjb6UW4Pe0I16cc8ZbTC/hE7oKO/c6Yy/tgHUDJQ2tBPn7x3IuvPN2QReGG7Xweyp3PIZ3CvkzzecdjL8xnT61/DnHhPAyHXsENvwO4RCGeprk7JduNQrkr6vw8MUo25J9ZB1AKGefzYPV2xchhL/zotQ9V7i64Tuqg9tBrB0Qbzry/MjApKcnOQ4sNeIP2R1Uo+NgomGLCMalS4h+S6c0IIDYSOKYAKsvXAZRST6j1Dx5gYmwM0xMTmBgdxeT4OAz0bIr6+sFBWKRolqXeSkCeTrSZR48wQqCh4WH8pdOJGiTgiF6PyenppVNvXcDFMk5eDZI3uoEBDBDQYDDAQF4vwjYEFF4aJu/6+vrQ398PPXk2NDQkyn7choBzc3OYnZ3FzMwMTCYT5ufnxWeb8nDTx+hqQH5xo/3PNWTTwG338P8BpAtnm3QurziHK+lxQHKuk6H7SGtDQ4OUlhZxSSzqccV+jMUul+kE7RCA35aVlYkbtWCQTkpRRqNRXHf2Ep7Zj5HeWaisrBQunBomMjIylMQVFxejp+cO393dTXUPurq6IPxQSUkJSktLRV29WgqNRoPbt39Gb28vtFqtUPOCLSYmBuHh4ZHil8DRo0FvhIQo2gk8SBqjz4RplSraSF8IFrrZs8ePv8uT6Jb/Dkt9c3R09JxKpZoi6Ul/R0REtAUHB0cJsH8BeAA55dOg0acAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;radial gradient&quot; title=&quot;&quot; src=&quot;/static/b48f700a6264ecb5f73beb3976cbffc4/5e02b/radial_gradient.png&quot; srcset=&quot;/static/b48f700a6264ecb5f73beb3976cbffc4/772e8/radial_gradient.png 200w,
/static/b48f700a6264ecb5f73beb3976cbffc4/5e02b/radial_gradient.png 252w&quot; sizes=&quot;(max-width: 252px) 100vw, 252px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;3. Angular Gradient&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;An angular gradient is also known as a “conic” gradient. This gradient applies the color function as the angle changes, relative to a center point and defined start and end angles. If endAngle - startAngle &gt; 2π, the gradient only draws the last complete turn. If endAngle - startAngle &amp;#x3C; 2π, the gradient fills the missing area with the colors defined by gradient locations one and zero, transitioning between the two halfway across the missing area. The gradient maps the unit-space center point into the bounding rectangle of each shape filled with the gradient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In simple words, angular gradient sweeps counterclockwise around the starting point. The line between start and endpoint defines the angle.&lt;/p&gt;
&lt;p&gt;Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AngularGradientView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; gradient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//you can use either of following initialiser to create angular gradient&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//1 with center only initialise&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//AngularGradient(gradient: gradient, center: .center)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//    .frame(width: 200, height: 200)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//    .cornerRadius(20)&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//2 with center and angle initialise&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//AngularGradient(gradient: gradient, center: .center, angle: .degrees(0))&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//  .frame(width: 200, height: 200)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//  .cornerRadius(20)&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;//3 with center, start angle and end angle initialise&lt;/span&gt;

            &lt;span class=&quot;token class-name&quot;&gt;AngularGradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gradient&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gradient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startAngle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;degrees&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endAngle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;degrees&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cornerRadius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;width: 200, height: 200\ncornerRadius: 20\nstartAngle: 0.0\nendAngle: 360.0&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multilineTextAlignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;center&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output will look like this,&lt;/p&gt;
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 251px; margin-bottom: 1.45rem;&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 199.00000000000003%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAE8UlEQVR42q2XC0xTVxjHLygEFBVkMl9RBAazoG5oBdxMHSkhjUDloQ4Mr0KRSbCg2cyyxGe2uKDZQgIrbjM42CbvEmcopaWZW+Zm3Cub2ahUx2sMRoZoC0Jv+985B6oizwgn+fee9vvOL/9773ce5TjSRCJRaERExKW9e/fqExIS9FlZWfq8vLxHOnz4MFMeUW5uLuvL5XJ9XFycft++fXpptPSSSCwOpSwuMTExbNeuXeazZ8+ioqLCVltbi8DAQJAQHB0d4eDgAGdnZzg7OWHBQic4ObuwmEAgQE1NDb68fNlWcK4A4eHhZsrikpOTPyYNpD3s7enhyZUn3/mgoCBeKBQybd++nYn2Q0JCWUxZomS5vff+5YcwPHTx04vIys76hEtPT71aU6uiQN48+BAjIxbYbDbM1GiOxWIh+SNsbFNTE8hjaOBk6Snqz76oRY8ZvLGbh3mYZlthJQNsM4iReJ5dNBoNZDKZmpPLM67TZ0Ga1WLhMbO38c0OpA7Jy2zkFAqFobKykgHHgs8MzMzMbORSU1N1dXV1Y7G5AZlD8vEtLZW5OtRqtRSoprf8S1VV1ZyB9KVkZ2d/w5HK/7m6unrOQLVajfz8/BukDjO+HrvlOT3DxsZGkGn6A5eTk3NzXh0S6oRnyAqX9CfI+liYpLCJuevMob2w5+Et0zpM19jrkM5Ntkrc60eHrgmdWg26tU3oIf0+ov+atRggetCsA9/fPzkwPf0xcGR4mCXd/OA8lB6L8LnPalRvWIUG3zW49sI6/LhxPW5t8oXBewX6PywYBY4tDtMCr50+gaJVHijb6IuqjRvQEOSH77YE4LetAhhDNqNd4I2B905ODVSpVOOA+jOncM5rGS74e6PMfz2+Evjg+83+aAkWoJMA/wn0hun9M7MHak6fxCnPJTjvtw6FPmtREeAN4zYBzGFbwO8MBl7yAwrenT3w6qkTeMt9MY57r8Y7a1fiyJoVSPPywP7n3PG6lyckTg648OZRlmuZDVB18jgOLXWFgsDkKz0Rs3wZ/F1dsHThAriSvYXuKYdycljuyGyA1cShbIkL5GueR5LXcuz2dMcry5Zgk9si+Lm5YSkBHlMoJgEenPwtl719DHFk0H4PN0QtdsFrrs7Y6rQAAY4cfKhLEjsyicODB58GjgZx48oVHBUGIz8sBG+ECCETbkPitmDEEkmCX4ZI8CJUo6v89ED7TKHV397Wjr+7ukC2VnR3dzPdvXsXfX19aGtrs4PGzZQJwEeLg9WKB6YH6CRAOthoNMJ45w7rd3Z2YmBggCRbZw+0N7sbqtbWVnRRx729Uy4OMwLpbba0tOD27dsMajAY0NHRMf1qMx3QbDbDZDLh/v37GBoaYv3BwcFxJ4vxwBkcPtN6OB3Q7uTJo8ecgPPu8JmAMtn8AVnZpKSkaKbal6c7xk12tsnIyFBz5MTUUF9fz34cJosDTbCSmUI1VbPHqYZHFxTmkBxFrpJblpWUlpayzY7mPilSc1ZSi+NEf3s6j44tLy+nx7kSLjo6OjQyMtJUWFgInU5no9abm5tBN26lUomioiIUFxcz0b5S+RGL6fV6UFck10bzJBKJmXDC2D+BHTt27BSLxaqoqKhfiW5JpdI/Y2NjDUlJScYDBw7cSUtL+4uK9ola4+PjW/bsif0jJkb6O8n9SSLZXSMSiV+lsP8BGuwRsSjyyrcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;angular gradient&quot; title=&quot;&quot; src=&quot;/static/84a751a69346e85135b04443a87cf129/26abe/angular_gradient.png&quot; srcset=&quot;/static/84a751a69346e85135b04443a87cf129/772e8/angular_gradient.png 200w,
/static/84a751a69346e85135b04443a87cf129/26abe/angular_gradient.png 251w&quot; sizes=&quot;(max-width: 251px) 100vw, 251px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
    &lt;/span&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;SwiftUI provides powerful gradients that you can use it to fill your views with required configurations. If you have any questions consider following me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/a&gt; and DM me your questions. If you enjoyed this article and would like to support me, &lt;a href=&quot;https://buymeacoffee.com/sagarunagar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Buy me a coffee&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thank you for reading! 😀 Stay safe and take care!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Property wrappers in SwiftUI]]></title><description><![CDATA[What is Property Wrapper? Property wrapper is a simple generic class/struct that has some logic that gets trigger whenever the value of…]]></description><link>https://www.sagarunagar.com/blog/property-wrappers-in-swiftui/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/property-wrappers-in-swiftui/</guid><pubDate>Mon, 03 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;What is Property Wrapper?&lt;/h3&gt;
&lt;p&gt;Property wrapper is a simple generic class/struct that has some logic that gets trigger whenever the value of property gets modified. It was introduced during WWDC 2019 and comes with Swift 5.&lt;/p&gt;
&lt;p&gt;SwiftUI provides us many property wrappers like &lt;strong&gt;@State&lt;/strong&gt;, &lt;strong&gt;@Binding&lt;/strong&gt;, &lt;strong&gt;@ObservedObject&lt;/strong&gt;, &lt;strong&gt;@EnvironmentObject&lt;/strong&gt;, &lt;strong&gt;@Environment&lt;/strong&gt;. Let&apos;s discuss each of them and understand when to use and how to use it.&lt;/p&gt;
&lt;h3&gt;@State&lt;/h3&gt;
&lt;p&gt;@State is a property wrapper that allows us to modify value inside a struct. When the state value changes, the view invalidate its appearance and rebuild the view. Because of the local nature of @State property, Apple recommends us to mark them as private. Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; showAlert&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showAlert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Show me alert&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isPresented&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $showAlert&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hey!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Have a good day :)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dismissButton&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;OK&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above example, we have a simple screen with the button &quot;Show me alert&quot; in the center. When you hit the button it will change the state property &lt;code class=&quot;language-text&quot;&gt;showAlert&lt;/code&gt; and SwiftUI recreates view and display the alert.&lt;/p&gt;
&lt;h3&gt;@Binding&lt;/h3&gt;
&lt;p&gt;@Binding property wrapper allows you to pass the data between two or more views without ownership. It provides reference like access for a value type. @Binding property has its value passed in from parent view as binding. It does not have ownership since it copies a value from parent @State value. Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isPlaying&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Test audio!&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;PlayButtonView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isPlaying&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $isPlaying&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PlayButtonView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Binding&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; isPlaying&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bool&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isPlaying&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toggle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;systemName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; isPlaying &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pause.circle&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;play.circle&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above example, we have a simple view with a label and play/pause button in the center. We have state property &lt;code class=&quot;language-text&quot;&gt;isPlaying&lt;/code&gt; and passing that reference to &lt;code class=&quot;language-text&quot;&gt;PlayButtonView&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;$&lt;/code&gt;. As soon as &lt;code class=&quot;language-text&quot;&gt;PlayButtonView&lt;/code&gt; changes the value of &lt;code class=&quot;language-text&quot;&gt;isPlaying&lt;/code&gt; property, SwiftUI recreates &lt;code class=&quot;language-text&quot;&gt;ContentView&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PlayButtonView&lt;/code&gt; as its child view.&lt;/p&gt;
&lt;h3&gt;@ObservedObject&lt;/h3&gt;
&lt;p&gt;@ObservedObject is similar to @State property wrapper but it is for external type and track the changes using @Published property wrapper. The key difference between @State and @ObservedObject is that @ObservedObject shares the object between two or more individual views. Let&apos;s look at the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ObservableObject&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Published&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; cartItems &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@ObservedObject&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; cart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Number of items in cart is: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;cart&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cartItems&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above example, we have &lt;code class=&quot;language-text&quot;&gt;Cart&lt;/code&gt; class that we are using in multiple views of our application. Whenever any changes made to &lt;code class=&quot;language-text&quot;&gt;cartItems&lt;/code&gt;, It will automatically notify all the views that use the &lt;code class=&quot;language-text&quot;&gt;Cart&lt;/code&gt;. Any type you mark as @ObservedObject should conform to the protocol &lt;code class=&quot;language-text&quot;&gt;ObservableObject&lt;/code&gt; and it should be a class type.&lt;/p&gt;
&lt;h3&gt;@EnvironmentObject&lt;/h3&gt;
&lt;p&gt;@EnvironmentObject is very similar to @ObservedObject but the main difference is that @EnvironmentObject allows us to create a property that shared across the entire app without created by view or passed in from another view. In simple words, we can add a property in the Environment of the view hierarchy and all the child view in the hierarchy can access that property. Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SceneDelegate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIResponder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIWindowSceneDelegate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIWindow&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;scene&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token omit keyword&quot;&gt;_&lt;/span&gt; scene&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIScene&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; willConnectTo session&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UISceneSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options connectionOptions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIScene&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ConnectionOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; windowScene &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; scene &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIWindowScene&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; window &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIWindow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;windowScene&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; windowScene&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; cart &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; contentView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;environmentObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cart&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootViewController &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UIHostingController&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rootView&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; contentView&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;window &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window
            window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;makeKeyAndVisible&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@EnvironmentObject&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; cart&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cart&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Number of items in cart is: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;cart&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cartItems&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Above example is similar to example of @ObservedObject but the difference is we don&apos;t need to pass the default value by uisng @EnvironmentObject. It means it will be provided by SwiftUI environment. You can see in the example that we created the cart object in SceneDelegate and passing it to ContentView&apos;s environment object.&lt;/p&gt;
&lt;h3&gt;@Environment&lt;/h3&gt;
&lt;p&gt;@Environment property wrapper allows us to use system default settings like whether the device is in dark mode or light mode, device&apos;s current timezone, etc. Here is the example,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@Environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;timeZone&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; timeZone&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TimeZone&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Your Timezone: &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;timeZone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;abbreviation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;N/A&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In above example, we have simple screen that display device&apos;s default currency code in the center of screen.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Property wrappers are powerful and playing a huge role while working with SwiftUI. You need to choose wisely which property wrapper you need to use and how to use it. If you have any questions feel free to follow me on &lt;a href=&quot;https://twitter.com/SagarUnagar_&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Twitter&lt;/a&gt; and ask me your questions.&lt;/p&gt;
&lt;p&gt;Thank you for reading! 😀 Peace ✌️&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Basic structure of SwiftUI project]]></title><description><![CDATA[Apple introduced SwiftUI in WWDC 2019 that enabled a new way to create user-interface of your iOS app. Whenever you create your single view…]]></description><link>https://www.sagarunagar.com/blog/basic-structure-of-swiftui-project/</link><guid isPermaLink="false">https://www.sagarunagar.com/blog/basic-structure-of-swiftui-project/</guid><pubDate>Mon, 23 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Apple introduced &lt;a href=&quot;https://developer.apple.com/xcode/swiftui/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SwiftUI&lt;/a&gt; in WWDC 2019 that enabled a new way to create user-interface of your iOS app.&lt;/p&gt;
&lt;p&gt;Whenever you create your single view app using SwiftUI, You will get the following basic template of your app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thepracticaldev.s3.amazonaws.com/i/9fqyrmhzy3rigq7q65ld.png&quot; alt=&quot;Alt Text&quot;&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s discuss more about this all files,&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;AppDelegate.swift&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After SwiftUI introduced, Appdelegate is only responsible for setting up external dependency and managing application data(ex. coredata).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;SceneDelegate.swift&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is something new you can see in a project that is created using SwiftUI. SeceneDelegate is responsible for managing the way your app is shown. This contains the app transition methods that handle the app enter in the foreground, enter in the background, etc.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;ContentView.swift&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is an initial view of your application. In this file, you can create your app interface using a declarative way. This is equivalent to ViewController that is being generated in the project that is created without using SwiftUI.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Assets.assets&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As usual as previous, Assets contain all the images and colors that are used in our project.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;LaunchScree.storyboard&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This screen is displayed as a launch screen(splash screen) of your app. Nothing changes the way we setting up the launch screen previously.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Info.plist&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is a property list file that states all the system related settings like app name, app version, build number, etc.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Preview Contain&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This folder includes one another asset catalog that is used at preview time in canvas.&lt;/p&gt;
&lt;p&gt;Thanks for reading, Happy Holidays 🎅🎄&lt;/p&gt;</content:encoded></item></channel></rss>