<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Swift with Blaze]]></title><description><![CDATA[Deep Swift & Using Swift: helping iOS developers master Swift with clear, deep explanations.]]></description><link>https://www.swiftwithblaze.com</link><image><url>https://substackcdn.com/image/fetch/$s_!oLx_!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4094dd4a-505b-475e-90a2-6ad83274cf3d_256x256.png</url><title>Swift with Blaze</title><link>https://www.swiftwithblaze.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 01 May 2026 18:11:32 GMT</lastBuildDate><atom:link href="https://www.swiftwithblaze.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[E.I. Blazej SLEBODA]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[swiftwithblaze@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[swiftwithblaze@substack.com]]></itunes:email><itunes:name><![CDATA[🅱🅻🅰🆉🅴]]></itunes:name></itunes:owner><itunes:author><![CDATA[🅱🅻🅰🆉🅴]]></itunes:author><googleplay:owner><![CDATA[swiftwithblaze@substack.com]]></googleplay:owner><googleplay:email><![CDATA[swiftwithblaze@substack.com]]></googleplay:email><googleplay:author><![CDATA[🅱🅻🅰🆉🅴]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Keyboards and Layouts for Software Developers]]></title><description><![CDATA[History of Keyboards and QWERTY, AZERTY Layouts]]></description><link>https://www.swiftwithblaze.com/p/keyboards-and-layouts-for-software</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/keyboards-and-layouts-for-software</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 20 Mar 2026 13:31:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mWbf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Many times, when I was designing a public interface for a framework&#8212;especially for prefixes of intermediate namespaces&#8212;I also took into account how easy the prefix was to type on my keyboard. I talked to my teammates about it. The idea was great, until now.</p><p>Now I know that the majority of the world uses QWERTY, but there are also AZERTY, QWERTZ, and other less common keyboard layouts. So the prefix &#8220;ib&#8221; that I chose for my UIViewKit framework happens to be part of the common set across these layouts&#8212;I got lucky.</p><p>Now I realize that the choice is more complex and should probably be made with the QWERTY layout as a reference.</p><p>In upcoming posts, I am going to share my findings about keyboards, UHID, system keyboard layouts, and using a keyboard when you are bilingual.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mWbf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mWbf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 424w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 848w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 1272w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mWbf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic" width="570" height="970" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:970,&quot;width&quot;:570,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/191580678?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mWbf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 424w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 848w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 1272w, https://substackcdn.com/image/fetch/$s_!mWbf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60396370-7bc0-41ed-accc-b1dfdbbae875_570x970.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Modern Keyboards Still Run On QWERTY]]></title><description><![CDATA[From mechanical typebars to touchscreens &#8212; the layout survived every technological revolution]]></description><link>https://www.swiftwithblaze.com/p/modern-keyboards-still-run-on-qwerty</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/modern-keyboards-still-run-on-qwerty</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Tue, 24 Feb 2026 10:46:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AwO1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AwO1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AwO1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 424w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 848w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 1272w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AwO1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6864615,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/189001484?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AwO1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 424w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 848w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 1272w, https://substackcdn.com/image/fetch/$s_!AwO1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98dcfebd-9d22-434f-93f4-73cfd51eff87_2912x2096.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Look at your keyboard.</p><p>Now look at a 19th-century typewriter.</p><p>Different materials. Same structure.</p><p>The first commercially successful writing machines introduced QWERTY to solve a mechanical problem: metal typebars were colliding. The layout wasn&#8217;t optimized for speed or ergonomics. It was engineered to prevent jams.</p>
      <p>
          <a href="https://www.swiftwithblaze.com/p/modern-keyboards-still-run-on-qwerty">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Crash Course: Unicode Strings for iOS Developers ]]></title><description><![CDATA[A fast, practical crash course on Unicode and Swift&#8217;s String: normalization, equality, hashing, etc.]]></description><link>https://www.swiftwithblaze.com/p/crash-course-unicode-strings-for</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/crash-course-unicode-strings-for</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Sun, 22 Feb 2026 14:11:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!83Kr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!83Kr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!83Kr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 424w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 848w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 1272w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!83Kr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120350,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/188797515?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!83Kr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 424w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 848w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 1272w, https://substackcdn.com/image/fetch/$s_!83Kr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef5be4d-a541-4e15-8056-6c807a41dda1_1604x1604.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>For nearly two months, I&#8217;ve been publishing notes and deep dives on Unicode and Swift&#8217;s String.</p><p>You&#8217;ve followed the journey. &#128064;</p><p>Now it&#8217;s time for the crash course. &#128104;&#8205;&#128187;</p><p>The content is ready.</p><p>This course is built for Mobile Leads and iOS developers who want a clear, structured understanding.</p><p>The goal is straightforward:</p><p>Fast-track Unicode from abstract tables to Swift&#8217;s String model.</p><p>Understand normalization, equality, hashing, sorting, and searching in practice.</p><p>See how real user input, real Unicode, can quietly affect your production apps.</p><p>Focused. Practical. Directly applicable.</p><p>Here is the link: <a href="https://luma.com/gngr0egg">Link</a></p><p>Join the crash course. See you inside. &#128640; </p>]]></content:encoded></item><item><title><![CDATA[Unicode Normalization Explains Why Backspace Sometimes Takes More Than One Tap]]></title><description><![CDATA[How NFC, NFD, and NFKC editing behavior]]></description><link>https://www.swiftwithblaze.com/p/unicode-normalization-explains-why</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/unicode-normalization-explains-why</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 20 Feb 2026 10:24:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!d3iR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d3iR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d3iR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 424w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 848w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 1272w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d3iR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png" width="1456" height="1049" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1049,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1344787,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/188598713?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d3iR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 424w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 848w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 1272w, https://substackcdn.com/image/fetch/$s_!d3iR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F988d6f6b-b069-4c70-90d7-3411cf99afb7_2916x2100.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It can be confusing when deleting a single visible character requires two or more backspace taps. You press delete once, nothing seems to happen. Press again, and only then does the character disappear. This is not a keyboard bug. It is usually a consequence of Unicode composition and normalization.</p><p>In Swift, a String is a collection of extended grapheme clusters, not Unicode scalars or UTF-16 code units. What looks like one character on screen can be composed of multiple scalars. Normalization (NFC vs NFD) affects equality and storage. Compatibility normalization (NFKC) goes further: it folds compatibility characters into their canonical equivalents.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;swift&quot;,&quot;nodeId&quot;:&quot;458eb2a8-85cf-40b7-96b2-4894c22cceb1&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-swift">import Foundation

// Canonical normalization (NFC)
let decomposed = "e\u{0301}" // se + &#9676;&#769;
let nfc = decomposed.precomposedStringWithCanonicalMapping
print(nfc.unicodeScalars.count) // 1

// Compatibility normalization (NFKC)
let ligature = "&#64257;" // U+FB01 LATIN SMALL LIGATURE FI
print(ligature == "fi") // false

let nfkc = ligature.precomposedStringWithCompatibilityMapping
print(nfkc == "fi") // true
print(nfkc.unicodeScalars.map { $0.value }) // [102, 105]</code></pre></div>]]></content:encoded></item><item><title><![CDATA[Cocoa Design Patterns Guide]]></title><description><![CDATA[How Cocoa Adapts Design Patterns]]></description><link>https://www.swiftwithblaze.com/p/cocoa-design-patterns-guide</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/cocoa-design-patterns-guide</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 06 Feb 2026 17:05:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DekF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Early in my career as a professional iOS developer, I was asked several times during job interviews to explain and give examples of design patterns. I am self-taught and wasn&#8217;t able to answer properly, so I was rejected a few times. Then I found this document, <em>&#8220;Cocoa Design Patterns Guide&#8221;</em> by Apple, published in 2005, and it became a pivotal moment for me. I studied it, and from then on, answering interview questions about design patterns was no longer a problem.</p><p>Today, someone posted on LinkedIn about the Chain of Responsibility pattern, which reminded me of that document. There is still an HTML version available online. I hope someone will find it helpful. Here is the link: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DekF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DekF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 424w, https://substackcdn.com/image/fetch/$s_!DekF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 848w, https://substackcdn.com/image/fetch/$s_!DekF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 1272w, https://substackcdn.com/image/fetch/$s_!DekF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DekF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png" width="1456" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:635169,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/187102858?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DekF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 424w, https://substackcdn.com/image/fetch/$s_!DekF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 848w, https://substackcdn.com/image/fetch/$s_!DekF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 1272w, https://substackcdn.com/image/fetch/$s_!DekF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2262e16-c730-463b-b309-db5142e18fc0_1456x1048.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[SwiftFiddle]]></title><description><![CDATA[SwiftFiddle is an online playground for creating, sharing, and embedding Swift fiddles]]></description><link>https://www.swiftwithblaze.com/p/swiftfiddle</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/swiftfiddle</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Tue, 03 Feb 2026 09:52:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!bRaG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>SwiftFiddle is an online playground for creating, sharing, and embedding Swift <strong>fiddles</strong> &#8212; small Swift programs that run directly in your browser. A &#8220;fiddle&#8221; in programming slang is a quick, disposable code snippet used to test an idea, demonstrate behavior, reproduce a bug, or share a minimal example.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bRaG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bRaG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 424w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 848w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 1272w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bRaG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png" width="1456" height="1050" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1050,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:837293,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/186716405?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bRaG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 424w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 848w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 1272w, https://substackcdn.com/image/fetch/$s_!bRaG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6215f52f-260e-4bf2-ab49-e64f778124ce_2924x2108.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The project is open source. Its main repository is at github.com/SwiftFiddle/swiftfiddle-web, licensed under MIT and maintained by the SwiftFiddle organization. Contributors have been active on the codebase for years, and the playground shows up in community links as early as 2023.</p><p>You can use SwiftFiddle at https://swiftfiddle.com, where you pick a Swift version, write code, and run it in the browser. Because all versions execute on the same Linux/ICU environment, Unicode behavior &#8212; including String equality and canonical equivalence &#8212; is consistent across tests.</p><p>SwiftFiddle is useful for:</p><ul><li><p>sharing minimal reproducible examples</p></li><li><p>quickly experimenting with language features</p></li><li><p>embedding runnable Swift snippets in docs or discussions</p></li></ul>]]></content:encoded></item><item><title><![CDATA[How Swift String Equality Affects Dictionaries and Sets]]></title><description><![CDATA[Comparing strings for equality is always performed using Unicode canonical representation.]]></description><link>https://www.swiftwithblaze.com/p/how-swift-string-equality-affects</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/how-swift-string-equality-affects</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Mon, 02 Feb 2026 17:39:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vO5S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Swift&#8217;s String equality is based on canonical Unicode equivalence&#8212;not on raw bytes, code units, or code points.</p><p>Comparing strings for equality using the equal-to operator (==) or a relational operator (like &lt; or &gt;=) is always performed using Unicode canonical representation. As a result, different representations of a string compare as being equal.</p><pre><code>let cafe1 = "Cafe\u{301}" // NFD - Normalization Form D (Canonical Decomposition)
let cafe2 = "Caf&#233;" // NFC - Normalization Form C (Canonical Composition)
print(cafe1 == cafe2)
// Prints "true"</code></pre><p>The Unicode scalar value &#8220;\u{301}&#8221; modifies the preceding character to include an accent, so &#8220;e\u{301}&#8221; has the same canonical representation as the single Unicode scalar value &#8220;&#233;&#8221;.</p><p>Basic string operations are not sensitive to locale settings, ensuring that string comparisons and other operations always have a single, stable result, allowing strings to be used as keys in Dictionary instances and for other purposes.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p><strong>Dictionary keys</strong> rely on hashing for fast lookup and fall back to == to resolve collisions. Because String equality is Unicode-aware, keys with different code points but canonically equivalent values are considered equal. When creating a dictionary, this can trigger a duplicate-key conflict (requiring a conflict-resolution closure) or even crash the app, depending on the initializer used; when assigning a value later, the new value replaces the existing one.</p><p><strong>Set</strong> behaves similarly: canonically equivalent strings represented with different code points (for example, NFC vs NFD) are treated as the same element. In such cases, only one value is stored, and the actual stored representation depends on which variant was inserted first.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vO5S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vO5S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 424w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 848w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 1272w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vO5S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png" width="1350" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c5ac3e4-0ab3-41c3-9f1a-7b758fcdd5a8_1350x768.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:180799,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/186633212?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c5ac3e4-0ab3-41c3-9f1a-7b758fcdd5a8_1350x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vO5S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 424w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 848w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 1272w, https://substackcdn.com/image/fetch/$s_!vO5S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4add54a2-6d18-40b5-8f3f-72a477a51ac0_1350x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Concatenation, user input, copy-paste, JSON payloads, and localization frequently introduce mixed normalization. You don&#8217;t see it. Swift does.</p><p>Rule of thumb: when a string is used as an identifier, key, or lookup value&#8212;and there is a risk of mixed normalization (NFC vs NFD)&#8212;normalize it explicitly (and usually case-fold it) before storing or comparing. Unicode equivalence is great for text&#8212;but dangerous for identifiers.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Modifying and Comparing Strings - <a href="https://developer.apple.com/documentation/Swift/String#Modifying-and-Comparing-Strings">Swift Documentation</a></p></div></div>]]></content:encoded></item><item><title><![CDATA[Canonical Equivalence and Set<String> in Swift]]></title><description><![CDATA[How Unicode normalization affects Set's hashing and equality]]></description><link>https://www.swiftwithblaze.com/p/canonical-equivalence-and-setstring</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/canonical-equivalence-and-setstring</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 30 Jan 2026 17:53:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!S8ic!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you create a Set of strings in Swift, you probably expect <em>unique</em> values to collapse into a single entry. What&#8217;s easy to miss is that this behavior depends on <strong>Unicode normalization</strong>&#8212;and Swift makes a very specific choice for you.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S8ic!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S8ic!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 424w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 848w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 1272w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S8ic!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic" width="1200" height="666" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:666,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25787,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/186323486?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!S8ic!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 424w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 848w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 1272w, https://substackcdn.com/image/fetch/$s_!S8ic!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3de23-3581-4622-b43b-d9ad555590d8_1200x666.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Even though a and b are built from different Unicode scalar sequences, Swift treats them as equal. That&#8217;s because Swift normalizes strings for equality and hashing. If two strings are canonically equivalent in Unicode, they are considered the same value when inserted into a Set or used as dictionary keys.</p><p>This is a deliberate design choice. Swift optimizes for <em>human-perceived equality</em>, not raw binary representation. From a user&#8217;s point of view, &#8220;&#233;&#8221; is &#8220;&#233;&#8221;, regardless of how it was typed, copied, or transmitted.</p><p>The subtlety is that this behavior is invisible until it matters. It shows up when you deduplicate user input, process international text, or handle data coming from multiple systems. If you assume that different scalar sequences always produce different values, your mental model of Set is already wrong.</p><pre><code>import Foundation

// ORIGINAL JSON payload (VALID JSON)
// Two canonically equivalent strings encoded differently
let originalJSON = """
{
  "tags": ["\\u00E0", "a\\u0300"]
}
""".data(using: .utf8)!

struct Payload: Codable {
    let tags: [String]
}

// 1&#65039;&#8419; Decode original JSON
let decoded = try JSONDecoder().decode(Payload.self, from: originalJSON)

print("Original decoded JSON:")
print(decoded.tags)
print("count =", decoded.tags.count) // &#9989; 2
print()

// 2&#65039;&#8419; Inspect internal representations
print("Decoded strings:")
for tag in decoded.tags {
    print(
        "\"\(tag)\" scalars:", tag.unicodeScalars.count,
        "characters:", tag.count
    )
}
print()

// 3&#65039;&#8419; Convert Array &#8594; Set
// ISSUE:
// Set&lt;String&gt; collapses canonically equivalent strings.
// Information is lost here.
let rawSet = Set(decoded.tags)

print("After Set conversion (DATA LOSS):")
print("count =", rawSet.count) // &#10060; 1 (was 2)
print(rawSet)
print()

// 4&#65039;&#8419; Re-encode after Set
// This JSON is NOT equivalent to the original input.
let reencoded = try JSONEncoder().encode(
    Payload(tags: Array(rawSet))
)

print("Re-encoded JSON (information lost):")
print(String(data: reencoded, encoding: .utf8)!)</code></pre><div><hr></div><p><strong>Output:</strong></p><pre><code>Original decoded JSON:
["&#224;", "a&#768;"]
count = 2
Decoded strings:
"&#224;" scalars: 1 characters: 1
"a&#768;" scalars: 2 characters: 1
After Set conversion (DATA LOSS):
count = 1
["&#224;"]
Re-encoded JSON (information lost):
{"tags":["&#224;"]}</code></pre><p>The key takeaway: <strong>in Swift, string equality is semantic, not structural</strong>. Unicode normalization, for some operations, is baked into the language.</p><p>This is one of the edge cases I cover in my Unicode training.</p>]]></content:encoded></item><item><title><![CDATA[Syntax (Syntactic) vs. String Semantics]]></title><description><![CDATA[The Most Used Word Nobody Clearly Defines: Semantics]]></description><link>https://www.swiftwithblaze.com/p/syntax-syntactic-vs-string-semantics</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/syntax-syntactic-vs-string-semantics</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Tue, 27 Jan 2026 11:36:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hlJ9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Syntax</em>&#8212;also called the <strong>syntactic level</strong>&#8212;describes how text is written in source code and how the compiler parses it. Unicode escape sequences (&#8221;\u{00E9}&#8221;), string literals (&#8221;hello&#8221;), and string interpolation (&#8221;\(value)&#8221;) all belong to this layer. They are construction mechanisms: precise instructions telling the compiler to consult the Unicode table, translate code points into Unicode scalars, and assemble them into a string. This level is designed for correctness and determinism, not human intuition.</p><p><strong>String semantics is a higher-level concept.</strong> Although the word <em>semantics</em> looks plural, it refers to a single domain: meaning. At the semantic level, a string represents human-perceived text rather than its construction details. Different syntactic forms can therefore map to the same semantic value. For example, &#8220;\u{00E9}&#8221; (precomposed <strong>&#233;</strong>) and &#8220;\u{0065}\u{0301}&#8221; (an <strong>e</strong> plus a combining acute accent) are syntactically different, yet semantically equivalent. Humans read the same character; the string system&#8217;s job is to bridge low-level Unicode mechanics with high-level meaning.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hlJ9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hlJ9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 424w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 848w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 1272w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hlJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic" width="928" height="1152" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1152,&quot;width&quot;:928,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120237,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/185949663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hlJ9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 424w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 848w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 1272w, https://substackcdn.com/image/fetch/$s_!hlJ9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc640ffff-be7f-49cf-9269-71172a81e9e9_928x1152.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Where Apple Expects You to Store Your Xcode Projects]]></title><description><![CDATA[The ~/Developer Folder: Apple&#8217;s Preferred Home for Xcode Projects]]></description><link>https://www.swiftwithblaze.com/p/where-apple-expects-you-to-store</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/where-apple-expects-you-to-store</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Wed, 21 Jan 2026 11:03:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5_KA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5_KA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5_KA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 424w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 848w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 1272w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5_KA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic" width="906" height="540" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:540,&quot;width&quot;:906,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23852,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.swiftwithblaze.com/i/185170783?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5_KA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 424w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 848w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 1272w, https://substackcdn.com/image/fetch/$s_!5_KA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5303e354-2315-4c77-aa46-4f758137f3e0_906x540.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3>Why does the ~/Developer folder in the Home directory show up with a hammer icon in the sidebar?</h3><p>Because this is a <strong>preferred location</strong> defined by Apple for storing Xcode projects. It is not mandatory, but if you choose that location, macOS displays a dedicated pictogram&#8212;similar to the <strong>Downloads</strong> or <strong>Desktop</strong> folders.</p><p>The ~/Developer folder is the natural place to:</p><ul><li><p>store Xcode projects</p></li><li><p>clone GitHub repositories</p></li><li><p>keep code projects executed or generated by Codex, Cloud tools, or other generative CLIs, and Android Studio</p></li></ul><div><hr></div><p>If you are a <strong>hobby developer</strong> and are not interested in keeping your projects under Git control, you can place them anywhere. To back up such projects, simply duplicate or zip them. Typical locations include ~/Desktop or ~/Documents.</p><div><hr></div><p><strong>PoC / temporary / test projects</strong> stored on ~/Desktop?</p><p>Yes &#8212; it&#8217;s a convenient location when creating a new project with no business value.</p><div><hr></div><p>If you keep projects in ~/Desktop or ~/Documents and those folders are synchronized with <strong>iCloud Drive</strong>, you get automatic backups. However, there is a risk: synchronization can be <strong>partial</strong>.</p><p>A realistic failure scenario:</p><ul><li><p>You work on an app</p></li><li><p>The internet connection is slow or intermittent</p></li><li><p>Some files sync, others don&#8217;t</p></li><li><p>You leave (for lunch, for example)</p></li><li><p>Your computer is stolen</p></li><li><p>You buy a new Mac</p></li><li><p>iCloud restores the project, but <strong>not all files are at the same revision</strong></p></li></ul><p>Result: the app no longer compiles.</p><p>This is a <strong>rare case</strong>, but it can happen.</p>]]></content:encoded></item><item><title><![CDATA[Replacing text in a string using replacingOccurrences(of:)]]></title><description><![CDATA[Swift&#8217;s replacingOccurrences can break flag emojis. Learn why NSString replaces across grapheme clusters, and how to fix it.]]></description><link>https://www.swiftwithblaze.com/p/replacing-text-in-a-string-using</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/replacing-text-in-a-string-using</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Thu, 15 Jan 2026 09:30:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1dd178ac-65e1-4d3c-932d-bb50cf9dccb3_1532x1148.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>String replacement in Swift looks trivial&#8212;until you touch emojis, flags, or anything outside the Unicode BMP. Then subtle Unicode details start leaking through the NSString class. Here&#8217;s a concrete example that exposes the problem.</p><h2><strong>1. The Surprising Result</strong></h2><pre><code><code>let result = "&#127464;&#127462;&#127482;&#127480;".replacingOccurrences(of: "&#127462;&#127482;", with: "&#127475;&#127470;")</code></code></pre><p><strong>Result:</strong></p><pre><code><code>&#127464;&#127475;&#127470;&#127480;</code></code></pre><p>At first glance&#8230;</p>
      <p>
          <a href="https://www.swiftwithblaze.com/p/replacing-text-in-a-string-using">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Can Swift run without the standard library?]]></title><description><![CDATA[Built-ins, compiler internals, and the limits of &#8220;bare Swift&#8221;]]></description><link>https://www.swiftwithblaze.com/p/can-swift-run-without-the-standard</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/can-swift-run-without-the-standard</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Mon, 12 Jan 2026 09:19:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/878bf70a-7ad1-4652-81db-d926f669c756_946x520.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>The short answer</h2><p>Yes &#8212; <strong>Swift can run without the standard library</strong>.<br>But once you remove it, you quickly realize that most of what you think of as &#8220;Swift&#8221; isn&#8217;t the language itself, but the <strong>standard library layered on top of compiler primitives</strong>.</p><p>To understand why, you need to understand <strong>Swift built-in types</strong>.</p><div><hr></div><h2>What &#8220;built-in types&#8221; actually are in Swift</h2><p>Swift built-in types are <strong>compiler-internal primitives</strong> exposed under a special namespace called <code>Builtin</code>. They exist <strong>below</strong> the standard library and are used by the compiler to model memory, values, and operations before anything becomes <code>Int</code>, <code>Bool</code>, or <code>Optional</code>.</p><p>Examples include:</p><ul><li><p><code>Builtin.Int1</code>, <code>Builtin.Int64</code></p></li><li><p><code>Builtin.Word</code></p></li><li><p><code>Builtin.RawPointer</code></p></li><li><p><code>Builtin.NativeObject</code></p></li><li><p><code>Builtin.BridgeObject</code></p></li><li><p><code>Builtin.FPIEEE64</code></p></li><li><p>SIL-only token and vector types</p></li></ul><p>Key facts:</p><ul><li><p>You <strong>cannot import</strong> them</p></li><li><p>They <strong>do not appear</strong> in autocomplete</p></li><li><p>They are <strong>not stable APIs</strong></p></li><li><p>They are meant for the <strong>compiler and standard library only</strong></p></li></ul><p>These types exist so Swift can lower high-level code into LLVM IR efficiently and predictably.</p><div><hr></div><h2>Built-ins vs the standard library</h2><p><code>Int</code>, <code>Bool</code>, <code>Optional</code>, <code>Array</code>, and even <code>String</code> are <strong>not built-in types</strong>. They are <strong>standard library abstractions</strong> built <em>on top of</em> built-ins.</p><p>For example, <code>Int</code> is effectively a wrapper around a compiler-known integer representation backed by a <code>Builtin.Int*</code> type. Arithmetic, comparisons, overflow behavior, and literals are implemented via compiler intrinsics operating on built-ins.</p><p>The actual layering looks like this:</p><pre><code><code>LLVM IR
&#8593;
Swift Built-in Types (Builtin.*)
&#8593;
Swift Standard Library (Int, Bool, Optional&#8230;)
&#8593;
Your Swift code
</code></code></pre><p>Once you remove the standard library, you lose everything above the <code>Builtin</code> layer.</p><div><hr></div><h2>Where built-in types live in the source</h2><p>You won&#8217;t find built-in types in Xcode documentation. You need the Swift compiler source maintained by the <strong>Swift Project</strong>.</p><p>Important locations:</p><ul><li><p><code>swift/include/swift/AST/Builtins.def</code></p></li><li><p><code>swift/include/swift/AST/BuiltinTypes.def</code></p></li></ul><p>These files define what built-ins exist and how the compiler understands them.</p><p>To see how they&#8217;re used:</p><ul><li><p><code>swift/lib/SIL/</code> &#8212; Swift Intermediate Language</p></li><li><p><code>swift/lib/IRGen/</code> &#8212; lowering to LLVM IR</p></li></ul><p>To see how the standard library wraps them:</p><ul><li><p><code>swift/stdlib/public/core/Builtin.swift</code></p></li><li><p><code>swift/stdlib/public/core/Int.swift</code></p></li><li><p><code>swift/stdlib/public/core/Optional.swift</code></p></li></ul><p>This is where compiler magic turns into user-facing APIs.</p><div><hr></div><h2>So&#8230; can Swift really run without the standard library?</h2><p>This exact question is discussed in depth on the <strong>Swift Forums</strong> in the thread <em>&#8220;<a href="https://forums.swift.org/t/swift-with-no-standard-library/61198">Swift with no standard library</a>&#8221;</em>. The conclusion is consistent and blunt:</p><ul><li><p>You can compile Swift with <code>-nostdlib</code></p></li><li><p>You can execute code using only built-ins</p></li><li><p>You lose literals, collections, strings, ARC helpers, and most conveniences</p></li><li><p>Writing meaningful programs becomes extremely low-level very quickly</p></li></ul><p>That discussion also points to an interesting experiment: <strong>&#956;Swift</strong>, available as the <code>compnerd/uswift</code> repository on GitHub. It provides a <em>minimal</em> stdlib-like core designed for constrained or experimental environments. It&#8217;s not a replacement for the real standard library, but it demonstrates that <strong>built-in types are sufficient to bootstrap higher-level abstractions</strong> &#8212; at a significant engineering cost.</p><div><hr></div><h2><strong>Takeaways</strong></h2><ul><li><p>It is technically possible to write and execute Swift code without the standard library.</p></li><li><p>Swift built-in types are thin compiler-level primitives that map directly onto LLVM representations.</p></li><li><p>A public GitHub repository <strong>compnerd/uswift</strong> demonstrates that this approach works in practice, not just in theory.</p></li><li><p>There is a thoughtful and technical discussion on the Swift Forums &#8220;<em><a href="https://forums.swift.org/t/swift-with-no-standard-library/61198">Swift with no standard library</a></em>&#8220; that explores the limits, trade-offs, and motivations behind running Swift without its standard library.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Swift String split vs components.]]></title><description><![CDATA[How to split a String into an Array in Swift?]]></description><link>https://www.swiftwithblaze.com/p/swift-string-split-vs-components</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/swift-string-split-vs-components</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 19 Dec 2025 15:52:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZkAn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZkAn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZkAn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 424w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 848w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 1272w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZkAn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:302226,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://swiftwithblaze.substack.com/i/182085202?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZkAn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 424w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 848w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 1272w, https://substackcdn.com/image/fetch/$s_!ZkAn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f38f46f-8687-4519-8fb0-0326bca9c76b_2052x1368.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">How to split a String into an Array in Swift? Swift String split vs components.</figcaption></figure></div><p>To split a String into an Array using the Swift Standard Library, use the split(separator:) method.</p><p><strong>Example split-1:</strong></p><pre><code><code>"Poland,France , Germany,, ".split(separator: ",")
</code>
<code>["Poland", "France ", " Germany", " "]</code></code></pre><p><strong>Example split-2:</strong></p><pre><code><code>"Poland,France , Germany,, ".split(separator: ",", omittingEmptySubsequences: false)

["Poland", "France ", " Germany", "", " "]</code></code></pre><p><strong>Example split-3:</strong></p><pre><code>"Poland,France , Germany,, ".split(separator: ",", maxSplits: 1)

["Poland", "France , Germany,, "]</code></pre><p><strong>Example split-4:</strong></p><pre><code>"Poland,France , Germany,, ,.Europe".split(omittingEmptySubsequences: false) { $0.isPunctuation }
["Poland", "France ", " Germany", "", " ", "", "Europe"]
</code></pre><p>In all cases, the result type is Array&lt;Substring&gt;.</p><p>To obtain String values, a transformation is needed:</p><pre><code>let s :[Substring] = "Poland,France".split(separator: ",")
let s :[String] = "Poland,France".split(separator: ",").map(String.init)</code></pre><p>There is also a Foundation&#8217;s components(separated:By) method.</p><p><strong>Example components-1:</strong></p><pre><code>"Poland,France , Germany,,".components(separatedBy: ",")

["Poland", "France ", " Germany", "", ""]</code></pre><p><strong>Example components-2:</strong></p><pre><code><code>"Poland,France , Germany,, ,.Europe".components(separatedBy: CharacterSet.punctuationCharacters)

["Poland", "France ", " Germany", "", ""]</code></code></pre><p>The result type is Array&lt;String&gt;. No transformation is needed to obtain String values.</p><h3>What is the difference between Swift Standard Library split(separator:) and Foundation&#8217;s components(separatedBy:) methods?</h3><p>There are differences between split and components methods of a Swift&#8217;s String. The components method is defined in Foundation and part of NSString and available in files which imported Foundation framework. The split method is part of Swift&#8217;s Standard Library. NSString API was evolving from 1990 and was impacted by development of Unicode, that&#8217;s why NSString memory storage is UTF-16 encoded and it&#8217;s API mainly is working on Unicode code units, in some cases it can be code units. Swift&#8217;s String is backed by UTF-8 encoded storage and it&#8217;s API is working with cluster code points. If needed the String&#8217;s API incudes access to code units via UTF-8, UTF-16 views.</p><p>When using components(separatedBy:) NSSting API must use additional operations to interpret Swift&#8217;s storage which is encoded in UTF-8 as UTF-16 which is the base for operations of NSString API.</p><p>Important to remember is that split can behave as components for adjacent occurences of separator but omittingEmptySubsequences must be set to false.</p>]]></content:encoded></item><item><title><![CDATA[Unicode and Fonts]]></title><description><![CDATA[From custom app fonts to the Last Resort font]]></description><link>https://www.swiftwithblaze.com/p/unicode-and-fonts</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/unicode-and-fonts</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Sat, 13 Dec 2025 18:18:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!dtdR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dtdR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dtdR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 424w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 848w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 1272w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dtdR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png" width="1280" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/adacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43897,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://swiftwithblaze.substack.com/i/181306784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dtdR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 424w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 848w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 1272w, https://substackcdn.com/image/fetch/$s_!dtdR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadacfdfa-dd85-4c06-907b-786a65e8ac79_1280x640.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>Unicode and Fonts</h1><p><em>From custom app fonts to the Last Resort font</em></p><p>This post explains the relationship between Unicode and fonts, with a focus on what happens when custom fonts lack glyphs. It covers font coverage limits, system fallback behavior, and why missing characters appear as fallback glyphs or, in the worst case, the Last Resort font in applications.</p><div><hr></div><h2>1. What Is Unicode?</h2><p>Unicode is an ordered system that defines characters and their identifiers.</p><p>More precisely, it defines a set of <strong>code points</strong>&#8212;numeric identifiers that uniquely represent characters in text. A code point identifies <em>what</em> a character is, not <em>how</em> it looks.</p><p>Unicode is more than a simple table. The standard also specifies algorithms for combining marks, bidirectional text ordering, normalization, segmentation, and shaping behavior for complex scripts. These rules are implemented by operating systems and text engines.</p><p>Unicode itself does not draw anything. It defines characters and their behavior; visual rendering is handled elsewhere. The same Unicode character can appear differently depending on the font and platform.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><div><hr></div><h2>2. What Is a Font?</h2><p>A font is a collection of designed glyphs, metrics, and typographic rules packaged together to render characters visually. It defines appearance, spacing, shaping behavior, and stylistic variations, and is distributed as a font file.</p><p>A <strong>Unicode font</strong> is a font that maps glyphs to code points defined by the Unicode Standard. Fonts do not define Unicode; they implement it by providing visual representations for some subset of code points.</p><p>Fonts that support a wide range of scripts and symbols are sometimes called <strong>pan-Unicode fonts</strong>. However, a single font file is limited to <strong>65,535 glyphs</strong>, because glyph identifiers are 16-bit values. As a result, no single font can provide distinct glyphs for all defined Unicode characters (159,801 characters in Unicode 17.0).</p><p>In practice, &#8220;pan-Unicode&#8221; does not mean one font file. It refers to a <strong>family of coordinated fonts</strong>, each covering different scripts or character ranges.</p><p>Notable examples include Noto (Google), Arial Unicode MS (Microsoft), DejaVu Sans, and GNU Unifont.</p><div><hr></div><h2>3. What Is the Noto Font Family?</h2><p>The Noto<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a> font family is a collection of open-source fonts created by Google that aims to provide consistent coverage across Unicode scripts. &#8220;Noto&#8221; means &#8220;No Tofu&#8221;, referring to the goal of eliminating missing-glyph boxes.</p><p>Rather than a single massive font, Noto is composed of script-specific fonts (Latin, Arabic, CJK, Emoji, and others) designed to work together visually. Despite its broad coverage, Noto is not fully complete, and systems may still fall back to other fonts or the Last Resort font for rare or newly added code points.</p><div><hr></div><h2>4. Font Fallback Mechanism</h2><p>Font fallback<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a> is handled by the operating system&#8217;s text rendering stack, which sits between applications and fonts. When an application requests text rendering, the system maps Unicode code points to glyphs provided by the selected font.</p><p>If a glyph is missing, the text engine automatically searches a prioritized set of fallback fonts that better match the script, language, and typographic context. This resolution happens at the glyph level and may result in multiple fonts being used within the same line of text.</p><p>If no available font contains the required glyph, the system ultimately uses the <strong>Last Resort font</strong>, indicating missing font coverage rather than invalid text.</p><div><hr></div><h2>5. What Is the Last Resort Font?</h2><p>The Last Resort font<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a> is a special-purpose font used by operating systems as the final step in the font fallback process. It does not attempt to render characters correctly or aesthetically.</p><p>Instead, it provides a generic placeholder glyph for every possible Unicode code point. Each glyph typically appears as a box containing a visual representation of the character&#8217;s Unicode value.</p><p>This makes the Last Resort font diagnostic rather than typographic. Its presence indicates that the character is valid Unicode, but no installed font provides a proper glyph for it. If you see this font, you have a font coverage problem.</p><div><hr></div><h2>6. Debug Fonts</h2><p>Adobe also provides specialized diagnostic fonts such as Adobe Blank<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a> and Adobe .notdef. Adobe Blank is a font that intentionally contains empty glyphs for most characters, making rendered text effectively invisible. It is used to detect unintended text rendering or layout dependencies. Adobe .notdef focuses on exposing missing-glyph behavior by forcing the use of the .notdef glyph. Unlike the Last Resort font, these fonts are developer tools, not system fallbacks, and are used deliberately to debug font coverage and rendering assumptions.</p><div><hr></div><h2>7. Custom App Fonts</h2><p>When an application specifies a custom font and that font does not contain a glyph for a given code point, the operating system performs fallback:</p><ul><li><p>Try the custom font</p></li><li><p>If the glyph is missing, try system fallback fonts</p></li><li><p>If no glyph exists anywhere, display a tofu box or the Last Resort font</p></li></ul><p>This fallback often appears as a sudden change in style inside a word, label, or paragraph.</p><div><hr></div><h2>8. Practical Advice for App Developers</h2><p>Use the system default font unless your app&#8217;s identity truly depends on a custom typeface.</p><p>System fonts provide broad script coverage and built-in shaping support, but they can change across OS versions. Metric adjustments may occur, which can lead to screenshot testing failures.</p><p>Choosing a custom font can be a deliberate way to gain visual stability and independence from system font changes. If you choose a custom font:</p><ul><li><p>Verify that the languages most important to your users are supported</p></li><li><p>Expect fallback for unsupported characters</p></li><li><p>Remember that, in the worst case, missing glyphs will be rendered using the Last Resort font</p></li></ul><p>Unicode guarantees character identity, not font availability or visual appearance.</p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>Font and keyboard FAQ: https://www.unicode.org/faq/font_keyboard</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>Noto fonts on Wikipedia: https://en.wikipedia.org/wiki/Noto_fonts</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>Fallback Font on Wikipedia: https://en.wikipedia.org/wiki/Fallback_font</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self">4</a><div class="footnote-content"><p>Last resort font on Github: https://github.com/unicode-org/last-resort-font</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-5" href="#footnote-anchor-5" class="footnote-number" contenteditable="false" target="_self">5</a><div class="footnote-content"><p>Adobe blank debug font on Github: https://github.com/adobe-fonts/adobe-blank/</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[What Does the "Text Encoding" Option in Xcode Mean?]]></title><description><![CDATA[Default Xcode UTF encoding is UTF-8.]]></description><link>https://www.swiftwithblaze.com/p/what-does-the-text-encoding-option</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/what-does-the-text-encoding-option</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Mon, 08 Dec 2025 12:42:56 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2c9d2da2-9eba-45dd-9637-296991d50c97_3264x1684.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Xcode exposes a &#8220;Text Encoding&#8221; option in the File Inspector, but its purpose today is mostly historical &#8212; and in practice, misleading. In the latest Xcode versions, including Xcode 26.1, this option creates the impression that you can choose how a file is encoded, but the feature does not actually work.</p><p>Let&#8217;s break down what this option <em>claims</em> to do versus what actually happens.</p><h2>1. The &#8220;Text Encoding&#8221; option in Xcode 26.1 does not function</h2><p>When you change the encoding in the File Inspector:</p><ul><li><p>Xcode prompts for confirmation</p></li><li><p>Xcode pretends it will convert the file</p></li><li><p>But the final result is: nothing changes</p></li></ul><p>Xcode does not detect the file&#8217;s actual encoding, does not convert it, and does not re-encode it to the selected option. The feature appears to be a leftover UI component that no longer matches how the Swift toolchain works.</p><p>If you expect Xcode to convert a file to UTF-16, UTF-32, ISO-Latin-1, or anything else, it won&#8217;t.</p><h2>2. Xcode source files must be UTF-8</h2><p>Regardless of what the UI suggests, Xcode&#8217;s only accept UTF-8 encoded source files.</p><p>If a .swift file is saved as UTF-16 or any non-UTF-8 format, Xcode displays:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7St_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7St_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 424w, https://substackcdn.com/image/fetch/$s_!7St_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 848w, https://substackcdn.com/image/fetch/$s_!7St_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 1272w, https://substackcdn.com/image/fetch/$s_!7St_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7St_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png" width="1456" height="74" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:74,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28399,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://swiftwithblaze.substack.com/i/181028773?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7St_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 424w, https://substackcdn.com/image/fetch/$s_!7St_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 848w, https://substackcdn.com/image/fetch/$s_!7St_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 1272w, https://substackcdn.com/image/fetch/$s_!7St_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bb89043-3e35-4a22-a990-ba6565a4e295_1928x98.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><strong>Xcode error: Input files must be encoded as UTF-8 instead of UTF-16</strong></figcaption></figure></div><p>The compiler does not auto-convert the file, and Xcode does not fix the encoding.</p><p>You must manually resave the file as UTF-8 with for example Visual Studio Code</p><h2>3. Swift itself rejects non-UTF-8 source files</h2><p>Swift source code must be valid UTF-8.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a> If a .swift file is saved using UTF-16 or UTF-32, the Swift compiler immediately stops with an error and will not attempt any recovery or transcoding.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g02Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g02Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 424w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 848w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 1272w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g02Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png" width="1456" height="227" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:227,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54785,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://swiftwithblaze.substack.com/i/181028773?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g02Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 424w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 848w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 1272w, https://substackcdn.com/image/fetch/$s_!g02Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb84101bc-7486-407a-b886-c8a720dc6a69_1464x228.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Swift error: input files must be encoded as UTF-8 instead of UTF-16</figcaption></figure></div><h2>4. Conclusion</h2><p>The &#8220;Text Encoding&#8221; control in Xcode looks like a real feature, but in modern toolchains it is effectively non-functional. Swift requires UTF-8, Xcode enforces UTF-8. Everything else will produce errors &#8212; and Xcode&#8217;s encoding selector won&#8217;t help you. If you&#8217;re assuming that Xcode can convert or detect encoding for you, it won&#8217;t.</p><h2>Want to learn more about encodings?</h2><p>This is part of a larger story: Unicode, UTF-8 as Swift&#8217;s native storage format, and the differences between encodings like UTF-8, UTF-16, and UTF-32. I cover all of that in this post:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;178bce18-d2c7-4270-be83-2e1cb3341494&quot;,&quot;caption&quot;:&quot;Understanding Unicode helps in using both Swift&#8217;s String and NSString APIs and their underlying behaviors.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Unicode for iOS Developers&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:329274804,&quot;name&quot;:&quot;Blaze&quot;,&quot;bio&quot;:&quot;Ex-Lead iOS Developer, self-taught with 15 years of experience. Writing about building apps with Swift for Apple platforms, mainly iOS. Worked across fintech, startups, and public orgs including BNP Paribas, Radio France, and Viadeo/Figaro.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21275274-fd18-4f38-ba33-edd9858ef765_800x800.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-12-06T07:28:18.745Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!2qIT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://swiftwithblaze.substack.com/p/unicode-for-ios-developers&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:180808604,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:6478525,&quot;publication_name&quot;:&quot;Swift With Blaze&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!oLx_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4094dd4a-505b-475e-90a2-6ad83274cf3d_256x256.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>https://forums.swift.org/t/may-swift-source-code-be-in-utf-16-in-xcode/34494/2</p><p></p></div></div>]]></content:encoded></item><item><title><![CDATA[Unicode for iOS Developers]]></title><description><![CDATA[Swift's String and UTF-8]]></description><link>https://www.swiftwithblaze.com/p/unicode-for-ios-developers</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/unicode-for-ios-developers</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Sat, 06 Dec 2025 07:28:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2qIT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Understanding Unicode helps in using both Swift&#8217;s String and NSString APIs and their underlying behaviors.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2qIT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2qIT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 424w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 848w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 1272w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2qIT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic" width="1456" height="563" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:563,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:81945,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://swiftwithblaze.substack.com/i/180808604?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2qIT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 424w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 848w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 1272w, https://substackcdn.com/image/fetch/$s_!2qIT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a314784-9175-4d96-ad92-40d603a1a80a_2204x852.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Comparison of String and NSString character-counting properties and encoding details</figcaption></figure></div><h2><strong>1. A short history of Unicode (with key dates)</strong></h2><p>Before Unicode, computing was a patchwork of character sets: ASCII in the US, ISO-8859 variants in Europe, Shift-JIS in Japan, KOI8-R in Russia, and many others. There was no universal representation of human scripts. Unicode was created with a clear goal: one universal character set for all present and ancient scripts, encoded in multiple efficient ways.</p><p>Major milestones:</p><ul><li><p>1963 &#8212; ASCII created (7-bit). Good for English, useless for anything else.</p></li><li><p>1987 &#8212; Unicode project begins, aiming to create a unified character set for all languages.</p></li><li><p>1991 &#8212; Unicode 1.0 released (first official version).</p></li><li><p>1996 &#8212; UTF-8 invented by Ken Thompson and Rob Pike; becomes the dominant web encoding.</p></li><li><p>2000s &#8212; Widespread adoption across OSes, browsers, mobile devices.</p></li><li><p>2010s &#8212; Emoji explosion, including ZWJ (zero-width joiner) sequences and multi-person, multi-skin-tone combinations.</p></li><li><p>Swift 5 (2019) &#8212; Swift adopts a stable UTF-8-based String storage.</p></li></ul><h2><strong>2. What are UTF encodings?</strong></h2><p>Unicode defines code points: conceptual identifiers like U+0041 (&#8220;A&#8221;) or U+1F600 (&#8220;&#128512;&#8221;). These are not bytes and not glyphs &#8212; just unique identifiers for characters.</p><p>Encodings define <em>how to store these identifiers in bytes</em>.</p><p>Example: Code point U+41 (character: &#8220;A&#8220;)</p><ul><li><p>UTF-8 &#8594; 0x41 (1 code unit, each of 1 byte, gives 1 bytes)</p></li><li><p>UTF-16 &#8594; 0x0041 (1 code unit, each of 2 bytes, gives 2 bytes)</p></li><li><p>UTF-32 &#8594; 0x00000041 (1 code unit of 4 bytes, gives 4 bytes)</p></li></ul><p>Example: Code point U+1F600 (emoji: &#8220;&#128512;&#8221;)</p><ul><li><p>UTF-8 &#8594; 0xF0 0x9F 0x98 0x80 (4 code units, each of 1 byte, gives 4 bytes)</p></li><li><p>UTF-16 &#8594; 0xD83D 0xDE00 (2 code units, each of 2 bytes, gives 4 bytes)</p></li><li><p>UTF-32 &#8594; 0x0001F600 (1 code unit, each of 4 bytes, gives 4 bytes)</p></li></ul><p>Encodings exist because different trade-offs matter: compactness, speed, compatibility.</p><h2><strong>3. UTF-8 vs UTF-16 vs UTF-32</strong></h2><h3><strong>UTF-8</strong></h3><ul><li><p>number of code units per code point: 1 to 4</p></li><li><p>code unit: 1 byte</p></li><li><p>maximum size in bytes: 4</p></li><li><p>maximum size in bits: 32</p></li><li><p>ASCII and Latin text remain compact (ASCII stays 1 byte; Western European characters usually 2 bytes)</p></li><li><p>Standard on Linux, macOS, iOS, web</p></li></ul><h3><strong>UTF-16</strong></h3><ul><li><p>number of code units per code point: 1 to 2</p></li><li><p>code unit: 2 byte</p></li><li><p>maximum size in bytes: 4</p></li><li><p>maximum size in bits: 32</p></li><li><p>Basic Multilingual Plane (BMP - most of characters used in Western European and China/Japan/Korean CJK languages) fits in 2 bytes</p></li><li><p>Supplementary characters (emoji, flags) use <em>surrogate pairs</em></p></li><li><p>Historically used by Windows, Java, .NET, <em>NSString</em></p></li></ul><h3><strong>UTF-32</strong></h3><ul><li><p>number of code units per code point: 1</p></li><li><p>code unit: 4 byte</p></li><li><p>fixed size in bytes: 4</p></li><li><p>fixed size in bits: 32</p></li><li><p>Unicode code point directly as a 32-bit integer.</p></li><li><p>Simplest for indexing</p></li><li><p>Wasteful in RAM and storage</p></li><li><p>Rarely used outside internal processing</p></li></ul><h2><strong>4. Swift&#8217;s String is UTF-8</strong></h2><p>Since Swift 5, String stores its contents in memory using UTF-8 encoding as the native representation. When you call String.count, Swift does not count bytes or Unicode scalars, it counts extended grapheme clusters, meaning the number of characters as a human perceives them.</p><p>Example:</p><pre><code>let s = "&#127477;&#127473;" // it is composed emoji of two regional letters &#127477;: U+1F1EA and &#127473;: U+1F1FA  
print(s.utf8.count)  // 8 code units, 8 bytes
print(s.utf16.count) // 4 code units, 8 bytes
print(s.unicodeScalars.count) // 2
print(s.count)       // 1 character</code></pre><h2><strong>5. NSString uses UTF-16</strong></h2><p>Whenever you use Foundation, Objective-C interoperability comes into play. NSString encodes text using UTF-16, and its API operate at the UTF-16 code-unit level. This leads to:</p><ul><li><p>.length returning number of UTF-16 code units, <em>not</em> characters</p></li><li><p>Indexing based on those UTF-16 code units</p></li></ul><p>Example:</p><pre><code>let flag = "&#127467;&#127479;" as NSString 
// 2 code points: F(U+1F1EB) R(U+1F1F7)
// 4 UTF-16 code units: F - (D83C) (DDEB) R - (D83C) (DDF7)
// 8 Bytes in total
print(flag.length) // 4 UTF-16 code units</code></pre><h2><strong>6. Swift is a wrapper around NSString when Foundation is imported</strong></h2><p>When you write:</p><pre><code>import Foundation</code></pre><p>String gains automatic bridging to NSString. This has several consequences:</p><ul><li><p>When using the String API, it becomes difficult to know whether autocomplete suggestions come from String or from NSString.</p></li><li><p>It is possible to break a Swift String by using certain NSString APIs, because they operate on UTF-16 code units rather than Swift&#8217;s grapheme-cluster&#8211;safe model.</p></li></ul><h2><strong>7. How NSString APIs can break a Swift String</strong></h2><p>Take a flag emoji. It&#8217;s composed of two Unicode Regional Indicator symbols.</p><p>Swift counts this as one extended grapheme cluster.</p><p>NSString.length, however, counts UTF-16 code units, so the same flag becomes four UTF-16 units.</p><p>NSString methods such as substring(with:) operate on UTF-16 code units, not grapheme clusters.</p><p>If you request a substring of length 1, you slice half of a surrogate pair of the first Unicode Regional Indicator symbol , producing an invalid string.</p><pre><code>var s = "&#127477;&#127473;"
let ns = s as NSString
let broken = ns.substring(with: NSRange(location: 0, length: 1)) // half of the regional letter P
prints nothing

var s = &#8220;&#127477;&#127473;&#8221;
let ns = s as NSString
let ok = ns.substring(with: NSRange(location: 0, length: 2))
prints full regional letter &#127477;</code></pre><p>Most developers never encounter these issues, but when working with emoji, flags, or ZWJ sequences, careless use of NSString APIs can corrupt text because they operate on UTF-16 code units, not Swift&#8217;s grapheme-cluster-safe model.</p><h2><strong>8. Character limits in TextFields: stay aligned with your backend</strong></h2><p>User-input character limits only work if the application and backend count text the same way. If the backend API documentation does not specify what is being counted, extended grapheme clusters, Unicode code points, UTF-8 bytes, or UTF-16 code units, you must either determine the method empirically or ask the backend team directly.</p><h2><strong>8. Key facts</strong></h2><ul><li><p>Swift&#8217;s String stores data in UTF-8.</p></li><li><p>NSString stores data in UTF-16.</p></li><li><p>Importing Foundation makes Swift.String transparently bridge to NSString.</p></li><li><p>Many NSString APIs operate on UTF-16 code units, not Unicode characters.</p></li><li><p>NSString&#8217;s UTF-16 APIs can easily break complex Unicode sequences (flags, emojis, ZWJ).</p></li><li><p>Use native Swift String methods whenever possible.</p></li><li><p>If someone asks, &#8220;What encoding should I use for String or Data?&#8221; &#8594; Default answer: UTF-8.</p></li></ul><h2>Related post:</h2><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;25efd187-802f-4957-93dd-f1330cd23a3e&quot;,&quot;caption&quot;:&quot;Unicode is a character-encoding standard maintained by the Unicode Consortium. It provides a universal foundation for processing, storing, and exchanging text in any language across modern software systems. Before Unicode existed, computers used a long chain of incompatible encodings: ASCII, then ISO-8859 variants, and earlier systems such as ITA2 (Baud&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Unicode for Software Developers&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:329274804,&quot;name&quot;:&quot;Blaze&quot;,&quot;bio&quot;:&quot;Ex-Lead iOS Developer, self-taught with 15 years of experience. Writing about building apps with Swift for Apple platforms, mainly iOS. Worked across fintech, startups, and public orgs including BNP Paribas, Radio France, and Viadeo/Figaro.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21275274-fd18-4f38-ba33-edd9858ef765_800x800.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-28T16:10:59.334Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!hubR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://swiftwithblaze.substack.com/p/unicode-for-software-developers&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:179451876,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:6478525,&quot;publication_name&quot;:&quot;Swift With Blaze&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!oLx_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4094dd4a-505b-475e-90a2-6ad83274cf3d_256x256.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h2><strong>Useful links:</strong></h2><p>https://www.compart.com/</p><p>https://codepoints.net/</p><p>https://emojipedia.org</p><p>https://forums.swift.org/t/can-encoding-string-to-data-with-utf8-fail/22437/5</p><p>https://www.swift.org/blog/utf8-string/</p><p>https://en.wikipedia.org/wiki/UTF-8</p><p>https://en.wikipedia.org/wiki/UTF-16</p><p>https://en.wikipedia.org/wiki/Unicode</p>]]></content:encoded></item><item><title><![CDATA[Unicode for Software Developers]]></title><description><![CDATA[Short history of Unicode]]></description><link>https://www.swiftwithblaze.com/p/unicode-for-software-developers</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/unicode-for-software-developers</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 28 Nov 2025 16:10:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hubR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hubR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hubR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 424w, https://substackcdn.com/image/fetch/$s_!hubR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 848w, https://substackcdn.com/image/fetch/$s_!hubR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 1272w, https://substackcdn.com/image/fetch/$s_!hubR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hubR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic" width="992" height="536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:536,&quot;width&quot;:992,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43684,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://vectorterra.substack.com/i/179451876?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hubR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 424w, https://substackcdn.com/image/fetch/$s_!hubR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 848w, https://substackcdn.com/image/fetch/$s_!hubR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 1272w, https://substackcdn.com/image/fetch/$s_!hubR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6d01923-3eb8-46a2-ae99-f6721a9e81b5_992x536.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Unicode is a character-encoding standard maintained by the Unicode Consortium. It provides a universal foundation for processing, storing, and exchanging text in any language across modern software systems. Before Unicode existed, computers used a long chain of incompatible encodings: ASCII, then ISO-8859 variants, and earlier systems such as ITA2 (Baudot&#8211;Murray), ITA1, and even Morse code.</p><div><hr></div><h2><strong>Short history of Unicode</strong></h2><p><strong>Creation and founders</strong></p><p>The Unicode Consortium was created in 1987 by engineers from Xerox and Apple, including Joe Becker, Lee Collins, and Mark Davis. Their goal was to design a single universal character set that could replace the dozens of regional encodings used around the world.</p><p><strong>Why Unicode was needed</strong></p><p>The growth of global software made national encodings impossible to maintain. Each region used its own system&#8212;ISO-8859-1 for Western Europe, Windows-1250 for Central Europe, Shift-JIS for Japan, GB for China, KOI8-R for Russia, and many others. These encodings were incompatible: the same byte could represent different letters depending on the system, which made text exchange unreliable. Developers often had to build multiple &#8220;locale-specific&#8221; versions of the same software. Unicode eliminated this fragmentation by defining one code point for every character&#8212;Latin, Cyrillic, Arabic, Chinese ideographs, Korean Hangul, Japanese kana, and eventually emojis. With one unified set, global software finally became practical.</p><p><strong>Draft proposal of Unicode88 &#8212; August, 1988</strong></p><p>Joseph D. Becker (Xerox) described the core problem clearly: people need to compute in their native languages, not just in English. ASCII was too small for that. Future systems needed a single multilingual standard covering Latin alphabets, major non-Latin scripts, and thousands of CJK ideographs. https://www.unicode.org/history/unicode88.pdf</p><p><strong>ISO 10646 drafts &#8212; 1988&#8211;1990</strong></p><p>ISO proposed a 31-bit design, not aligned with ASCII, and driven by national-body processes. The approach was bureaucratic and technically difficult to implement on 1980s hardware.</p><p><strong>Unicode version 1 &#8212; October, 1991</strong></p><p>Unicode initially rejected ISO&#8217;s proposal. The Consortium believed a 16-bit space was enough to encode all necessary characters, and keeping ASCII compatibility was essential. ISO disagreed, and Version 1.0 received no international approval.</p><p><strong>Unicode Version 1.1 and ISO/IEC 10646-1:1993 &#8212; June, 1993</strong></p><p>A compromise was reached: ISO adopted Unicode&#8217;s code charts, and Unicode adopted ISO&#8217;s plane structure. Both standards were synchronized to define the same characters at the same code points, with guaranteed ASCII compatibility.</p><p><strong>Unicode Version 2 &#8212; July, 1996</strong></p><p>Real-world requirements showed that 16 bits were not enough. China and Japan requested thousands of additional ideographs used in legal names and government documents. China later required all software sold in the country to support its complete repertoire. This pushed Unicode and ISO to expand beyond the original 65,536-code-point limit. Unicode 2.0 introduced surrogate pairs and expanded the design to a 21-bit code space. UCS-2 became UTF-16, enabling characters outside the Basic Multilingual Plane. This expansion was strongly influenced by Chinese national standards such as GB 18030.</p><p><strong>Relationship between Unicode and ISO</strong></p><p>Unicode and ISO now work jointly, but they began with different roles. ISO, as an international standards body, has political authority&#8212;governments depend on it for regulation and language policy. Unicode, founded by private-sector engineers, moved faster and focused on solving technical problems. Over time both organizations aligned: ISO provides global legitimacy, while Unicode defines the technical rules&#8212;encoding behavior, normalization, bidirectional text, and emoji specifications. Today they share a synchronized repertoire.</p><p><strong>Why ASCII tables still matter?</strong></p><p>Unicode kept ASCII as its foundation. The first 128 code points are identical to ASCII, so modern systems inherently support ASCII. Developers still consult ASCII tables because many low-level protocols&#8212;HTTP, email, URLs, shells, programming languages&#8212;continue to rely on ASCII byte values. Unicode didn&#8217;t replace ASCII; it extended it.</p><p><strong>Are modern languages affected by Unicode?</strong></p><p>Yes. Each language integrates Unicode differently based on its historical string model.</p><p><strong>Swift</strong> has been strongly influenced by Unicode, especially since Swift 5 switched String to native UTF-8 storage. It treats Unicode correctly at a high level, supporting grapheme clusters, ZWJ emoji, flags, combining characters, and normalization. Indexing operates on extended grapheme clusters rather than UTF-16 units, although bridging to NSString reintroduces UTF-16 semantics when older APIs are involved. As a result, Swift is one of the most Unicode-correct mainstream languages.</p><p><strong>Objective-C</strong>, through NSString and CFString, uses UTF-16 internally. Its length and indexing operations work at the level of UTF-16 code units rather than Unicode scalars or grapheme clusters. Modern Unicode constructs such as surrogate pairs, flags, ZWJ sequences, and emoji with modifiers break the assumptions behind its basic APIs, and it provides no native way to iterate grapheme clusters without relying on higher-level functions. Objective-C can represent the full Unicode repertoire, but it cannot interpret many modern features correctly at the raw API level.</p><p><strong>Java</strong> is similarly affected because it also stores String as UTF-16, inheriting the same limitations as Objective-C. Its length() method counts 16-bit code units rather than characters, and any character above the Basic Multilingual Plane requires explicit surrogate handling. Later versions added improved Unicode support in regular expressions and utility classes, but the underlying string model remains firmly tied to the older UTF-16/UCS-2 style. In practice, Java supports Unicode but remains constrained by decisions made in the 1990s.</p><p><strong>Kotlin</strong>, when running on the JVM, inherits Java&#8217;s UTF-16 representation. Its String.length property counts UTF-16 units, and surrogate pairs, emojis, and ZWJ sequences behave exactly as they do in Java. Even Kotlin Multiplatform aligns with UTF-16 for compatibility reasons. As a result, Kotlin&#8217;s Unicode behavior is limited by the JVM&#8217;s architecture and is not as correct or flexible as more modern approaches like Swift&#8217;s.</p><p><strong>Which encoding do modern operating system kernels actually use for filenames, system calls, and process arguments? Do macOS, Linux, and Windows rely on UTF-8, UTF-16, or something else internally?</strong></p><p>macOS follows UNIX conventions and uses UTF-8 for almost all system-level interfaces exposed to userland. The kernel itself treats filenames as byte sequences but the entire Apple ecosystem assumes UTF-8 as the canonical encoding. Linux kernels do not enforce Unicode at all: they store filenames and arguments as raw bytes and leave interpretation to userland, which today standardizes on UTF-8 through glibc and desktop environments. Windows is the outlier: the NT kernel and the Win32 API are built around UTF-16, and APIs that accept UTF-8 are thin compatibility layers added later. As a result, the behavior of text at the OS boundary still differs significantly across platforms.</p><p><strong>Are UI frameworks on iOS and Android aware of modern Unicode features such as emojis, ZWJ sequences, flag pairs, and other complex grapheme clusters?</strong></p><p>Yes, but the awareness comes from the text-rendering stack, not the UI frameworks themselves. On iOS, both UIKit and SwiftUI rely on Core Text, Core Graphics, and Apple&#8217;s system fonts. These layers fully support emojis, ZWJ sequences, flag pairs, skin-tone modifiers, and other grapheme clusters defined by modern Unicode. On Android, both the View system and Jetpack Compose depend on HarfBuzz, Minikin, and system fonts, which implement the same modern Unicode rules. The frameworks do not parse or interpret complex characters on their own; they delegate rendering, shaping, and cluster boundaries to lower-level text engines that track the evolving Unicode standard.</p><p><strong>Why is there a difference between how Foundation handles Unicode features and how UI frameworks on iOS and Android display them? Shouldn&#8217;t both layers support the same modern Unicode behavior?</strong></p><p>Foundation is an older API layer whose string behavior is shaped by historical constraints such as UTF-16 storage, legacy Objective-C design, and APIs that operate on code units rather than grapheme clusters. As a result, certain modern Unicode constructs&#8212;ZWJ sequences, complex emojis, multi-scalar clusters&#8212;cannot be interpreted correctly by its low-level methods. UI frameworks, on the other hand, do not parse Unicode themselves. They delegate all shaping, rendering, and grapheme-boundary decisions to system text engines like Core Text and HarfBuzz, which track the latest Unicode specifications. This separation means the rendering layer keeps up with modern Unicode evolution, while older string APIs in Foundation or the JVM may lag behind because they were designed around simpler character models.</p><p><strong>What is the difference between UCS-2, UCS-4, UTF-8, UTF-16, and UTF-32?</strong></p><p><strong>UCS-2</strong> was the original fixed-width encoding of Unicode 1.0 in 1991. It stored every character in exactly sixteen bits and reflected the early belief that 65,536 positions would be sufficient for all writing systems. Once the standard began to incorporate larger repertoires&#8212;especially after CJK countries highlighted the vast number of ideographs in real use&#8212;it became clear that UCS-2 could not scale beyond the Basic Multilingual Plane, and it became obsolete once Unicode adopted surrogate pairs.</p><p><strong>UCS-4</strong> emerged from the early ISO/IEC 10646 work between 1989 and 1993. ISO originally proposed a massive 31-bit code space. The final ISO 10646-1:1993 edition reduced this to a fixed 32-bit representation, still far larger than practical Unicode needs. After Unicode and ISO unified their repertoires, UCS-4 remained simply a 32-bit encoding form capable of representing the same 21-bit Unicode range, mainly used in specialized systems where simplicity mattered more than memory.</p><p><strong>UTF-8</strong> was invented in 1992 by Ken Thompson and Rob Pike and became part of Unicode 1.1 in 1993. It stores characters in a variable number of bytes from one to four and keeps ASCII as a one-byte identity mapping. UTF-8 quickly became the dominant encoding on Unix systems, the web, and almost all modern text protocols because of its compactness and compatibility with existing ASCII-based tools.</p><p><strong>UTF-16</strong> was introduced with Unicode 2.0 in 1996. It replaced UCS-2 by extending the original 16-bit model with surrogate pairs that represent characters above U+FFFF. This allowed Unicode to expand to a 21-bit code space without breaking software built around 16-bit code units. UTF-16 became the internal string representation for Windows, Java, .NET, and Apple&#8217;s NSString/CFString.</p><p><strong>UTF-32</strong> appeared in the late 1990s as a simplified version of UCS-4 restricted to the actual Unicode range. It stores every code point in exactly four bytes. Although easy to process, it is space-inefficient, so it is rarely used for storage and instead appears mainly in internal structures of compilers, font engines, or low-level text tools.</p><p>In summary, UCS-2 and UCS-4 were early fixed-width forms tied to the initial Unicode and ISO designs; UTF-8, UTF-16, and UTF-32 are modern encoding forms introduced throughout the 1990s to reconcile practicality, compatibility, and the need for a larger code space as Unicode matured.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!St7Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!St7Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 424w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 848w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 1272w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!St7Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic" width="1456" height="1091" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1091,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:136647,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://vectorterra.substack.com/i/179451876?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!St7Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 424w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 848w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 1272w, https://substackcdn.com/image/fetch/$s_!St7Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecbed670-977b-4aa1-a7fd-c679449fd69a_1524x1142.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Hello World! encoded in UTF-8, UTF-16 and UTF-32 encodings</figcaption></figure></div><p><strong>Which Unicode encoding is the most widely used today, and why?</strong></p><p>The most widely used Unicode encoding today is UTF-8, by a very large margin. It dominates the modern computing world because it preserves ASCII as a one-byte identity mapping, works smoothly with legacy Unix tools, and compresses Western languages extremely well. Almost all major platforms and technologies&#8212;Linux, macOS, iOS, Android, web browsers, servers, JSON, HTML, XML, email, and modern programming languages&#8212;standardize on UTF-8 for storage, communication, and file formats. Large-scale measurements confirm this dominance: well over 95% of all web pages are now encoded in UTF-8, and new protocols are designed around it by default.</p><p>UTF-16 and UTF-32 remain in use, but mainly as internal representations inside specific programming ecosystems. UTF-16 persists inside Java, Kotlin (JVM and Native), .NET, and Objective-C&#8217;s NSString, while UTF-32 appears occasionally in low-level text engines. However, when it comes to actual text exchange, files, services, and the internet as a whole, UTF-8 is by far the most popular encoding in the world today.</p><p><strong>If UTF-8 is the most widely used encoding today, why did China push for Unicode to expand beyond the original 16-bit limit?</strong></p><p>China&#8217;s push to expand Unicode beyond 16 bits had nothing to do with UTF-8&#8217;s popularity. It was about the size of the Unicode repertoire itself, not about how Unicode was encoded.</p><p>In the early 1990s, Unicode was based on a 16-bit model (UCS-2), which allowed only 65,536 code points. The designers believed this would cover all writing systems. Once China, Japan, and Korea examined the standard more closely, they discovered that the number of ideographs needed for real-world use&#8212;especially for names, publications, government documents, and variant forms&#8212;far exceeded that limit. Many of these characters are rarely used in ordinary text, but they are legally and administratively essential. If a standard cannot encode the characters in a citizen&#8217;s name, a place name, or an official document, it is not viable for national use.</p><p>China therefore required Unicode to support all ideographs in national standards, including less common ones, and eventually introduced GB 18030, which made full coverage mandatory for software sold in China. Because the BMP was too small for this expanded repertoire, Unicode had to move from the fixed 16-bit UCS-2 model to the 21-bit model introduced in Unicode 2.0. That transition brought surrogate pairs and UTF-16, enabling more than one million possible code points.</p><p>This expansion was a repertoire problem, not an encoding problem. UTF-8 could already encode far more than 65,536 characters from the start, so its popularity is unrelated. Unicode needed more than 16 bits because the world&#8217;s scripts genuinely required more characters&#8212;not because of how those characters were encoded.</p><p><strong>When converting raw data into a string in Swift, Objective-C, Java, or Kotlin on Android, which text encoding should be used?</strong></p><p>Across all these languages and platforms, the correct encoding to use when decoding external data is UTF-8. Modern systems&#8212;Apple platforms, Android, web services, JSON, XML, SQLite, network protocols, and almost every contemporary file format&#8212;standardize on UTF-8 for text interchange.</p><p>Swift internally stores strings as UTF-8, and Objective-C uses UTF-16 internally, but both expect incoming data to be UTF-8 and convert it automatically after decoding. Android&#8217;s Java and Kotlin also store strings as UTF-16, yet the entire Android ecosystem assumes UTF-8 for external data, from HTTP clients to JSON libraries and resource files.</p><p>You should only choose another encoding when dealing with legacy data created in old regional code pages (Windows-125x, ISO-8859-x, Shift-JIS, GBK, etc.). For modern applications and APIs, UTF-8 is the universal and correct choicefor decoding raw bytes into text.</p>]]></content:encoded></item><item><title><![CDATA["Hello World!" in Terminal]]></title><description><![CDATA[What is the difference between echo, print and printf commands]]></description><link>https://www.swiftwithblaze.com/p/hello-world-in-terminal</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/hello-world-in-terminal</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Mon, 24 Nov 2025 10:45:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xZ_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xZ_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xZ_E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 424w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 848w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 1272w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xZ_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png" width="717" height="537" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:537,&quot;width&quot;:717,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:455015,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://vectorterra.substack.com/i/179797680?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xZ_E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 424w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 848w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 1272w, https://substackcdn.com/image/fetch/$s_!xZ_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2611ba54-6617-4b9e-9f4b-adf93c13f2e3_717x537.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Key dates of the shell commands: echo, print and printf</figcaption></figure></div><p>To print &#8220;Hello World!&#8220; in macOS Terminal using the default zsh shell, just type <code>echo</code></p><pre><code><code>echo &#8220;Hello World!&#8220;</code></code></pre><p>but hey, you can do it as well with <code>printf</code></p><pre><code><code>printf &#8220;Hello World!&#8220;</code></code></pre><p>and even with <code>print</code></p><pre><code><code>print &#8220;Hello World!&#8221;</code></code></pre><h2>What it the difference between these three commands?</h2><p>Each command appeared at the different moment and for different reasons.</p><h3>1. <code>echo</code> &#8212; the oldest (early 1970s)</h3><p><strong>Origin:</strong> UNIX Version 1 (AT&amp;T Bell Labs)<br><strong>Creators:</strong> Ken Thompson &amp; Dennis Ritchie (UNIX authors)<br><strong>First appearance:</strong> <strong>1971</strong></p><p><code>echo</code> was one of the original commands in early Unix.<br>Its only job: write text to standard output.<br>That&#8217;s why it&#8217;s primitive, inconsistent, and full of historical quirks &#8212; it predates portability standards, POSIX, and even ANSI C.</p><p>It existed long before shells became programmable languages.</p><div><hr></div><h3>2. <em>printf</em> &#8212; much later (1980s &#8594; 1992 standardization)</h3><p><strong>Origin:</strong> C programming language&#8217;s <code>printf</code> (Brian Kernighan &amp; Dennis Ritchie) around 1972&#8211;1974<br><strong>Shell version introduced:</strong> AT&amp;T System V shell (/usr/bin/printf), mid-1980s<br><strong>POSIX standardization:</strong> IEEE POSIX.2 (1992)</p><p>Shell <code>printf</code> did not exist in early Unix.</p><p>It was added when shell scripting became more serious and the community needed a precise, predictable formatter &#8212; something <code>echo</code> could never be.</p><p>POSIX essentially forced every shell to ship a compatible <code>printf</code> implementation.</p><div><hr></div><h3>3. <em>print</em> &#8212; invented by David Korn for the Korn shell (mid-1980s)</h3><p><strong>Origin</strong>: KornShell (ksh)<br><strong>Creator</strong>: David Korn, AT&amp;T Bell Labs<br><strong>First appearance</strong>: ksh88, released 1988</p><p><em>print</em> was created because:</p><ul><li><p><em>echo</em> was unreliable</p></li><li><p><em>printf</em> didn&#8217;t yet exist as a shell command</p></li><li><p>Korn wanted a consistent, user-friendly output builtin</p></li></ul><p>Later, zsh (1990, Paul Falstad) adopted and extended <em>print</em> because it fit their philosophy of improving shell ergonomics.</p><p></p><h2>When should I use <em>print</em> versus <em>printf</em> in the shell, and in which situations is it appropriate for an iOS developer to rely on <code>echo</code>?</h2><h3>1. <em>print</em> &#8212; use it only in zsh (interactive use)</h3><p><em>print</em> is a zsh/ksh-specific convenience command.</p><p>Use <em>print</em> when:</p><ul><li><p>you are typing commands interactively in zsh</p></li><li><p>you want cleaner, predictable behavior than <em>echo</em></p></li><li><p>you want features like <code>print -r</code> (raw), <code>print -f</code> (formatting), or automatic newline</p></li></ul><p>Do NOT use <code>print</code> in scripts unless the script is explicitly for zsh (<code>#!/bin/zsh</code>).</p><p>If the script must run everywhere &#8594; never touch <code>print</code>.</p><div><hr></div><h3>2. <code>printf</code> &#8212; use it in scripts (portable, predictable)</h3><p><code>printf</code> is the correct command when you want:</p><ul><li><p>reliability</p></li><li><p>cross-platform compatibility</p></li><li><p>consistent escaping</p></li><li><p>no random behavior with <code>-e</code>, <code>-n</code>, backslashes, or options</p></li><li><p>portable shell scripts (<code>#!/bin/sh</code>, <code>#!/bin/bash</code>, <code>#!/bin/zsh</code>, <code>#!/bin/dash</code>, etc.)</p></li></ul><p><code>printf</code> is guaranteed by POSIX.<br>It behaves the same everywhere.<br>It never surprises you.</p><p>Typical use:</p><pre><code><code>printf &#8220;Hello World\n&#8221;</code></code></pre><div><hr></div><h3>3. <code>echo</code> &#8212; use for quick and dirty output, interactive only</h3><p><code>echo</code> is fine for:</p><ul><li><p>quick interactive use</p></li><li><p>debugging while typing commands</p></li><li><p>humans reading output where precision doesn&#8217;t matter</p></li></ul><p>But it is NOT reliable in scripts, because:</p><ul><li><p>some <code>echo</code> interpret <code>\n</code></p></li><li><p>some don&#8217;t</p></li><li><p>some treat <code>-e</code> specially</p></li><li><p>some don&#8217;t</p></li><li><p>some print <code>-n</code> literally</p></li><li><p>some treat it as option</p></li><li><p>behavior differs between BSD, GNU, POSIX shells, and builtins</p></li></ul><p>Example of &#8220;fun&#8221; portability issues:</p><pre><code><code>echo &#8220;\n&#8221;     # may print one newline, two, or the characters &#8220;\&#8221;, &#8220;n&#8221;
echo -e &#8220;\n&#8221;  # may work, may not
echo -n hi    # may print &#8220;hi&#8221; or &#8220;-n hi&#8221;</code></code></pre><p>If you care about correctness &#8594; don&#8217;t use <code>echo</code>.</p><h2>Should an iOS developer use <code>echo</code>?</h2><p>Yes for interactive debugging, no for scripting.</p><p>As an iOS developer you are using the shell mostly for:</p><ul><li><p>printing messages in simple scripts</p></li><li><p>build scripts</p></li><li><p>CI scripts (Fastlane, GitHub Actions, Bitrise, Jenkins)</p></li><li><p>Xcode Run Script phases</p></li></ul><p>In these contexts, you should prefer <code>printf</code>, because:</p><ul><li><p>output must be predictable</p></li><li><p>logs must be stable</p></li><li><p>CI machines may run different shells</p></li><li><p>macOS (BSD), Linux (GNU), and Alpine (Busybox) all differ</p></li></ul><p><code>echo</code> is fine when:</p><pre><code><code>echo &#8220;building...&#8221;
echo &#8220;done&#8221;</code></code></pre><p>But for anything involving escaping, newlines, or control characters &#8594; use <code>printf</code>.</p><h2>Your simple rule (practical):</h2><h4>Interactive zsh (Terminal typing)</h4><ul><li><p>Use <code>print</code> or <code>echo</code></p></li><li><p>They&#8217;re fast, convenient, and safe enough</p></li></ul><h4>Scripts (shell, CI, build steps, automation)</h4><ul><li><p>Always use <code>printf</code></p></li><li><p>Never use <code>print</code></p></li><li><p>Avoid <code>echo</code> unless it&#8217;s trivial text</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Difference Between Procedural And Declarative Programming]]></title><description><![CDATA[Imagine you&#8217;re driving a car and you&#8217;re thirsty.]]></description><link>https://www.swiftwithblaze.com/p/difference-between-procedural-and</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/difference-between-procedural-and</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Tue, 18 Nov 2025 10:50:01 GMT</pubDate><enclosure url="https://api.substack.com/feed/podcast/179234440/2eba2508befbe39bfb5b0729ff4043a4.mp3" length="0" type="audio/mpeg"/><content:encoded><![CDATA[<p>Imagine you&#8217;re driving a car and you&#8217;re thirsty.</p><p>You ask your passenger: &#8216;Hey Max, take the bottle, open it, and put it in my right hand.&#8217;</p><p>That&#8217;s procedural programming.</p><p>But when you simply say: &#8216;I&#8217;m thirsty,&#8217; you expect the passenger to know what to do and handle it in the best way to satisfy your need.</p><p>That&#8217;s declarative programming.</p><p>UIKit and SwiftUI are perfect examples of these two styles.</p>]]></content:encoded></item><item><title><![CDATA[Xcode Quick Actions]]></title><description><![CDATA[Execute Xcode's menu items as command-line tools in Terminal]]></description><link>https://www.swiftwithblaze.com/p/xcode-quick-actions</link><guid isPermaLink="false">https://www.swiftwithblaze.com/p/xcode-quick-actions</guid><dc:creator><![CDATA[🅱🅻🅰🆉🅴]]></dc:creator><pubDate>Fri, 14 Nov 2025 17:53:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hYfn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>What exactly is Quick Actions in Xcode?</strong></h3><p>The Quick Actions panel, introduced in Xcode 15, is Apple&#8217;s new feature inspired by tools like Spotlight and Visual Studio Code&#8217;s Command Palette.<br>It centralizes access to Xcode menu items, Automator workflows, and Shortcuts app actions &#8212; all from one place, without ever leaving the editor.</p><p>Think of it as Xcode&#8217;s built-in command line, where you can search, discover, and execute actions instantly. It&#8217;s not just about running menu items &#8212; it&#8217;s a productivity hub that reveals what Xcode can do, and lets you trigger it all with a few keystrokes.</p><p>Quick Actions can also serve as a finder for keyboard shortcuts of menu items.</p><p>You can access it from the menu Editor &#8594; Quick Actions or with &#8963;&#8679;&#8984;A (Control&#8211;Shift&#8211;Command&#8211;A). Once you open it, search for an action by typing it&#8217;s name or just single letter to find the action or just to get ideas what is accessible. Xcode 26 contains more actions than Xcode 15 and 16, so it&#8217;s worth checking what&#8217;s new in each version.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hYfn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hYfn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 424w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 848w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 1272w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hYfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic" width="1456" height="856" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:856,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:109653,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://vectorterra.substack.com/i/178786956?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hYfn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 424w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 848w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 1272w, https://substackcdn.com/image/fetch/$s_!hYfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19cb8f37-dc63-40c6-91e6-a8cbf7fc75fa_2048x1204.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Xcode Quick Actions panel displaying the &#8216;Commit&#8230;&#8217; action and its keyboard shortcut on the right.</figcaption></figure></div><h3><strong>Wait &#8212; I saw my macOS Shortcuts App actions  there. Why?</strong></h3><p>Because <strong>Quick Actions</strong> are tightly integrated with the <strong>Shortcuts app</strong>.</p><p>You can create a shortcut in the Shortcuts App and have it appear directly in Xcode&#8217;s Quick Actions panel.</p><h3><strong>Does it work with Automator too?</strong></h3><p>Yes.</p><h3><strong>Can it run my own shell scripts or commands like xcodegen generate?</strong></h3><p>Yes &#8212; just wrap your script with an Automator workflow or Shortcuts App custom action.</p><h3><strong>What are your favourite Quick Actions commands?</strong></h3><p>Here are some of my favorite built-in<strong> </strong>Xcode&#8217;s Quick Actions:</p><ul><li><p>Discard changes in the current file</p></li><li><p>Discard all changes in the project </p></li><li><p>Clean build folder</p></li><li><p>Clear consol</p></li><li><p>Find and replace in the current file</p></li><li><p>Commit</p></li></ul><p>And my custom ones:</p><ul><li><p>Execute <em>xcodegen generate</em> command</p></li><li><p>Switch between my project&#8217;s white-labels environments</p><p></p></li></ul><h3>&#128236; Coming Next (for subscribers):</h3><p>&#8220;How to Build a Shortcut App, Custom Shortcut for Xcode&#8221;</p><p>Learn how to turn your everyday build scripts into one-click actions inside Xcode.<br><strong>Subscribe now</strong> to get the tutorial as soon as it&#8217;s published.</p>]]></content:encoded></item></channel></rss>