<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/josip-cavar/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 03 Apr 2026 12:58:20 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>19276581https://infinum.com/uploads/2026/03/Snapshot-testing-audio-dsp-hero.webp</url>
				</image>
				<title>Snapshot Testing for Audio DSP</title>
				<link>https://infinum.com/blog/snapshot-testing-for-audio-dsp/</link>
				<pubDate>Mon, 09 Mar 2026 09:52:59 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19276581</guid>
				<description>
					<![CDATA[<p>Learn about AudioSnapshotTesting, a new open-source library developed in collaboration with AudioKit, designed to bring the benefits of snapshot testing to audio development.</p>
<p>The post <a href="https://infinum.com/blog/snapshot-testing-for-audio-dsp/">Snapshot Testing for Audio DSP</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-231"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-93">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-94'
	>
	Snapshot Testing has become a commonly adopted technique for testing user interfaces. The popularity stems from its ability to address the unique challenges of UI testing and the simplicity of setup.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-97'
	>
	Despite its success in UI testing, snapshot testing hasn’t gained much traction in other areas of software development. This lack of adoption is unfortunate, as many challenges in software development mirror those encountered in UI testing: hard-to-define outputs, complex interactions, and the need for reliable, repeatable tests.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-100'
	>
	This is especially relevant in the age of AI, where a feedback loop is crucial for autonomous agentic development.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-103'
	>
	But snapshot testing can be extended beyond UI and applied effectively to audio development. Enter AudioSnapshotTesting, a library developed in collaboration with AudioKit, designed to simplify and streamline the testing of audio processing workflows.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-109"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-105">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-106'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-107'
	>
	<em>There is no greater impediment to the advancement of knowledge than the ambiguity of words.</em></p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-108'
	>
	<em>Thomas Reid</em></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-110">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-111'
	>
	The idea of snapshot testing was popularised in the iOS community by Facebook’s <a href="https://github.com/facebookarchive/ios-snapshot-test-case">FBSnapshotTestCase</a>, later renamed and maintained by Uber as <a href="https://github.com/uber/ios-snapshot-test-case">iOSSnapshotTestCase</a>. The API of those libraries was constrained to UI testing. Later on, a “delightful” Swift <a href="https://github.com/pointfreeco/swift-snapshot-testing">Snapshot testing library</a> has gained popularity. While swift-snapshot-testing made a significant step in generalising the idea of snapshot testing &#8211; by providing strategies to <a href="https://github.com/pointfreeco/swift-snapshot-testing?tab=readme-ov-file#snapshot-anything">“Snapshot Anything”</a> &#8211; in practice, companies <a href="https://github.com/MobileNativeFoundation/discussions/discussions/6#discussioncomment-427538">mostly use it for UI testing</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-113">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-114'
	>
	Snapshot Testing, Golden Master Testing, Characterization Testing, Approval Testing and Reference Testing all describe the same fundamental idea &#8211; verifying that software behaviour remains consistent over time. Unfortunately, terminological fragmentation creates artificial barriers, leading to missed opportunities.<br />
To explore Snapshot Testing outside of the UI domain, we will work on a simple metronome app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-116">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-117'
	>
	Testing Metronome</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-119">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-120'
	>
	Building a metronome seems straightforward: generate periodic audio clicks at a specified tempo?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-122">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-123'
	>
	However, when we start implementing one, questions arise quickly:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-125">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-126'
	>
	<li>How do we verify that the timing is accurate and doesn&#8217;t drift over time?</li><li>How do we ensure your audio processing doesn&#8217;t introduce artifacts?</li><li> How do we catch regressions when refactoring?</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-128">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-129'
	>
	The traditional approach is tedious: build the app, run it and listen carefully. Maybe export audio and inspect it in a third-party tool. Repeat for every change.<br />
<br />
Snapshot testing offers a different workflow. Here&#8217;s a simple test for our metronome&#8217;s audio output:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">record:</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">, 
</span></span><span class="line"><span class="token">        </span><span class="token">strategy:</span><span class="token"> .</span><span class="token">waveform(</span><span class="token">width:</span><span class="token"> </span><span class="token" style="color: #005cc5;">3000</span><span class="token">, </span><span class="token">height:</span><span class="token"> </span><span class="token" style="color: #005cc5;">800</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">@MainActor</span><span class="token">
</span></span><span class="line"><span class="token">func testMetronomeOutput</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> metronome </span><span class="token" style="color: #d73a49;">= Met</span><span class="token">ronome(</span><span class="token">bpm:</span><span class="token"> </span><span class="token" style="color: #005cc5;">120</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> metronome.</span><span class="token">render(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">of:</span><span class="token"> buffer</span><span class="token">, 
</span></span><span class="line"><span class="token">        </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">metronome-120bpm</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-133">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-134'
	>
	Running this test with <code>record: true</code> saves the audio buffer to disk as a lossless ALAC-encoded file. The ALAC format produces significantly smaller files than WAV while maintaining audio fidelity. Additionally, while in recording mode, the library generates a waveform visualization that allows us to iterate on our metronome implementation and see changes in the generated image.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-136">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-137'
	>
	Once we have a reference we are confident in, we switch to <code>record: false</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-139">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-140'
	>
	Now the test compares the current output against that reference audio file, failing if anything changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-142">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-143'
	>
	This workflow transforms audio development. Instead of rebuilding and running our app dozens of times, we run our test suite. Each test runs quickly and provides the iterative feedback we (or AI agent) need to implement our audio features.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-145">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-146'
	>
	The real power emerges when refactoring. Want to optimize your audio rendering or change your DSP algorithm? The expected output is now covered by tests. If the visual output remains identical, we haven&#8217;t broken anything. If it changes, we can immediately see what changed and decide if it&#8217;s intended or a bug.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-148">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-149'
	>
	A picture truly is worth a thousand tests</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-151">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-152'
	>
	AudioSnapshotTesting Library</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-154">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-155'
	>
	AudioSnapshotTesting is designed to work seamlessly with Swift Testing framework, providing specialized support for snapshotting AVAudioPCMBuffer’s with various visualization strategies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-159"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-157">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-158'
	>
	Waveform: Time-Domain Visualization</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-162"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-160">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-161'
	>
	The waveform strategy provides the familiar amplitude-over-time view. It&#8217;s perfect for spotting timing issues, clipping, unexpected silence, or amplitude problems:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">strategy:</span><span class="token"> .</span><span class="token">waveform(</span><span class="token">width:</span><span class="token"> </span><span class="token" style="color: #005cc5;">3000</span><span class="token">, </span><span class="token">height:</span><span class="token"> </span><span class="token" style="color: #005cc5;">800</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">func testSineWave</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">of:</span><span class="token"> buffer</span><span class="token">, </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">sine</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-165"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-166">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2026/03/image-92-1-1400x373.jpg				media='(max-width: 699px)'
				type=image/jpeg								height="373"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2026/03/image-92-1.jpg"
					class="image__img block-media__image-img"
					alt=""
										height="533"
															width="1999"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-169'
	>
	Want to compare two audio buffers visually? The waveform strategy automatically overlays multiple buffers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">strategy:</span><span class="token"> .</span><span class="token">waveform(</span><span class="token">width:</span><span class="token"> </span><span class="token" style="color: #005cc5;">3000</span><span class="token">, </span><span class="token">height:</span><span class="token"> </span><span class="token" style="color: #005cc5;">800</span><span class="token">)</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">func testComparison</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">of:</span><span class="token"> </span><span class="token">(</span><span class="token">sineBuffer</span><span class="token">, </span><span class="token">squareBuffer</span><span class="token">)</span><span class="token">, 
</span></span><span class="line"><span class="token">        </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">sine-over-square</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-173"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-174">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2026/03/image-93-1-1400x350.jpg				media='(max-width: 699px)'
				type=image/jpeg								height="350"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2026/03/image-93-1.jpg"
					class="image__img block-media__image-img"
					alt=""
										height="500"
															width="1999"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-176">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-177'
	>
	This renders the first buffer in red, the second in green, making differences immediately obvious.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-179">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-180'
	>
	Spectrum: Frequency-Domain Visualization</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-182">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-183'
	>
	While waveforms show what happens over time, spectrum analysis reveals frequency content. This is invaluable when testing filters, equalizers, or any DSP that operates in the frequency domain:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">strategy:</span><span class="token"> .</span><span class="token">spectrum(</span><span class="token">width:</span><span class="token"> </span><span class="token" style="color: #005cc5;">1500</span><span class="token">, </span><span class="token">height:</span><span class="token"> </span><span class="token" style="color: #005cc5;">400</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">func testWhiteNoise</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">of:</span><span class="token"> buffer</span><span class="token">, </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">white-noise</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-187"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-188">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2026/03/image-94-1-1400x373.webp				media='(max-width: 699px)'
				type=image/webp								height="373"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2026/03/image-94-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="400"
															width="1500"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-190">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-191'
	>
	Spectrogram: Time-Frequency Representation</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-193">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-194'
	>
	The spectrogram strategy combines time and frequency analysis, showing how spectral content evolves:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">strategy:</span><span class="token"> .</span><span class="token">spectrogram(</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">hopSize:</span><span class="token"> </span><span class="token" style="color: #005cc5;">4096</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">frequencyCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">2048</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">amplitudeScale:</span><span class="token"> .</span><span class="token">logarithmic(</span><span class="token">range:</span><span class="token"> </span><span class="token" style="color: #005cc5;">120</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">func testChirp</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">of:</span><span class="token"> buffer</span><span class="token">, </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">chirp</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-199'
	>
	Spectrograms are particularly useful for analyzing complex signals, transient events, or any audio where frequency content changes over time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-201">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-202'
	>
	Streamlined Workflow</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-206"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-204">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-205'
	>
	For an even smoother development experience, the library offers the <code>autoOpen</code> parameter. When enabled during recording, it automatically opens visualizations in Preview (on macOS), eliminating the need to manually locate and open files:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@Test</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">audioSnapshot(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">record:</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">,
</span></span><span class="line"><span class="token">        </span><span class="token">strategy:</span><span class="token"> .</span><span class="token">waveform(</span><span class="token">width:</span><span class="token"> </span><span class="token" style="color: #005cc5;">3000</span><span class="token">, </span><span class="token">height:</span><span class="token"> </span><span class="token" style="color: #005cc5;">800</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">        </span><span class="token">autoOpen:</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">func testWithAutoOpen</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">await</span><span class="token"> </span><span class="token">assertAudioSnapshot(</span><span class="token">of:</span><span class="token"> buffer</span><span class="token">, </span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">test</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-210'
	>
	This is particularly useful when iterating on DSP algorithms—run the test, and the waveform appears instantly for visual verification.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-214"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-212">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-213'
	>
	Why a Standalone Library?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-217"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-215">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-216'
	>
	While swift-snapshot-testing is an excellent library, we wanted a specialised approach. Audio is about samples—raw numeric data representing sound waves. In AudioSnapshotTesting, sample-by-sample comparison is the source of truth. Visualizations are secondary, generated only on failure or during recording as debugging aids. The audio files are always preserved, allowing inspection in any audio editor.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-220"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-218">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-219'
	>
	Try it out</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-221">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-222'
	>
	In this article, we&#8217;ve shown how snapshot testing serves dual purposes: providing rapid feedback during development and acting as a comprehensive regression suite. The techniques we&#8217;ve explored—waveform visualization, spectrum analysis, and spectrogram generation—aren&#8217;t new, but integrating them into your test suite transforms them from manual verification tools into automated quality gates.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-224">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-225'
	>
	With audio files always preserved for detailed inspection, configurable bit depth for balancing file size and precision, and workflow enhancements like auto-opening, AudioSnapshotTesting makes audio testing both powerful and practical.<br />
<br />
As long-term AudioKit users, we&#8217;ve benefited immensely from the community&#8217;s contributions to audio development on Apple platforms. We&#8217;re thrilled to give back with this tool and hope it helps others build more reliable audio software.<br />
<br />
The library is open source and available on GitHub, and we welcome contributions from the community:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-227">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-228'
	>
	<li><a href="https://github.com/AudioKit/AudioSnapshotTesting">AudioSnapshotTesting Github Repository</a></li><li><a href="https://github.com/jcavar/Metronome">Metronome implementation guided by snapshot testing</a></li></ul></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/snapshot-testing-for-audio-dsp/">Snapshot Testing for Audio DSP</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19264889https://infinum.com/uploads/2025/03/Swift-Sanitizer-min.webp</url>
				</image>
				<title>Time to Get Real – Introducing RealtimeSanitizer for Swift</title>
				<link>https://infinum.com/blog/realtimesanitizer-swift/</link>
				<pubDate>Wed, 26 Mar 2025 12:21:43 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19264889</guid>
				<description>
					<![CDATA[<p>Meet RTSanStandaloneSwift, our Swift wrapper around RealtimeSanitizer, helping you write predictable and safe real-time code.</p>
<p>The post <a href="https://infinum.com/blog/realtimesanitizer-swift/">Time to Get Real – Introducing RealtimeSanitizer for Swift</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-353"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-232">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-233">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-234'
	>
	<strong>Swift is modern, powerful, and versatile – but real-time coding can get tricky. Meet RTSanStandaloneSwift, our new Swift wrapper around LLVM&#8217;s RealtimeSanitizer, designed to help you write safe and effective</strong> <strong>real-time code.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-236">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-237'
	>
	Developing robust real-time systems brings a unique set of challenges. Real-time code must not only be logically correct but also execute within strict time constraints. Failing to meet these deadlines can lead to system failures, which means that thorough debugging and validation of real-time safety are absolutely essential. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-239">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-240'
	>
	To simplify this intricate process, LLVM 20 introduces <a href="https://clang.llvm.org/docs/RealtimeSanitizer.html" target="_blank" rel="noreferrer noopener">RealtimeSanitizer</a> – a runtime analysis tool designed to detect operations that violate real-time constraints. While RealtimeSanitizer is initially available in the Clang compiler, its foundations are built within LLVM, allowing for broader language adoption. This has already been demonstrated with the <a href="https://steck.tech/posts/rtsan-in-rust/" target="_blank" rel="noreferrer noopener">Rust wrapper</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-242">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-243'
	>
	Over the past several months, we’ve collaborated with Chris Apple and David Trevelyan, creators of RealtimeSanitizer, to bring this powerful capability to Swift. Today, we’re excited to introduce <a href="https://github.com/realtime-sanitizer/RTSanStandaloneSwift" target="_blank" rel="noreferrer noopener">RTSanStandaloneSwift</a> – a Swift wrapper around RealtimeSanitizer that will enable Swift developers to build and maintain real-time applications more easily.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-247"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-245">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-246'
	>
	Real-time programming in Swift</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-250"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-248">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-249'
	>
	C and C++ have long dominated real-time development due to their predictable performance and low-level control.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-253"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-251">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-252'
	>
	Swift, on the other hand, is a modern, fast, and memory-safe language that is interoperable with C++ and has cross-platform support, making it an attractive option for a wide range of applications.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-258"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-254">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-255'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-256'
	>
	Swift’s project goal is to create the best available language for uses ranging from systems programming to mobile and desktop apps, scaling up to highly distributed cloud services.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-257'
	>
	<a href="http://Swift.org">SWIFT.ORG</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-259">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-260'
	>
	While Swift has already demonstrated its <a href="https://fosdem.org/2025/schedule/event/fosdem-2025-5284-building-a-ferrofluidic-music-visualizer-with-embedded-swift/" target="_blank" rel="noreferrer noopener">capability as a real-time programming language</a>, its high-level nature can make it challenging to reason about strict execution time requirements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-264"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-262">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-263'
	>
	Let’s examine a simple Swift implementation of an audio processor:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class AudioProcessor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> gain </span><span class="token" style="color: #d73a49;">= 1
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func process</span><span class="token">(</span><span class="token">buffer</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">Float</span><span class="token">]</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">for</span><span class="token"> i </span><span class="token" style="color: #d73a49;">in</span><span class="token"> 0.</span><span class="token" style="color: #d73a49;">.&lt;buffer.c</span><span class="token" style="color: #005cc5;">ount</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            buffer</span><span class="token">[</span><span class="token">i</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">= buffer[i] *</span><span class="token" style="color: #d73a49;"> gain
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-267">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-268'
	>
	Although this example resembles a straightforward C-style loop, it contains several potential pitfalls for real-time performance:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-270">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-271'
	>
	<li>Exclusivity checking – which may allocate memory</li><li>Protocol lookup and metadata instantiation  – which may allocate memory or introduce locks</li><li>Copy-on-write behaviour on the array – which may allocate memory</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-275"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-273">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-274'
	>
	Having a tool that can help us detect these issues would be invaluable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-278"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-276">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-277'
	>
	How RealtimeSanitizer works</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-281"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-279">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-280'
	>
	Similar to AddressSanitizer, RealtimeSanitizer works by intercepting “interesting” functions – in this context, those that could violate realtime-safety guarantees. Typically, these functions involve locks, memory allocation or I/O operations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-284"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-282">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-283'
	>
	For a full list of intercepted functions, check out the <a href="https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp" target="_blank" rel="noreferrer noopener">implementation</a> details.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-287"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-285">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-286'
	>
	In C++ (Clang), real-time sanitizer is <strong>activated</strong> by annotating a function with the <code>[[clang:nonblocking]]</code> attribute. When such a function invokes a real-time unsafe operation, the sanitizer aborts the process and provides a stack trace for debugging purposes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-290"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-288">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-289'
	>
	RealtimeSanitizer also includes <a href="https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/rtsan/rtsan.h" target="_blank" rel="noreferrer noopener">a suite of C functions</a> that give developers fine-grained control over its behaviour.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-293"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-291">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-292'
	>
	RealtimeSanitizer in Swift</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-296"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-294">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-295'
	>
	Leveraging Swift’s interoperability with C, we can invoke RealtimeSanitizer’s C bindings and create a more convenient Swift API.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-299"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-297">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-298'
	>
	RTSanStandaloneSwift is a lightweight implementation that introduces a user-friendly Swift macro for annotating functions that are subject to real-time constraints.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-300">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-301'
	>
	Similar to the <code>[[clang:nonblocking]]</code><em> </em>attribute in C++, RTSanStandaloneSwift provides the <code>@NonBlocking</code><em> </em>macro in Swift.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-305"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-303">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-304'
	>
	For example, we can annotate our earlier <code>process</code> function like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@NonBlocking</span><span class="token">
</span></span><span class="line"><span class="token">func process</span><span class="token">(</span><span class="token">buffer</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">Float</span><span class="token">]</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">for</span><span class="token"> i i</span><span class="token" style="color: #d73a49;">n</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #d73a49;">..&lt;buff</span><span class="token">er.</span><span class="token" style="color: #005cc5;">count</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        buffer</span><span class="token">[</span><span class="token">i</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">= buffer[</span><span class="token">i</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">* gain
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-308">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-309'
	>
	Now, when we run this code, RealtimeSanitizer will automatically detect and report any real-time violations:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">==</span><span class="token" style="color: #005cc5;">11917</span><span class="token" style="color: #d73a49;">==</span><span class="token" style="color: #005cc5;">ERROR</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">RealtimeSanitizer</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">unsafe</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">library</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">call</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">Intercepted</span><span class="token"> </span><span class="token" style="color: #005cc5;">call</span><span class="token"> </span><span class="token" style="color: #005cc5;">to</span><span class="token"> </span><span class="token" style="color: #d73a49;">real</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">time</span><span class="token"> </span><span class="token" style="color: #005cc5;">unsafe</span><span class="token"> </span><span class="token" style="color: #d73a49;">function</span><span class="token"> </span><span class="token" style="color: #032f62;">`</span><span class="token" style="color: #032f62;">os_unfair_lock_lock</span><span class="token" style="color: #032f62;">`</span><span class="token"> </span><span class="token" style="color: #005cc5;">in</span><span class="token"> </span><span class="token" style="color: #d73a49;">real</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">time</span><span class="token"> </span><span class="token" style="color: #005cc5;">context</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">0 in os_unfair_lock_lock rtsan_interceptors_posix.cpp:592</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">1 in _swift_allocObject_+0x1b4 (libswiftCore.dylib:arm64)</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">2 in _ArrayBuffer._consumeAndCreateNew(bufferIsUnique:minimumCapacity:)</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">3 0x00010061f5a4 in AudioProcessor_main main.swift:26</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">SUMMARY</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">RealtimeSanitizer</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">unsafe</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">library</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #6f42c1;">call</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">libswiftCore</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">dylib</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">in</span><span class="token"> </span><span class="token" style="color: #005cc5;">_swift_allocObject</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-313">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-314'
	>
	In this particular example, RealtimeSanitizer detected a lock within the Swift runtime triggered by the copy-on-write behavior during array mutation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-316">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-317'
	>
	RTSanStandaloneSwift roadmap</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-319">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-320'
	>
	We consider the current version of RTSanStandaloneSwift a <strong>transitional solution, </strong>and plan further improvements in the next stages:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-324"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-322">
	<h3	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-323'
	>
	Stage 1</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-325">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-326'
	>
	Currently, RTSanStandaloneSwift ships with a prebuilt version of the RealtimeSanitizer dynamic library. While this approach is functional, it is not ideal in the long term.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-330"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-328">
	<h3	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-329'
	>
	Stage 2</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-333"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-331">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-332'
	>
	<a href="https://github.com/llvm/llvm-project/releases/tag/llvmorg-20.1.0" target="_blank" rel="noreferrer noopener">LLVM 20 is officially out</a>, so when the first Swift nightly toolchains targeting LLVM 20 become available, we plan to phase out the prebuilt versions of the RealtimeSanitizer dynamic library. At that point, RTSanStandaloneSwift will rely entirely on the RealtimeSanitizer functionality provided directly in the toolchain.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-336"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-334">
	<h2	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-335'
	>
	Stage 3</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-339"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-337">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-338'
	>
	Ultimately, our goal is to make a pitch for adding the attributes and the sanitizer as first-class features natively integrated into Swift.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-342"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-340">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-341'
	>
	Get involved and try it out</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-345"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-343">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-344'
	>
	RTSanStandaloneSwift marks a significant milestone for real-time programming in Swift, enabling Swift developers to more easily write predictable and safe real-time code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-348"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-346">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-347'
	>
	We’d love you to try it out, share your feedback and contribute to its ongoing development.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-351"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-349">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-350'
	>
	<li><strong>Github</strong>: <a href="https://github.com/realtime-sanitizer/RTSanStandaloneSwift">RTSanStandaloneSwift Repository</a> </li><li><strong>Official documentation</strong>: <a href="https://clang.llvm.org/docs/RealtimeSanitizer.html">RealtimeSanitizer Docs</a></li><li><strong>Swift Package Index</strong>: <a href="https://swiftpackageindex.com/realtime-sanitizer/RTSanStandaloneSwift">RTSanStandaloneSwift Package</a></li><li><strong>Discord</strong>: <a href="https://discord.gg/DZqjbmSZzZ">RealtimeSanitizer (RTSan)</a></li><li><strong>Email</strong>: <a href="mailto:realtime.sanitizer@gmail.com" target="_blank" rel="noreferrer noopener">realtime.sanitizer@gmail.com</a></li><li><strong>Swift Forums</strong>: <a href="https://forums.swift.org/t/introducing-realtimesanitizer-for-swift" target="_blank" rel="noreferrer noopener">RealtimeSanitizer for Swift thread</a><br />
</li></ul></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/realtimesanitizer-swift/">Time to Get Real – Introducing RealtimeSanitizer for Swift</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19258520https://infinum.com/uploads/2024/10/Swift-Ownership_-Non-copyable-types-hero.webp</url>
				</image>
				<title>Meet Non-Copyable Types – Swift’s Secret Performance Boost</title>
				<link>https://infinum.com/blog/swift-non-copyable-types/</link>
				<pubDate>Mon, 21 Oct 2024 14:49:48 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19258520</guid>
				<description>
					<![CDATA[<p>Discover the power of non-copyable types in Swift. Boost performance, ensure unique ownership, and enhance safety for resource-heavy code.</p>
<p>The post <a href="https://infinum.com/blog/swift-non-copyable-types/">Meet Non-Copyable Types – Swift’s Secret Performance Boost</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-594"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-354">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-357"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-355">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-356'
	>
	<strong>We explore non-copyable types, Swift’s game-changing feature that boosts performance and safety for resource-heavy code. Find out how non-copyable types work, why they matter, and how they can optimize your workflow for critical use cases.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-360"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-358">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-359'
	>
	Version 5.9 marked a big step in Swift’s evolution toward a high-performance and ergonomic programming language. Along with new ownership modifiers, the release introduced non-copyable types – instances that always maintain unique ownership, ensuring they cannot be copied. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-363"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-361">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-362'
	>
	Although we likely won’t see non-copyable types widely used in common codebases, they enable important features like Swift-native Atomics and Locks. Non-copyable types also offer significant benefits in terms of safety and performance, but their somewhat esoteric syntax and niche use cases can make them difficult to grasp.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-366"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-364">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-365'
	>
	In this article, we’ll take a closer look at what non-copyable types bring to the table, break down their complexities, and explain how they fit into Swift’s evolving ecosystem. Even if you don’t expect to use non-copyable types regularly, learning how they work will give you a better understanding of Swift’s growing capabilities.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-369"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-367">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-368'
	>
	Copyability in Swift</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-372"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-370">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-371'
	>
	The concept of copyability represents one of the main distinguishing traits between value and reference types in Swift. This distinction is highlighted early in <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language" target="_blank" rel="noreferrer noopener">The Swift Programming Language</a> book:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-375"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-373">
	<p	class='typography typography--size-18-text-roman js-typography block-paragraph__paragraph'
	data-id='es-374'
	>
	<em>A </em><strong><em>value type</em></strong><em> is a type whose value </em><strong><em>is copied</em></strong><em> when it’s assigned to a</em> <em>variable or constant, or when it’s passed to a function. </em><em>(<a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures#Structures-and-Enumerations-Are-Value-Types" target="_blank" rel="noreferrer noopener">source</a>)</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-378"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-376">
	<p	class='typography typography--size-18-text-roman js-typography block-paragraph__paragraph'
	data-id='es-377'
	>
	<em>Unlike value types, </em><strong><em>reference types</em></strong><em> are </em><strong><em>not copied</em></strong><em> when they’re assigned to a variable or constant, or when they’re passed to a function. (<a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures#Classes-Are-Reference-Types" target="_blank" rel="noreferrer noopener">source</a>)</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-381"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-379">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-380'
	>
	This distinction often plays a crucial role in choosing the right construct for solving a particular problem. However, the introduction of non-copyable types gives us a new perspective on copyability.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-384"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-382">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-383'
	>
	Consider the following code sample:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-386"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">var x:</span><span class="token"> Test</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Test(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> y </span><span class="token" style="color: #d73a49;">=</span><span class="token"> x
</span></span><span class="line"><span class="token">x </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-389"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-387">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-388'
	>
	In this example, we deliberately avoid specifying what <code>Test</code><em> </em>is. However, regardless of its exact definition, the compiler must guarantee that the variable <code>y</code><em> </em>remains valid even after <code>x</code><em> </em>is set to <code>nil</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-392"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-390">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-391'
	>
	How can a compiler do that? Typically, it handles it through one of two mechanisms:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-396"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-393">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-394'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-395'
	>
	If <code>Test</code> is a simple (<a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0426-bitwise-copyable.md" target="_blank" rel="noreferrer noopener">bitwise-copyable</a>) <code>struct</code>, its bytes are copied to a separate memory location.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-400"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-397">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-398'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-399'
	>
	If <code>Test</code> is a <code>class</code>, the instance is retained through reference counting.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-401">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-402'
	>
	These two approaches demonstrate different notions of copyability, which have been explicitly formalized with the introduction of the <code>Copyable</code> protocol. Both mechanisms allow programmers to pass values and references around safely and efficiently, while the compiler can use one of these operations to ensure safe code execution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-406"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-404">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-405'
	>
	The introduction of the <code>Copyable</code> <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md#marker-protocols">marker</a> <a href="https://github.com/swiftlang/swift/blob/swift-5.10-RELEASE/stdlib/public/core/Misc.swift#L158-L163" target="_blank" rel="noreferrer noopener">protocol</a> formalizes an already implicit concept. All existing types in Swift <strong>implicitly </strong>conform to it, so this change adds no additional burden for developers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-409"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-407">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-408'
	>
	<strong>Implicit</strong> conformance is not a new idea in Swift. We’ve already seen implicit <code>Sendable</code> <a href="https://developer.apple.com/documentation/swift/sendable#Sendable-Structures-and-Enumerations" target="_blank" rel="noreferrer noopener">conformance</a>, and there is also a <a href="https://forums.swift.org/t/pitch-non-escapable-types-and-lifetime-dependency/69865" target="_blank" rel="noreferrer noopener">proposal</a> for adding default conformance to the <code>Escapable</code> protocol.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-412"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-410">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-411'
	>
	Why we need non-copyable types</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-415"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-413">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-414'
	>
	For over a decade, Swift’s ever-present copyability has served us well. But as Swift evolves into a true general-purpose programming language, and especially with growing ambitions in the <a href="https://github.com/swiftlang/swift-evolution/blob/main/visions/embedded-swift.md" target="_blank" rel="noreferrer noopener">embedded systems space</a>, new demands for safety and performance have emerged. These requirements bring forth new code idioms that call for advanced features like non-copyable types, designed specifically for <strong>performance-critical</strong> and <strong>correctness-sensitive</strong> code. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-418"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-416">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-417'
	>
	For example, some real-world scenarios where performance and correctness are critical include:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-421"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-419">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-420'
	>
	<li>Database connections</li><li>Database cursors</li><li>Transactions</li><li>Network connections</li><li>Audio buffers</li><li>Wrapping C libraries&nbsp;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-424"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-422">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-423'
	>
	In these cases, specific state transitions can invalidate instances, making ownership controls essential for ensuring safe and reliable code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-427"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-425">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-426'
	>
	Let’s explore these two key aspects in more detail.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-430"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-428">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-429'
	>
	Optimizing performance</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-433"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-431">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-432'
	>
	In a previous article on <a href="https://infinum.com/blog/swift-ownership/" target="_blank" rel="noreferrer noopener">ownership in Swift</a>, we explored the concept of <code>borrowing</code> and <code>consuming</code> parameter modifiers, both aimed at optimizing performance-critical code. Non-copyable types take this a step further by providing even stronger guarantees, requiring us to explicitly define ownership conventions when passing an instance of a non-copyable type.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-436"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-434">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-435'
	>
	There are two main sources of performance improvements when using non-copyable types:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-439"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-437">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-438'
	>
	<li><strong>Inline storage</strong>: non-copyable types are stored inline with the containing type, which eliminates the need for separate memory allocations</li><li><strong>No reference counting</strong>: since non-copyable types don’t rely on reference counting, the overhead associated with tracking references is completely removed </li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-442"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-440">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-441'
	>
	Consider the following code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-444"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func test</span><span class="token">(</span><span class="token">_ numbers</span><span class="token">: </span><span class="token">[</span><span class="token" style="color: #005cc5;">Int</span><span class="token">]</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> numbers </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">1</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">10000000</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #005cc5;">map</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">test(</span><span class="token">numbers</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-447"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-445">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-446'
	>
	Since <code>Array</code><em> </em>is a copy-on-write (CoW) data type and no mutations are happening, the large array won’t be copied – this is an important optimization for most common use cases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-450"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-448">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-449'
	>
	However, there’s a hidden performance cost: reference counting. As a CoW data type, the underlying array buffer must be reference counted so that Swift’s runtime knows when an actual copy is necessary.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-453"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-451">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-452'
	>
	While a single retain might seem negligible, when this code is invoked in a loop, the performance impact becomes more significant – a point we’ll explore further in the case study.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-456"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-454">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-455'
	>
	Ideally, we’d have a <code>NonCopyableArray</code><em> </em>type that would allow the compiler to reject code that might trigger expensive copies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-459"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-457">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-458'
	>
	Maximizing correctness</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-462"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-460">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-461'
	>
	Non-copyable types also improve code correctness by enforcing unique ownership and preventing invalid states. For example, consider the following code (the ~ indicates <strong>non</strong>, which we’ll explore in more detail later):</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-464"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct SingleUseToken</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">let token:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">init(tok</span><span class="token">en</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">token</span><span class="token"> </span><span class="token" style="color: #d73a49;">= token
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> </span><span class="token">func use</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> token
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func run</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> token </span><span class="token" style="color: #d73a49;">= Sin</span><span class="token">gleUseToken(</span><span class="token">token:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1234</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> 
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; `toke</span><span class="token">n` consumed more then once
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-467"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-465">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-466'
	>
	By declaring <code>SingleUseToken</code> as <code>~Copyable</code>, we ensure that the compiler rejects any invalid code where a token is consumed more than once.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-470"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-468">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-469'
	>
	This explicit state management requires unique ownership, and the compiler enforces the following:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-472"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-20-text js-typography block-highlighted-text__typography'
	data-id='es-471'
	>
	<strong>There can’t be multiple variables pointing to the same value.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-475"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-473">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-474'
	>
	For example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-477"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func multipleVariables</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> token </span><span class="token" style="color: #d73a49;">= Sin</span><span class="token">gleUseToken(</span><span class="token">token:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1234</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> tokenReference </span><span class="token" style="color: #d73a49;">= tok</span><span class="token">en
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; `toke</span><span class="token">n` consumed more then once
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-480"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-478">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-479'
	>
	The message above is somewhat confusing, but the <code>token</code> is not valid anymore when we assign (move) it to <code>tokenReference</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-483"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-481">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-482'
	>
	To summarize, non-copyable types represent a new tool in the Swift type system:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-486"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-485>
	
<div
	class="wrapper"
	data-id="es-484"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table is-style-regular" style="font-size:20px"><table><tbody><tr><td></td><td class="has-text-align-center" data-align="center">Unique resource</td><td class="has-text-align-center" data-align="center">Unique ownership</td><td class="has-text-align-center" data-align="center">Inline storage</td></tr><tr><td><code>struct</code>, <code>enum</code></td><td class="has-text-align-center" data-align="center"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr><tr><td><code>class</code>, <code>actor</code></td><td class="has-text-align-center" data-align="center"><br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr><tr><td><code>~Copyable</code></td><td class="has-text-align-center" data-align="center"><br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td class="has-text-align-center" data-align="center"><br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-489"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-487">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-488'
	>
	The syntax of non-copyable types</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-492"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-490">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-491'
	>
	Swift’s esoteric choice of syntax for non-copyable types has sparked considerable debate within the <a href="https://forums.swift.org/t/second-review-se-0390-noncopyable-structs-and-enums/63866" target="_blank" rel="noreferrer noopener">Swift community</a>, and it’s worth understanding the rationale behind it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-495"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-493">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-494'
	>
	The naming of this feature is somewhat unfortunate and has also caused some confusion, especially when used in Swift’s generics system. The main challenge was to establish a syntax that clearly communicates the <strong>suppression of default Copyable conformance</strong><strong>.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-498"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-496">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-497'
	>
	The <a href="https://forums.swift.org/t/pitch-noncopyable-or-move-only-structs-and-enums/61903" target="_blank" rel="noreferrer noopener">initial pitch</a> for this feature proposed the following syntax:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-500"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@noncopyable</span><span class="token">
</span></span><span class="line"><span class="token">struct Test</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-503"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-501">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-502'
	>
	However, this approach didn’t integrate well with Swift’s generics system, so the language designers adopted a different method, using a protocol constraint instead.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-506"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-504">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-505'
	>
	Typically, protocols in Swift describe functionality that adds behavior to types. In the case of non-copyable types, the situation is reversed – functionality is <strong>removed </strong>from the type. Therefore, Swift needed a syntax that allows a type to <strong>suppress </strong>the default<strong> </strong><code>Copyable</code> conformance.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-509"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-507">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-508'
	>
	Swift’s ~ operator is not generally applicable and only works on specifically chosen protocols. Nevertheless, it is a more flexible and powerful tool because it allows Swift to suppress other conformances in the future (e.g. <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0426-bitwise-copyable.md#suppressing-inferred-conformance" target="_blank" rel="noreferrer noopener"><code>BitwiseCopyable</code></a>).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-512"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-510">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-511'
	>
	Interestingly, Swift is not alone in adopting this approach. For example, <a href="https://doc.rust-lang.org/std/marker/trait.Sized.html" target="_blank" rel="noreferrer noopener">Rust uses the ? operator</a> for a very similar purpose.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-515"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-513">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-514'
	>
	Ownership modifiers</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-518"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-516">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-517'
	>
	New ownership modifiers are a key requirement for the implementation of non-copyable types. While for regular types these modifiers serve as optional guardrails, they are mandatory for non-copyable types because these types enforce <strong>unique</strong> ownership. This means developers must be explicit when passing them around, clearly defining how ownership rules are transferred or borrowed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-519">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-520'
	>
	Consuming ownership</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-522">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-523'
	>
	When a function takes ownership of a non-copyable type, we mark the parameter as <code>consuming</code>. This transfers ownership to the function, invalidating the original owner:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-526"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func use</span><span class="token">(</span><span class="token">token</span><span class="token">: </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> SingleUseToken</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SingleUseToken(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">use(</span><span class="token">token:</span><span class="token"> token</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; `</span><span class="token">token` consumed more then once
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-529"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-527">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-528'
	>
	Some operations, like variable assignments, have default consuming semantics:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-531"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SingleUseToken(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> consumedToken </span><span class="token" style="color: #d73a49;">=</span><span class="token"> token
</span></span><span class="line"><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; `</span><span class="token">token` consumed more then once
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-534"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-532">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-533'
	>
	Borrowing ownership</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-537"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-535">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-536'
	>
	If a function requires a parameter of a non-copyable type only temporarily, we mark the parameter as <code>borrowing</code>. This indicates that the original ownership is not invalidated and that the function cannot consume the parameter in any way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func borrow</span><span class="token">(</span><span class="token">token</span><span class="token">: </span><span class="token" style="color: #d73a49;">borrowing</span><span class="token"> SingleUseToken</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SingleUseToken(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">use(</span><span class="token">token:</span><span class="token"> token</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">token.</span><span class="token">use(</span><span class="token">)</span><span class="token"> allowed
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func borrow</span><span class="token">(</span><span class="token">token</span><span class="token">: </span><span class="token" style="color: #d73a49;">borrowing</span><span class="token"> SingleUseToken</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    token.</span><span class="token">use(</span><span class="token">)</span><span class="token"> `token` </span><span class="token" style="color: #d73a49;">is</span><span class="token"> borrowed and cannot be consumed
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SingleUseToken(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">borrow(</span><span class="token">token:</span><span class="token"> token</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-542"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-540">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-541'
	>
	The inout modifier</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-545"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-543">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-544'
	>
	Before looking into how the <code>inout</code> modifier behaves with non-copyable types, it’s helpful to review what <code>inout</code><em> </em>does:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-548"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-546">
	<p	class='typography typography--size-18-text-roman js-typography block-paragraph__paragraph'
	data-id='es-547'
	>
	<em>In-out parameters are passed as follows:</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-551"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-549">
	<ul	class='typography typography--size-18-text-roman js-typography lists__typography'
	data-id='es-550'
	>
	<li><em>When the function is called, the value of the argument is copied.</em></li><li><em>In the body of the function, the copy is modified.</em></li><li><em>When the function returns, the copy’s value is assigned to the original argument.</em></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-552">
	<p	class='typography typography--size-14-text-roman js-typography block-paragraph__paragraph'
	data-id='es-553'
	>
	(<a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations/#In-Out-Parameters">THE SWIFT PROGRAMMING LANGUAGE</a> BOOK)</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-557"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-555">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-556'
	>
	For non-copyable types, things are a bit different. If a function consumes an <code>inout</code><em> </em>argument, the compiler will issue a warning, indicating that the <code>inout</code><em> </em>argument must be reinitialized (since it cannot be copied back after consumption):</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-559"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func </span><span class="token" style="color: #d73a49;">`</span><span class="token">inout`</span><span class="token">(</span><span class="token">token</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> SingleUseToken</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    token.</span><span class="token">use(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; Missi</span><span class="token">ng reinitialization </span><span class="token" style="color: #d73a49;">of</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> parameter `token` after consume
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SingleUseToken(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">inout</span><span class="token">(</span><span class="token">token:</span><span class="token"> token</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-562"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-560">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-561'
	>
	Mutating functions</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-565"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-563">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-564'
	>
	A mutating function implicitly takes the <code>self</code><em> </em>argument as <code>inout</code>, which means the same rules apply as for explicit <code>inout</code><em> </em>arguments:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-567"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SingleUseToken</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">mutating</span><span class="token"> </span><span class="token">func useAndUpdate</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">use(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; Missing r</span><span class="token">einitialization </span><span class="token" style="color: #d73a49;">of</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> parameter `</span><span class="token" style="color: #005cc5;">self</span><span class="token">` after consume
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-570"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-568">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-569'
	>
	The discard operator</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-573"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-571">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-572'
	>
	Although non-copyable types are value types, their unique ownership makes <code>deinit</code><em> </em>relevant. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-576"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-574">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-575'
	>
	You can declare a <code>deinit</code><em> </em>for non-copyable types, just as you would for classes:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-578"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct SingleUseToken</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        UserDefaults.</span><span class="token">standard</span><span class="token">.</span><span class="token" style="color: #005cc5;">set</span><span class="token">(</span><span class="token" style="color: #005cc5;">false</span><span class="token">, </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">token-used</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-581"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-579">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-580'
	>
	However, there are scenarios where you may want to prevent <code>deinit</code><em> </em>from being called in certain code paths:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct SingleUseToken</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> </span><span class="token">func use</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">       </span><span class="token" style="color: #d73a49;">let</span><span class="token"> token </span><span class="token" style="color: #d73a49;">=</span><span class="token"> token
</span></span><span class="line"><span class="token">       UserDefaults.</span><span class="token">standard</span><span class="token">.</span><span class="token" style="color: #005cc5;">set</span><span class="token">(</span><span class="token" style="color: #005cc5;">true</span><span class="token">, </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">token-used</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">       discard </span><span class="token" style="color: #005cc5;">self</span><span class="token">
</span></span><span class="line"><span class="token">       </span><span class="token" style="color: #d73a49;">return</span><span class="token"> token
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        UserDefaults.</span><span class="token">standard</span><span class="token">.</span><span class="token" style="color: #005cc5;">set</span><span class="token">(</span><span class="token" style="color: #005cc5;">false</span><span class="token">, </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">token-used</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-584">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-585'
	>
	If we didn’t <code>discard self</code>, the <code>deinit</code><em> </em>would be called and <code>token-used</code> would be incorrectly set to <code>false</code><em>.</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-587">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-588'
	>
	Non-copyable generics</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-592"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-590">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-591'
	>
	Swift’s type hierarchy has traditionally assumed that types are copyable, which is reflected in the interaction between structs, enums, and classes:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-597"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-595"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-596">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/10/Before-1400x963.webp				media='(max-width: 699px)'
				type=image/webp								height="963"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2024/10/Before-2400x1651.webp				media='(max-width: 1199px)'
				type=image/webp								height="1651"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2024/10/Before.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1926"
															width="2800"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-617"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-601">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-600"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-598">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-602">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-603'
	>
	However, the introduction of non-copyable types presents a new challenge: how do these types fit into the existing hierarchy?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-605">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-606'
	>
	At first glance, one might assume that non-copyable types could be considered subtypes of regular structs and enums. However, this isn’t possible because these types are inherently copyable. Another idea might be to place them as subtypes of <code>Any</code>, but unfortunately, this approach also fails since <em>Any</em> is implicitly <code>Copyable</code>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-608">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-609'
	>
	Consider the following example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-612"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct Test</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> test </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Test(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">test </span><span class="token" style="color: #d73a49;">as</span><span class="token"> </span><span class="token" style="color: #005cc5;">Any</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; N</span><span class="token">oncopyable type &#039;Test&#039; cannot be erased to copyable existential type &#039;</span><span class="token" style="color: #005cc5;">Any</span><span class="token">&#039;
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-615"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-613">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-614'
	>
	Therefore, non-copyable types do not fit into the existing hierarchy but form their own type hierarchy instead.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-620"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-618"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-619">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/10/Distinct-1400x963.webp				media='(max-width: 699px)'
				type=image/webp								height="963"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2024/10/Distinct-2400x1651.webp				media='(max-width: 1199px)'
				type=image/webp								height="1651"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2024/10/Distinct.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1926"
															width="2800"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-666"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-624">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-623"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-621">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-627"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-625">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-626'
	>
	However, having two independent type hierarchies makes it really challenging to write generic code. A simple example illustrates this issue:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-629"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">struct</span><span class="token"> </span><span class="token" style="color: #005cc5;">Test</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #005cc5;">Copyable</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">func</span><span class="token"> </span><span class="token" style="color: #005cc5;">generic</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #005cc5;">T</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">(</span><span class="token" style="color: #005cc5;">t</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">T</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">generic</span><span class="token">(</span><span class="token" style="color: #6f42c1;">Test</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">&#x274c;</span><span class="token"> </span><span class="token" style="color: #005cc5;">Noncopyable</span><span class="token"> </span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">Test</span><span class="token" style="color: #032f62;">&#039;</span><span class="token"> </span><span class="token" style="color: #005cc5;">cannot</span><span class="token"> </span><span class="token" style="color: #005cc5;">be</span><span class="token"> </span><span class="token" style="color: #005cc5;">substituted</span><span class="token"> </span><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token" style="color: #005cc5;">copyable</span><span class="token"> </span><span class="token" style="color: #005cc5;">generic</span><span class="token"> </span><span class="token" style="color: #005cc5;">parameter</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">T</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-632"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-630">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-631'
	>
	In this case, the generic type parameter <code>T</code> assumes copyability, as it is a subtype of Any. Consequently, a type from the non-copyable hierarchy can’t be passed in.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-635"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-633">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-634'
	>
	We could employ a workaround here, writing an alternative function that accepts non-copyable types. However, this approach makes non-copyable types feel like second-class citizens in Swift’s type system.<br />
The issue is even worse if you consider that you can’t use non-copyable types with <code>Optional</code>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-637"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct Test</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> test </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Optional</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">Test</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">.</span><span class="token" style="color: #005cc5;">none</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; N</span><span class="token">oncopyable type &#039;Test&#039; cannot be used with generic type &#039;</span><span class="token" style="color: #005cc5;">Optional</span><span class="token" style="color: #d73a49;">&lt;Wr</span><span class="token">apped</span><span class="token" style="color: #d73a49;">&gt;&#039;
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-638">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-639'
	>
	Before delving into the new type hierarchy, it is important to clarify the meaning of <code>~Copyable</code>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-642"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-20-text js-typography block-highlighted-text__typography'
	data-id='es-641'
	>
	<strong>~Copyable suppresses the implicit conformance to the Copyable protocol.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-645"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-643">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-644'
	>
	This means that when a type is marked as <code>~Copyable</code>, the compiler is not allowed to insert any copy operations for that type.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-648"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-646">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-647'
	>
	Here’s what this means for generic code constrained to <code>~Copyable</code>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-650"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func generic</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">T</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable</span><span class="token">&gt;</span><span class="token">(</span><span class="token">t</span><span class="token">: </span><span class="token">T</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; P</span><span class="token">arameter </span><span class="token" style="color: #d73a49;">of</span><span class="token"> noncopyable type &#039;T&#039; must specify ownership
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-653"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-651">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-652'
	>
	First of all, we need to specify ownership, as the compiler needs to understand which operations are allowed within the function.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-655"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct NC</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">struct CO</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func generic</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">T</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable</span><span class="token">&gt;</span><span class="token">(</span><span class="token">t</span><span class="token">: </span><span class="token" style="color: #d73a49;">borrowing</span><span class="token"> T</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">generic(</span><span class="token">Test(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x2705; a</span><span class="token">llowed
</span></span><span class="line"><span class="token">generic(</span><span class="token">CO(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x2705; a</span><span class="token">llowed
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-658"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-656">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-657'
	>
	Once we do that, we can use <em>generic</em> functions both with <code>~Copyable</code> and <code>Copyable</code> types.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-661"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-659">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-660'
	>
	This way, <code>Copyable</code><em> </em>types are effectively a subtype of <code>~Copyable</code>, as <code>Copyable</code><em> </em>adds new functionality to the conforming type.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-664"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-662">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-663'
	>
	Finally, the new type hierarchy can be illustrated as follows:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-669"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-667"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-668">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/10/After-1400x1143.webp				media='(max-width: 699px)'
				type=image/webp								height="1143"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2024/10/After-2400x1959.webp				media='(max-width: 1199px)'
				type=image/webp								height="1959"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2024/10/After.webp"
					class="image__img block-media__image-img"
					alt=""
										height="2286"
															width="2800"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-723"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-673">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-672"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-670">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-676"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-674">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-675'
	>
	Non-copyable or maybe-copyable?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-679"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-677">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-678'
	>
	At first glance, it may seem strange that we can use a <strong>copyable </strong>type in place of a <strong>non-copyable </strong>one in generic code. This is where the naming of the feature can be confusing. In generic code, we are not strictly dealing with <strong>non-copyable</strong> types, but rather <strong>maybe-copyable </strong>types.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-682"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-680">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-681'
	>
	In a way, the distinction is contextual:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-685"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-683">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-684'
	>
	<li>Our Test struct is <strong>non-copyable</strong> – the compiler will prevent any attempt to copy it</li><li>A generic parameter T constrained by ~Copyable is <strong>maybe-copyable</strong>, meaning that a given parameter cannot be assumed to be copyable, but can be, depending on the specific type</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-688"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-686">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-687'
	>
	Though it may seem like this distinction calls for a different syntax, in practice, both <strong>non-copyable </strong>and <strong>maybe-copyable </strong>types<strong> </strong>share the fundamental requirement: the compiler cannot assume the type is copyable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-689">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-690'
	>
	Case study: finding the longest line in a large file</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-694"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-692">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-693'
	>
	To demonstrate the performance advantages of non-copyable types in Swift, let’s try a real-world, performance-critical task: finding the longest line in a large file. In cases where files are too large to load entirely into memory, we need to read them line by line. Optimizing tasks like this can yield significant benefits for performance, especially when processing multi-gigabyte files.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-697"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-695">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-696'
	>
	For our case study, we use a large dataset – 2,47GB of <a href="https://www.kaggle.com/datasets/dhruvildave/github-commit-messages-dataset" target="_blank" rel="noreferrer noopener">Github Commit Messages</a>. The goal is to identify the longest line in the file as efficiently as possible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-700"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-698">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-699'
	>
	Initial approach: using high-level Swift APIs</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-703"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-701">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-702'
	>
	<a href="https://github.com/infinum/iOS-Swift-Ownership/blob/main/Sources/SwiftOwnership/FindLongest/StringFindLongest.swift#L4-L12" target="_blank" rel="noreferrer noopener">Source code</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-706"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-704">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-705'
	>
	The following code sample demonstrates a possible <a href="https://forums.swift.org/t/read-text-file-line-by-line/28852/6" target="_blank" rel="noreferrer noopener">typical wrapper</a> around a <code>FILE</code> pointer:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-708"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class File</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">let file:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UnsafeMutablePointer</span><span class="token">&lt;</span><span class="token">FILE</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">init(fil</span><span class="token">eURL</span><span class="token">: </span><span class="token">URL</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> fil</span><span class="token">e </span><span class="token" style="color: #d73a49;">= fopen(f</span><span class="token">ileURL.</span><span class="token">path</span><span class="token">, </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">r</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">throw</span><span class="token"> </span><span class="token">NSError(</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">domain:</span><span class="token"> NSPOSIXErrorDomain</span><span class="token">,
</span></span><span class="line"><span class="token">                </span><span class="token">code:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">(</span><span class="token">errno</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">                </span><span class="token">userInfo:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">file</span><span class="token"> </span><span class="token" style="color: #d73a49;">= file
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> success </span><span class="token" style="color: #d73a49;">= fclose(</span><span class="token">file</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">== 0
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">assert</span><span class="token">(</span><span class="token">success</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-711"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-709">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-710'
	>
	And this code illustrates the <code>readLine</code> API that the <code>File</code> wrapper might expose.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-713"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func readLine</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= [CC</span><span class="token" style="color: #005cc5;">har</span><span class="token">]</span><span class="token">(</span><span class="token">repeating:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">, </span><span class="token">count:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">guard</span><span class="token"> fge</span><span class="token">ts(</span><span class="token" style="color: #d73a49;">&amp;buff</span><span class="token">er</span><span class="token">, </span><span class="token" style="color: #005cc5;">Int32</span><span class="token">(</span><span class="token">maxLength</span><span class="token">)</span><span class="token">, </span><span class="token">file</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">!= nil</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> feof(fi</span><span class="token">le</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">!= 0 {
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">throw</span><span class="token"> </span><span class="token">NSError(</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">domain:</span><span class="token"> NSPOSIXErrorDomain</span><span class="token">, 
</span></span><span class="line"><span class="token">                </span><span class="token">code:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">(</span><span class="token">errno</span><span class="token">)</span><span class="token">, 
</span></span><span class="line"><span class="token">                </span><span class="token">userInfo:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">(</span><span class="token">cString:</span><span class="token"> buffer</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-716"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-714">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-715'
	>
	Finally, we can implement an algorithm to find the longest line:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-718"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">File</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">var longest:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> lin</span><span class="token">e</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token" style="color: #d73a49;">= try rea</span><span class="token" style="color: #005cc5;">dLine</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> line.count </span><span class="token" style="color: #d73a49;">&gt; (longest?.c</span><span class="token" style="color: #d73a49;">ount ?? 0)</span><span class="token" style="color: #d73a49;"> {
</span></span><span class="line"><span class="token">                longest </span><span class="token" style="color: #d73a49;">= line
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-721"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-719">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-720'
	>
	Running this code on a large file won’t complete in a reasonable amount of time. Before we optimize it, we want to check the instruments trace:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-726"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-724"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-725">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/10/naive-1400x693.webp				media='(max-width: 699px)'
				type=image/webp								height="693"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/10/naive.webp"
					class="image__img block-media__image-img"
					alt=""
										height="792"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-752"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-730">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-729"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-727">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-733"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-731">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-732'
	>
	We can see that over 90% of the time is spent in functions related to <em>String</em> handling, which is somewhat expected. Swift’s Strings are very powerful, but that power comes at a cost.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-736"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-734">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-735'
	>
	Ideally, we’d want to see file reading operations at the top of the profile.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-739"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-737">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-738'
	>
	Optimization #1: using the CChar array instead of String</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-742"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-740">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-741'
	>
	<a href="https://github.com/infinum/iOS-Swift-Ownership/blob/main/Sources/SwiftOwnership/FindLongest/StringFindLongest.swift#L14-L28" target="_blank" rel="noreferrer noopener">Source code</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-745"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-743">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-744'
	>
	Instead of constructing a <code>String</code> for every line that we read, let’s expose the <code>[CChar]</code> array as a return type of <code>readLine</code><em> </em>and construct a <code>String</code> <strong>only when</strong> we have a result:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-747"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longest:</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">CChar</span><span class="token">]</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longestCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> line</span><span class="token" style="color: #d73a49;">:</span><span class="token"> [</span><span class="token" style="color: #005cc5;">CChar</span><span class="token">] </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> </span><span class="token" style="color: #005cc5;">readLine</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">= line.wi</span><span class="token" style="color: #005cc5;">thUnsafeBufferPointer</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">strlen(</span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token" style="color: #005cc5;">baseAddress</span><span class="token" style="color: #d73a49;">!) }
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> count &gt;</span><span class="token" style="color: #d73a49;"> longest</span><span class="token">Count </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            longest </span><span class="token" style="color: #d73a49;">= line
</span></span><span class="line"><span class="token">            longestCount </span><span class="token" style="color: #d73a49;">= count
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest.</span><span class="token" style="color: #005cc5;">map</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">(</span><span class="token">cString:</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-750"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-748">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-749'
	>
	Let’s see how it performs now.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-755"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-753"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-754">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/10/cchar-array.webp"
					class="image__img block-media__image-img"
					alt=""
										height="790"
															width="1332"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-778"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-759">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-758"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-756">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-762"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-760">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-761'
	>
	This change eliminates much of the overhead associated with <code>String</code><em> </em>creation, but performance is still impacted by the memory allocations for each line. This is expected, as we are allocating a new buffer for each line read.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-765"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-763">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-764'
	>
	Optimization #2: reusing existing buffers</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-768"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-766">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-767'
	>
	<a href="https://github.com/infinum/iOS-Swift-Ownership/blob/main/Sources/SwiftOwnership/FindLongest/StringFindLongest.swift" target="_blank" rel="noreferrer noopener">Source code</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-771"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-769">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-770'
	>
	Let’s reuse a buffer from the previous read iteration instead of allocating a new one every time:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-773"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= [CC</span><span class="token" style="color: #005cc5;">har</span><span class="token">]</span><span class="token">(</span><span class="token">repeating:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">, </span><span class="token">count:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longest:</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">CChar</span><span class="token">]</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longestCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> line</span><span class="token" style="color: #d73a49;">:</span><span class="token"> [</span><span class="token" style="color: #005cc5;">CChar</span><span class="token">] </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> </span><span class="token" style="color: #005cc5;">readLine</span><span class="token">(</span><span class="token">reuseChunk:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;buff</span><span class="token">er</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">= line.wi</span><span class="token" style="color: #005cc5;">thUnsafeBufferPointer</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">strlen(</span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token" style="color: #005cc5;">baseAddress</span><span class="token" style="color: #d73a49;">!) }
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> count &gt;</span><span class="token" style="color: #d73a49;"> longest</span><span class="token">Count </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            longest </span><span class="token" style="color: #d73a49;">= line
</span></span><span class="line"><span class="token">            longestCount </span><span class="token" style="color: #d73a49;">= count
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest.</span><span class="token" style="color: #005cc5;">map</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">(</span><span class="token">cString:</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-776"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-774">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-775'
	>
	If we profile this code, we get the following trace:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-781"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-779"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-780">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/10/cchar-array-reuse.webp"
					class="image__img block-media__image-img"
					alt=""
										height="788"
															width="1332"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-809"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-785">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-784"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-782">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-788"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-786">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-787'
	>
	This reduces the memory allocation cost but surfaces a new issue: the <code>Array</code> type in Swift is a copy-on-write (CoW) data type, and whenever we find a new longest line, the whole array will be copied.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-791"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-789">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-790'
	>
	Optimization #3: introducing FileChunk</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-794"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-792">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-793'
	>
	<a href="https://github.com/infinum/iOS-Swift-Ownership/blob/main/Sources/SwiftOwnership/FindLongest/ClassFindLongest.swift" target="_blank" rel="noreferrer noopener">Source code</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-797"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-795">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-796'
	>
	To avoid unnecessary copying, we will not expose <code>[CChar]</code><em> </em>directly but wrap a pointer in a <code>FileChunk</code> object:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-799"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class FileChunk</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">let maxCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let _buffer:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UnsafeMutablePointer</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">CChar</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">init(max</span><span class="token">Count</span><span class="token">: </span><span class="token" style="color: #005cc5;">Int</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">precondition</span><span class="token">(</span><span class="token">maxCount </span><span class="token" style="color: #d73a49;">&gt; 0)
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">maxCount</span><span class="token"> </span><span class="token" style="color: #d73a49;">= maxCoun</span><span class="token">t
</span></span><span class="line"><span class="token">        _buffer </span><span class="token" style="color: #d73a49;">= UnsafeM</span><span class="token" style="color: #005cc5;">utablePointer</span><span class="token" style="color: #d73a49;">&lt;CChar&gt;.a</span><span class="token" style="color: #d73a49;">llocat</span><span class="token" style="color: #005cc5;">e</span><span class="token">(</span><span class="token">capacity:</span><span class="token"> maxCount</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        _buffer.</span><span class="token" style="color: #005cc5;">initialize</span><span class="token">(</span><span class="token">repeating:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">, </span><span class="token">count:</span><span class="token"> maxCount</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        _buffer.</span><span class="token" style="color: #005cc5;">deinitialize</span><span class="token">(</span><span class="token">count:</span><span class="token"> maxCount</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        _buffer.</span><span class="token" style="color: #005cc5;">deallocate</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">var count:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">strlen(</span><span class="token">_buffer</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">var asString:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">(</span><span class="token">cString:</span><span class="token"> _buffer</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-802"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-800">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-801'
	>
	This is our <code>findLongest</code> algorithm now:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-804"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= Fil</span><span class="token">eChunk(</span><span class="token">maxLength:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longest:</span><span class="token"> FileChunk</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longestCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> line</span><span class="token" style="color: #d73a49;">:</span><span class="token"> FileChunk </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> </span><span class="token" style="color: #005cc5;">readLine</span><span class="token">(</span><span class="token">reuseChunk:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;buff</span><span class="token">er</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">= line.co</span><span class="token" style="color: #005cc5;">unt</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> count &gt;</span><span class="token" style="color: #d73a49;"> longest</span><span class="token">Count </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            longest </span><span class="token" style="color: #d73a49;">= line
</span></span><span class="line"><span class="token">            longestCount </span><span class="token" style="color: #d73a49;">= count
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest.</span><span class="token">asString</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-807"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-805">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-806'
	>
	Let’s profile it now:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-812"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-810"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-811">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/10/file-chunk.webp"
					class="image__img block-media__image-img"
					alt=""
										height="790"
															width="1330"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-859"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-816">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-815"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-813">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-819"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-817">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-818'
	>
	The situation is looking much better. As we would expect, the majority of the time is spent on <code>fgets</code> and the associated C functions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-822"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-820">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-821'
	>
	It is also interesting to notice that <code>swift_retain</code> and<code> swift_release</code> incur significant costs.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-825"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-823">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-824'
	>
	Optimization #4: making FileChunk non-copyable</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-828"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-826">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-827'
	>
	<a href="https://github.com/infinum/iOS-Swift-Ownership/blob/main/Sources/SwiftOwnership/FindLongest/NonCopyableFindLongest.swift" target="_blank" rel="noreferrer noopener">Source code</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-831"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-829">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-830'
	>
	To address this issue, we’ll convert <code>FileChunk</code><em> </em>from a reference type to a non-copyable type:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-833"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">struct FileChunk</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #6f42c1;">Copyable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> the same implementation</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-836"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-834">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-835'
	>
	But now we are required to explicitly manage the ownership of <code>FileChunk</code> as it can no longer be shared between multiple owners.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-839"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-837">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-838'
	>
	First, we need to adjust our <code>readLine</code> function to make ownership explicit:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-841"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func readLine</span><span class="token">(</span><span class="token">toReuse</span><span class="token">: </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> FileChunk</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">FileChunk</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> currentChunk </span><span class="token" style="color: #d73a49;">= toR</span><span class="token">euse </span><span class="token" style="color: #d73a49;">?? Fil</span><span class="token">eChunk(</span><span class="token">maxCount:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> The same implementation as previously</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> currentChunk
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-844"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-842">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-843'
	>
	In this version, we mark the <code>FileChunk</code> parameter as <code>consuming</code>, meaning the function takes ownership of the argument. Once the buffer is filled, the function returns <code>currentChunk,</code> passing ownership back to the caller, allowing the buffer to be reused.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-847"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-845">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-846'
	>
	After making this change, we get two errors in our <code>findLongest</code> implementation:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-849"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longest:</span><span class="token"> FileChunk</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= Fil</span><span class="token">eChunk(</span><span class="token">maxCount:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&#x274c; // &#039;b</span><span class="token" style="color: #6a737d;">uffer&#039; consumed in a loop</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longestCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> line</span><span class="token" style="color: #d73a49;">:</span><span class="token"> FileChunk </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> </span><span class="token" style="color: #005cc5;">readLine</span><span class="token">(</span><span class="token">toReuse:</span><span class="token"> buffer</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">= line.co</span><span class="token" style="color: #005cc5;">unt</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> count &gt;</span><span class="token" style="color: #d73a49;"> longest</span><span class="token">Count </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            longest </span><span class="token" style="color: #d73a49;">= line &#x274c; // I</span><span class="token" style="color: #d73a49;">mplicit c</span><span class="token" style="color: #6a737d;">onversion to &#039;FileChunk?&#039; is consuming</span><span class="token">
</span></span><span class="line"><span class="token">            longestCount </span><span class="token" style="color: #d73a49;">= count
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest</span><span class="token" style="color: #d73a49;">?.asS</span><span class="token">tring</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-852"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-850">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-851'
	>
	Let’s solve them:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-854"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func findLongest</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longest:</span><span class="token"> FileChunk</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">= nil</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> buffer </span><span class="token" style="color: #d73a49;">= Fil</span><span class="token">eChunk(</span><span class="token">maxCount:</span><span class="token"> maxLength</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var longestCount:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> line</span><span class="token" style="color: #d73a49;">:</span><span class="token"> FileChunk </span><span class="token" style="color: #d73a49;">= try</span><span class="token"> </span><span class="token" style="color: #005cc5;">readLine</span><span class="token">(</span><span class="token">toReuse:</span><span class="token"> buffer</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">= line.co</span><span class="token" style="color: #005cc5;">unt</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> count &gt;</span><span class="token" style="color: #d73a49;"> longest</span><span class="token">Count </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            buffer </span><span class="token" style="color: #d73a49;">= l</span><span class="token">ongest
</span></span><span class="line"><span class="token">            longest </span><span class="token" style="color: #d73a49;">= consume lin</span><span class="token">e
</span></span><span class="line"><span class="token">            longestCount </span><span class="token" style="color: #d73a49;">= count
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            buffer </span><span class="token" style="color: #d73a49;">= consume lin</span><span class="token">e
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> longest</span><span class="token" style="color: #d73a49;">?.asS</span><span class="token">tring</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-857"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-855">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-856'
	>
	And now, let’s check the performance.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-868"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-863">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-862"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-860">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-866"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-864">
	</div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-871"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-869"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-870">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/10/non-copyable.webp"
					class="image__img block-media__image-img"
					alt=""
										height="792"
															width="1332"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-898"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-875">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-874"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-872">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-878"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-876">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-877'
	>
	We can see that almost all of the time is spent on file reading operations, indicating a significant performance improvement.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-881"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-879">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-880'
	>
	Final results: performance gains</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-884"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-882">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-883'
	>
	The performance improvements across the different implementations are summarized in the table below:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-887"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-886>
	
<div
	class="wrapper"
	data-id="es-885"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure style="font-size:20px" class="wp-block-table"><table><thead><tr><th><strong>Implementation</strong></th><th><strong>Timing (ms)</strong></th></tr></thead><tbody><tr><td>Naive</td><td>Doesn’t complete in reasonable time</td></tr><tr><td>CChar array</td><td>106295</td></tr><tr><td>Reuse allocation in CChar array</td><td>100463</td></tr><tr><td>FileChunk</td><td>3136</td></tr><tr><td>Non-copyable FileChunk</td><td>2079</td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-890"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-888">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-889'
	>
	Note: If you are interested, the longest line can be found in <a href="https://github.com/chromium/chromium/commit/4e3395cd014da53004ac20cc296c9eb876e1727f" target="_blank" rel="noreferrer noopener">this commit</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-893"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-891">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-892'
	>
	A hidden bug</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-896"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-894">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-895'
	>
	If you look closely, you’ll notice a difference between our final implementation using a reference type and the one using a non-copyable type:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-910"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="grid block-grid__grid" data-id="es-909">
	
<div class="block-grid-item" data-id="es-901">
	
<div class="block-paragraph" data-id="es-899">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-900'
	>
	<strong><code>FileChunk</code> as a reference type</strong></p></div>
</div>

<div class="block-grid-item" data-id="es-903">
	
<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">code</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">=</span><span class="token"> line.</span><span class="token" style="color: #005cc5;">count</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">if</span><span class="token"> count </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> longestCount </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    longest </span><span class="token" style="color: #d73a49;">= lin</span><span class="token">e
</span></span><span class="line"><span class="token">    longestCount </span><span class="token" style="color: #d73a49;">= cou</span><span class="token">nt
</span></span><span class="line"><span class="token">}</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">code</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span></code></pre></div>
</div>

<div class="block-grid-item" data-id="es-906">
	
<div class="block-paragraph" data-id="es-904">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-905'
	>
	<strong><code>FileChunk</code> as a non-copyable type</strong></p></div>
</div>

<div class="block-grid-item" data-id="es-908">
	
<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">code</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">let</span><span class="token"> count </span><span class="token" style="color: #d73a49;">=</span><span class="token"> line.</span><span class="token" style="color: #005cc5;">count</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">if</span><span class="token"> count </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> longestCount </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    buffer </span><span class="token" style="color: #d73a49;">= lon</span><span class="token">gest
</span></span><span class="line"><span class="token">    longest </span><span class="token" style="color: #d73a49;">= con</span><span class="token" style="color: #d73a49;">sume</span><span class="token"> line
</span></span><span class="line"><span class="token">    longestCount </span><span class="token" style="color: #d73a49;">= cou</span><span class="token">nt
</span></span><span class="line"><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    buffer </span><span class="token" style="color: #d73a49;">= con</span><span class="token" style="color: #d73a49;">sume</span><span class="token"> line
</span></span><span class="line"><span class="token">}</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">code</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span></code></pre></div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-931"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-914">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-913"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-911">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-917"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-915">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-916'
	>
	Upon closer inspection, we can see that the reference type implementation contains a hidden bug – it overrides the longest line found because the buffer is being reused. This issue is avoided with the non-copyable type, as it enforces unique ownership and prevents unintentional buffer reuse.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-920"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-918">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-919'
	>
	The value of non-copyable types</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-923"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-921">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-922'
	>
	As we’ve seen, non-copyable types offer not only performance benefits but also improved safety compared to reference types. They are a safer and more ergonomic alternative to dealing with raw pointers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-926"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-924">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-925'
	>
	One of the reasons the programming language C is known for its speed is that it exposes the full complexity of memory management, allowing direct manipulation through pointers. Swift, as a high-level programming language, abstracts much of this complexity. With the introduction of non-copyable types, Swift strikes a balance – allowing developers to write safe, high-performance code while maintaining the high-level programming experience.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-929"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-927">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-928'
	>
	For reference, the associated source code for this article can be found <a href="https://github.com/infinum/iOS-Swift-Ownership/tree/main/Sources/SwiftOwnership/FindLongest" target="_blank" rel="noreferrer noopener">here</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/swift-non-copyable-types/">Meet Non-Copyable Types – Swift’s Secret Performance Boost</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19252667https://infinum.com/uploads/2024/04/Best-practices-for-crash-reporting-hero-min.webp</url>
				</image>
				<title>Fix It Fast – Best Practices for Application Errors and Crashes</title>
				<link>https://infinum.com/blog/application-errors-best-practices/</link>
				<pubDate>Thu, 11 Apr 2024 15:39:04 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19252667</guid>
				<description>
					<![CDATA[<p>Application errors and crashes are a part of life. Instead of avoiding them, learn how to handle them in a meaningful way.</p>
<p>The post <a href="https://infinum.com/blog/application-errors-best-practices/">Fix It Fast – Best Practices for Application Errors and Crashes</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1031"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-932">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-935"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-933">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-934'
	>
	<strong>Application errors and crashes are a part of life. Instead of avoiding them, learn how to handle them in a meaningful way.&nbsp;</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-938"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-936">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-937'
	>
	Everyone loves an application that runs perfectly smoothly and never crashes. The users are happy, the clients are happy, you can high-five your colleagues and head home. Unfortunately, this isn’t always the case. Crashes and application errors are simply a part of life, and we have to know how to deal with them.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-941"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-939">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-940'
	>
	Instead of striving for a perfect world, our goal as developers should be to make the best effort to effectively diagnose and quickly fix issues when they arise.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-944"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-942">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-943'
	>
	At Infinum, we’ve worked on hundreds of mobile apps, and fixing crashes is our daily activity. In this article, we will present our learnings and best practices for crash reporting and error handling.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-947"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-945">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-946'
	>
	Handling application errors</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-952"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-948">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-949'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-950'
	>
	Errors are a fact of life in software.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-951'
	>
	<a href="https://doc.rust-lang.org/book/ch09-00-error-handling.html" target="_blank" rel="noreferrer noopener">RUST PROGRAMMING LANGUAGE</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-955"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-953">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-954'
	>
	Swift has a powerful <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/" target="_blank" rel="noreferrer noopener">error-handling mechanism</a>, which can be very helpful for building robust and resilient apps. But, as with all language features, we need to use it correctly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-958"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-956">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-957'
	>
	Generally speaking, there are two types of application errors: expected and unexpected.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-961"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-959">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-960'
	>
	Expected application errors</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-964"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-962">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-963'
	>
	Expected errors are usually handled as part of the regular application flow. Let&#8217;s illustrate this with two examples.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-967"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-965">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-966'
	>
	<strong>Example 1</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-970"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-968">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-969'
	>
	The user uploads a document to the backend, but the backend needs some time to process it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-973"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-971">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-972'
	>
	In this case, the application might implement API polling. The API can return a 404 error to indicate that the resource is not yet available. The application can retry an API call until it gets a 200 response code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-976"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-974">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-975'
	>
	<strong>Example 2</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-979"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-977">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-978'
	>
	The user attempts to download a file in bad network conditions. The application might implement an automatic retry mechanism to make it more resilient to failures.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-982"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-980">
	<h3	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-981'
	>
	Typed errors</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-987"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-983">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-984'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-985'
	>
	Errors are generally propagated and rendered, but rarely handled exhaustively, and are prone to changing over time in a way that types are not.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-986'
	>
	<a href="https://github.com/apple/swift-evolution/blob/main/proposals/0413-typed-throws.md#motivation" target="_blank" rel="noreferrer noopener">SE-0413 TYPED THROWS</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-990"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-988">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-989'
	>
	Whether your APIs are using Combine, Result type, or recently accepted <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0413-typed-throws.md" target="_blank" rel="noreferrer noopener">typed throws</a>, you might be inclined to define something like:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-992"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">enum MyAppError</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">network
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">invalidInput
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> ...</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-995"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-993">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-994'
	>
	This would expose explicit error types in your APIs. However, this tactic is generally not advisable as it will limit your ability to compose. You’ll likely end up constantly adding error cases to the <code>MyAppError</code> enumeration.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-998"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-996">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-997'
	>
	However, when we approach this wisely, in some cases, we can get elegant APIs. For example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1000"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">enum ResourceError</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Error </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">notAvailable
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">error</span><span class="token">(</span><span class="token" style="color: #005cc5;">Error</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func checkIfResourceAvailable</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">AnyPublisher</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Void</span><span class="token">, ResourceError</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">fatalError</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func waitUntilAvailable</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> Publisher</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Void</span><span class="token">, </span><span class="token" style="color: #005cc5;">Error</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">checkIfResourceAvailable(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        .</span><span class="token">tryCatch</span><span class="token"> </span><span class="token">{</span><span class="token"> error </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">switch</span><span class="token"> error {
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token">notAvailable</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">waitUntilAvailable(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token" style="color: #005cc5;">error</span><span class="token">(</span><span class="token" style="color: #d73a49;">let</span><span class="token"> error</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">throw</span><span class="token"> error
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        .</span><span class="token">eraseToAnyPublisher(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1003"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1001">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1002'
	>
	It is important to use this approach on very localized use cases that don’t propagate typed error information upstream. Upstream code tends to handle errors generically.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1006"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1004">
	<h3	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-1005'
	>
	Unexpected application errors</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1011"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1007">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1008'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1009'
	>
	An error has occurred.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1010'
	>
	<a href="http://hallofshame.gp.co.at/errormsg.htm" target="_blank" rel="noreferrer noopener">INTERFACE HALL OF SHAME</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1014"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1012">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1013'
	>
	Unexpected errors are the ones that applications cannot handle in a meaningful way. Usually, the application has no better way of dealing with these errors than by displaying them to the user.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1017"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1015">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1016'
	>
	Here are some recommendations for handling unexpected errors:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1020"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1018">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1019'
	>
	Make illegal states unrepresentable</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1023"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1021">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1022'
	>
	One of our primary objectives as programmers is to translate business rules into code representation. While direct translation is often impractical, striving for close alignment between the code and business rules is important. This ensures that the code reflects the intended logic and avoids states that are not allowed by business rules.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1026"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1024">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1025'
	>
	This principle equally applies to error handling and enables a consistent user experience.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1029"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1027">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1028'
	>
	Errors usually occur in response to some user action. More generally, this interaction can be visualized in the following diagram:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1034"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1032"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1033">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/04/Shema-1400x608.webp				media='(max-width: 699px)'
				type=image/webp								height="608"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2024/04/Shema-2400x1042.webp				media='(max-width: 1199px)'
				type=image/webp								height="1042"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2024/04/Shema.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1250"
															width="2880"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1270"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1038">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1037"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1035">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1041"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1039">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1040'
	>
	The diagram shows three mutually exclusive states of our program:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1045"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1042">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1043'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1044'
	>
	Data loading is in progress.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1049"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1046">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1047'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1048'
	>
	Data is successfully obtained.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1053"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1050">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1051'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1052'
	>
	There was an error during data loading.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1056"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1054">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1055'
	>
	To provide a consistent experience, it is useful to represent this idea in code explicitly. In SwiftUI, we can define something like:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1058"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">enum Loadable</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Value</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">loading
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">failure</span><span class="token">(</span><span class="token">error:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Error</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">success</span><span class="token">(</span><span class="token" style="color: #005cc5;">Value</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">struct LoadableView</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">T</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">U</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">View</span><span class="token">&gt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let element:</span><span class="token"> Loadable</span><span class="token">&lt;</span><span class="token">T</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@ViewBuilder</span><span class="token"> </span><span class="token">let onSuccess:</span><span class="token"> </span><span class="token">(</span><span class="token">T</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> U</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let onRetry:</span><span class="token"> </span><span class="token">(</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">Void</span><span class="token">)</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var body:</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">switch</span><span class="token"> element</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token">loading</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">LoadingView(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token">failure(</span><span class="token" style="color: #d73a49;">let</span><span class="token"> error</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">ErrorView(</span><span class="token">error:</span><span class="token"> error</span><span class="token">, </span><span class="token">onRetry:</span><span class="token"> onRetry</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token">success(</span><span class="token" style="color: #d73a49;">let</span><span class="token"> value</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">onSuccess(</span><span class="token">value</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1061"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1059">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1060'
	>
	This allows us to handle loading, error, and success states generically and consistently throughout the app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1064"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1062">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1063'
	>
	<code>ErrorView</code> can look something like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1066"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct ErrorView</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let error:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Error</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let onRetry:</span><span class="token"> </span><span class="token">(</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">Void</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token">var body:</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">VStack</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">Image(</span><span class="token">.</span><span class="token" style="color: #005cc5;">error</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">An error has occured</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">Text(</span><span class="token">error.</span><span class="token">localizedDescription</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">Button(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Retry</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">onRetry(</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1069"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1067">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1068'
	>
	This way, users will always see localized descriptions of the error, and they will be able to retry the operation. We also have the flexibility to expose other relevant information such as error code or error user info.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1072"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1070">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1071'
	>
	This pattern can either be applied to the whole screen or partially, to some of its elements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1075"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1073">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1074'
	>
	Error mappings</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1078"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1076">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1077'
	>
	To ensure this pattern works well, all your errors should conform to <code>LocalizedError</code> and provide a meaningful message to the user.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1081"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1079">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1080'
	>
	Unfortunately, in many cases, we will get an error from some API in either a third-party SDK or an iOS SDK. If it’s important to provide a human-readable message in those cases, you will need to handle those errors explicitly and provide your error message.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1084"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1082">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1083'
	>
	One of those cases can be a state of no internet connection. The code that handles it might look like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1086"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct NoInternetError</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Error</span><span class="token">, </span><span class="token" style="color: #6f42c1;">LocalizedError </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var errorDescription:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Please check your internet connection</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #005cc5;">Error</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var asNoInternet:</span><span class="token"> NoInternetError</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">switch</span><span class="token"> (</span><span class="token" style="color: #005cc5;">self</span><span class="token"> a</span><span class="token" style="color: #d73a49;">s</span><span class="token"> NSError</span><span class="token">)</span><span class="token">.code </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">case</span><span class="token"> NSURLErrorNotConnectedToInternet, NSURLErrorDataNotAllowed</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">NoInternetError(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">default</span><span class="token" style="color: #d73a49;">:</span><span class="token"> 
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1089"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1087">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1088'
	>
	API errors</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1092"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1090">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1091'
	>
	If the app uses backend APIs, this will most likely be the main source of errors. Try to define an error body contract with the backend team. This will transfer the ownership of error messages to the originator. The backend has more context required to return a good error message to the user.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1094"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">struct ErrorResponse</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Decodable</span><span class="token">, </span><span class="token" style="color: #6f42c1;">Equatable</span><span class="token">, </span><span class="token" style="color: #6f42c1;">Sendable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let code:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let title:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let detail:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">struct APIError</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">LocalizedError </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let code:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">let response:</span><span class="token"> ErrorResponse</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var errorDescription:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token"> response</span><span class="token" style="color: #d73a49;">?.tit</span><span class="token">le</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1097"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1095">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1096'
	>
	This can be optionally parsed from the response of URLSession and thrown as a more detailed error:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1099"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func fetch</span><span class="token">(</span><span class="token">request</span><span class="token">: </span><span class="token">URLRequest</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">async</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> ...</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">guard</span><span class="token"> res</span><span class="token">ponse.statusCode </span><span class="token" style="color: #d73a49;">&gt;= 200</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp; res</span><span class="token">ponse.statusCode </span><span class="token" style="color: #d73a49;">&lt; 300</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">let</span><span class="token"> response </span><span class="token" style="color: #d73a49;">= try? JS</span><span class="token" style="color: #d73a49;">ONDec</span><span class="token">oder(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #005cc5;">decode</span><span class="token">(</span><span class="token">ErrorResponse.</span><span class="token" style="color: #d73a49;">self</span><span class="token">, </span><span class="token">from:</span><span class="token"> data</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">throw</span><span class="token"> </span><span class="token">APIError(</span><span class="token">code:</span><span class="token"> response.</span><span class="token">statusCode</span><span class="token">, </span><span class="token">response:</span><span class="token"> response</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1102"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1100">
	<h5	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1101'
	>
	Be careful in API design</h5></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1103">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1104'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1105'
	>
	We still focus so much on our experience of the use of the construct.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1106'
	>
	<a href="https://www.youtube.com/watch?v=SxdOUGdseq4" target="_blank" rel="noreferrer noopener">SIMPLE MADE EASY – RICH HICKEY</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1108">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1109'
	>
	We all prefer convenient and easy-to-use APIs. But we need to be aware of what goes on in the background.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1112'
	>
	For example, it might be tempting to expose Keychain API as a property wrapper. That would allow us to do something like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">User</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token" style="color: #d73a49;">@</span><span class="token" style="color: #6f42c1;">KeychainValue</span><span class="token">(&quot;</span><span class="token" style="color: #6f42c1;">to</span><span class="token" style="color: #032f62;">ken</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">token</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">}
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1116">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1117'
	>
	This is very expressive code. In just one line, it is clear that we are dealing with a keychain item that automatically gets serialized and deserialized to the keychain.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1119">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1120'
	>
	Unfortunately, with such an API design, we fundamentally limit our program to handling keychain errors. The reason is that the underlying keychain API returns the status of the operation being performed. By exposing such an API as <code>String?</code><em>,</em> we effectively map all errors to optional values.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1122">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1123'
	>
	The same advice can be applied to choosing libraries. Understand what you get by integrating a library.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1125">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1126'
	>
	Debugging errors in production</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1128">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1129'
	>
	We can summarize this with a few simple rules:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1131">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1132'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1133'
	>
	Always preserve the original error. If you need to transform it, wrap it inside of your custom error.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1135">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1136'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1137'
	>
	Avoid using <code>try?</code> unless the operation is truly optional. This is rarely the case.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1139">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1140'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1141'
	>
	Avoid returning optional when an error should be thrown.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1143">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1144'
	>
	4</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1145'
	>
	Conform your errors to <code>LocalizedError</code><em>.</em></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1147">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1148'
	>
	By following these rules, we also get some positive side effects: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1150">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1151'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1152'
	>
	Users will always see localized descriptions.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1154">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1155'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1156'
	>
	We will preserve the original errors with all the details (such as HTTP status code or framework error).</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1158">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1159'
	>
	Error details</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1163"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1161">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1162'
	>
	Users are generally interested in human-readable descriptions of errors. But for programmers, it is critical to have as many details as possible about the error.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1164">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1165'
	>
	We can expose these details in our <code>ErrorView</code> by providing an additional Details button. If you can’t do that in production, it might be a good idea to enable detailed error handling at least in staging builds. This can make finding issues easier and shorten the feedback loop between the person reproducing the error and you.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1167">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1168'
	>
	Non-fatals</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1170">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1171'
	>
	Firebase <a href="https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=ios#log-excepts" target="_blank" rel="noreferrer noopener">non-fatals</a> are a great way to get more detailed information about errors that occur in production. This can usually provide critical information for debugging user-reported issues. To utilize and analyze them effectively, we need fine-grained error grouping.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1173">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1174'
	>
	As the <a href="https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=ios" target="_blank" rel="noreferrer noopener">Crashlytics guide</a> states:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1176">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1177'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1178'
	>
	Unlike fatal crashes, which are grouped via stack trace analysis, logged errors are grouped by <em>domain</em> and <em>code</em>.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1181'
	>
	This means that, to group Swift errors properly, we need to conform them to <code>CustomNSError</code>. For example, our <code>APIError</code> can conform to <code>CustomNSError</code> in the following way: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">APIError</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">CustomNSError </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var errorCode:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token">{</span><span class="token"> code </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">var errorDomain:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">APIError</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1187"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1185">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1186'
	>
	This will group all API errors with the same status code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1188">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1189'
	>
	The additional benefit of conforming to <code>CustomNSError</code> is that we can provide additional details that will show up in Firebase:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">var errorUserInfo:</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">String</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Any</span><span class="token">]</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    [
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">title</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token"> response</span><span class="token" style="color: #d73a49;">?.title a</span><span class="token" style="color: #d73a49;">s</span><span class="token"> </span><span class="token" style="color: #005cc5;">Any</span><span class="token">,
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">detail</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token"> response</span><span class="token" style="color: #d73a49;">?.detail </span><span class="token" style="color: #d73a49;">as</span><span class="token"> </span><span class="token" style="color: #005cc5;">Any</span><span class="token">,
</span></span><span class="line"><span class="token">    ]
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1193">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1194'
	>
	What to do with application crashes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1196">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1197'
	>
	Fail fast</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1199">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1200'
	>
	An application crash is usually the worst outcome our app users can experience, and we should do everything we can to prevent it. However, avoiding crashes is not something to be done at any cost. In some cases, we want to “fail fast” and use those crashes to find issues more effectively.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1204"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1202">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1203'
	>
	Generally speaking, when we can’t handle some condition in a meaningful way, we should expose it as an error to the user.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1207"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1205">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1206'
	>
	However, we are also limited by the programming language and the ecosystem we operate in. Sometimes we need more expressivity in the language to represent some concept.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1208">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1209'
	>
	Let’s look at the following example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1212"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">NamePicker</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #24292e;">let</span><span class="token"> </span><span class="token" style="color: #e36209;">names</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">John</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Josh</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Lucy</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Angela</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #24292e;">var</span><span class="token"> </span><span class="token" style="color: #e36209;">selectedName</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">String</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">init</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">selectedName</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">names</span><span class="token" style="color: #24292e;">.firs</span><span class="token">t</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1213">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1214'
	>
	In general, force unwrapping is a pattern that we would like to avoid. But in this case, making <code>init throwing</code> wouldn’t convey the right message and would pollute the code. It would require all upstream functions to be annotated with throws, which would obscure the true value of genuine errors.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1216">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1217'
	>
	Here is another example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1220"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> status </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">CVDisplayLinkCreateWithActiveCGDisplays(</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">link</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> link, status </span><span class="token" style="color: #d73a49;">==</span><span class="token"> kCVReturnSuccess </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">fatalError</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Could not create display link. Return status: </span><span class="token" style="color: #032f62;">\(</span><span class="token" style="color: #032f62;">status</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1221">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1222'
	>
	In this case, we believe that all preconditions for creating <code>CVDisplayLink</code> are fulfilled when this code is invoked. Therefore, instead of propagating optional <code>CVDisplayLink</code> through the codebase, we declare that this operation will crash the program, which allows us to catch holes in our assumptions quickly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1224">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1225'
	>
	The decision whether to crash, throw an error or return optional value needs to be made on a case-by-case basis. Here are some questions you should ask yourself to make this decision more easily:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1227">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1228'
	>
	<li>How likely is failure?</li><li>Does ignoring the failure lead to undefined behavior and even worse consequences, such as data loss?</li><li>Have you ensured preconditions to be true in other parts of the code?</li><li>Is there a reasonable default value you can provide in case of failure?</li><li>Would showing an error message to a user be better than crashing?</li><li>Is application security at risk in any given area of the code?</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1230">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1231'
	>
	If you want to explore this topic further, here are some good resources:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1233">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1234'
	>
	<li><a href="https://en.wikipedia.org/wiki/Fail-fast_system">https://en.wikipedia.org/wiki/Fail-fast_system</a></li><li><a href="https://en.wikipedia.org/wiki/Offensive_programming">https://en.wikipedia.org/wiki/Offensive_programming</a></li><li><a href="https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html">https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html</a></li><li><a href="https://www.martinfowler.com/ieeeSoftware/failFast.pdf">https://www.martinfowler.com/ieeeSoftware/failFast.pdf</a></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1236">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1237'
	>
	Additional crash logs</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1239">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1240'
	>
	Looking at the stack trace can very often lead us to a clear root cause of the crash and the conditions under which it happens. Unfortunately, this is not the case for all crashes, and any associated information might prove useful for investigating, understanding, reproducing, and fixing the crash.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1242">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1243'
	>
	We can abstract this idea into the following protocol:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1246"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">protocol CrashInfoLogger</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Sendable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func log</span><span class="token">(</span><span class="token">_ message</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1249"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1247">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1248'
	>
	And we can implement Firebase crash info logging:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class FirebaseCrashLogger</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">CrashLogger </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func log</span><span class="token">(</span><span class="token">_ message</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        Logger.</span><span class="token">app</span><span class="token">.</span><span class="token">log(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">\(</span><span class="token" style="color: #032f62;">message</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        Crashlytics.</span><span class="token">crashlytics(</span><span class="token">)</span><span class="token">.</span><span class="token">log(</span><span class="token">message</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1252">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1253'
	>
	And finally, we can provide a convenient extension for it:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1256"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Logger</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">let crashInfo:</span><span class="token"> CrashLogger </span><span class="token" style="color: #d73a49;">= Fir</span><span class="token">ebaseCrashLogger(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1259"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1257">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1258'
	>
	This way, we can log some key events during the program’s execution. If the app crashes, these key events will be associated with the crash report in Firebase.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1262"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1260">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1261'
	>
	Follow the trends</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1263">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1264'
	>
	Whether it is crashes or errors, some problems might never be reproducible in your local setup. For these kinds of issues, we often need to experiment with the fix.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1268"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1266">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1267'
	>
	In that case, we need some way of confirming if the fix helped or not. Firebase can provide valuable information about that. The following graph is an example of an issue that was fixed and confirmed by production data:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1273"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1271"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1272">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/04/Graph-1400x608.webp				media='(max-width: 699px)'
				type=image/webp								height="608"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2024/04/Graph-2400x1042.webp				media='(max-width: 1199px)'
				type=image/webp								height="1042"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2024/04/Graph.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1250"
															width="2880"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1282"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1277">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1276"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1274">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1278">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1279'
	>
	Firebase also provides a lot of valuable associated data. For example, this crash is only happening on iOS 15:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1283"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1284">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/04/Tabs-1400x853.webp				media='(max-width: 699px)'
				type=image/webp								height="853"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/04/Tabs.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1250"
															width="2052"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1318"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1289">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1286">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1290">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1291'
	>
	This is key information that can help us reproduce and fix the issue.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1293">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1294'
	>
	App Store Connect can also provide valuable information about your crash rate and how you compare to other apps in your category. It is important to monitor this trend and ensure it does not grow.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1296">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1297'
	>
	Legal considerations</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1299">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1300'
	>
	Beyond technical concerns, there are legal and regulatory aspects to consider with crash and error handling. For example, this includes data protection laws such as the General Data Protection Regulation (GDPR).&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1302">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1303'
	>
	Furthermore, it&#8217;s worth noting that some companies have strict policies prohibiting the transmission of any data to third parties, regardless of the circumstances. These policies may stem from privacy concerns, contractual obligations, or industry regulations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1305">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1306'
	>
	Logging errors or even crashes to third-party systems can have a legal impact on the product you are building, so always check with your legal department to see what you are allowed to do.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1308">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1309'
	>
	Be proactive about application errors and crashes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1313"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1311">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1312'
	>
	Even if we follow all the best practices and invest significant resources into this area, errors and crashes are almost impossible to avoid. Therefore, it is important to be upfront about the situation with your clients and have open discussions about it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1316"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1314">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1315'
	>
	It is more professional to inform your client that a new application version has introduced a crash than to have them come to you with a complaining user report.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1319"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1320">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/04/check-crashes.webp"
					class="image__img block-media__image-img"
					alt=""
										height="71"
															width="454"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1342"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1325">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1324"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1322">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1328"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1326">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1327'
	>
	Clients are generally not interested in individual crashes. Instead, you can set up a cadence where you check the status and inform your client in a public channel. This builds trust and understanding and allows you to handle issues professionally.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1331"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1329">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1330'
	>
	Reap the benefits of quality error handling</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1334"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1332">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1333'
	>
	Robust error handling requires intention and care, but it is fundamentally not difficult.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1337"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1335">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1336'
	>
	Following the best practices creates substantial benefits for your organization, including more effective debugging and issue resolution, a deeper understanding of user behavior, stronger client relationships, and more reliable applications.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1340"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1338">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1339'
	>
	We hope this guide has equipped you with the knowledge and tools to enhance your error and crash-handling strategies. Take action today to implement these practices and reap the benefits for your organization&#8217;s success.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/application-errors-best-practices/">Fix It Fast – Best Practices for Application Errors and Crashes</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>51141https://infinum.com/uploads/2024/03/Swift-Ownership-Borrow-consume-hero-min.webp</url>
				</image>
				<title>A Comprehensive Guide to Understanding Ownership in Swift</title>
				<link>https://infinum.com/blog/swift-ownership/</link>
				<pubDate>Wed, 27 Mar 2024 16:04:07 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=51141</guid>
				<description>
					<![CDATA[<p>We break down the complexity of Swift's ownership features so even beginner developers can learn how to use them.</p>
<p>The post <a href="https://infinum.com/blog/swift-ownership/">A Comprehensive Guide to Understanding Ownership in Swift</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1536"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1343">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1346"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1344">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-1345'
	>
	<strong>With the introduction of Swift 5.9 came new ownership features mostly reserved for advanced use cases. We break down the complexity so even beginner developers can learn how to use them.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1349"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1347">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1348'
	>
	<li><a href="https://infinum.com/blog/swift-ownership/#understanding-ownership"><strong>Understanding ownership</strong></a></li><li><strong><a href="https://infinum.com/blog/swift-ownership/#law-of-exclusivity">Law of exclusivity</a></strong></li><li><a href="https://infinum.com/blog/swift-ownership/#swift-ownership-system"><strong>Swift&#8217;s default ownership system</strong></a></li><li><strong><a href="https://infinum.com/blog/swift-ownership/#borrowing-consuming">Borrowing and consuming parameter modifiers</a></strong></li><li><strong><a href="https://infinum.com/blog/swift-ownership/#consume-operator">Consume operator</a></strong></li><li><strong><a href="https://infinum.com/blog/swift-ownership/#conclusion">Powerful and still beginner-friendly</a></strong></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1352"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1350">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1351'
	>
	When the <a href="https://github.com/apple/swift/commit/4c67c1d45b6f9649cc39bbb296d63663c1ef841f" target="_blank" rel="noreferrer noopener">Swift Ownership Manifesto</a> was initially published in 2017, it laid out a vision for making Swift a successful low-level programming language. By 2023 and the release of Swift 5.9, the work outlined in the manifesto was, for the good part, done. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1355"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1353">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1354'
	>
	Since the ownership features released in Swift 5.9 are focused on more advanced use cases, such as systems programming and performance tuning, we wanted to break them down to help developers get familiar with them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1358"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="understanding-ownership"></div>
	
			<div class="block-heading" data-id="es-1356">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1357'
	>
	Understanding ownership</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1363"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1359">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1360'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1361'
	>
	“<em>Ownership</em> is the responsibility of some piece of code to eventually cause a value to be destroyed. An <em>ownership system</em> is a set of rules or conventions for managing and transferring ownership.”</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1362'
	>
	<a href="https://github.com/apple/swift/blob/main/docs/OwnershipManifesto.md#">Swift Ownership Manifesto</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1366"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1364">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1365'
	>
	The concept of ownership in programming is not new. Every programming language incorporates some form of memory management. It can be manual, as in C, or automated, as it is in Swift. In manual memory management, allocated memory needs to be explicitly freed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1369"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1367">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1368'
	>
	However, it is not always obvious who is responsible for releasing the allocated memory. For example, let’s imagine the following C function:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1371"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-c github-light" data-language="c" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">void</span><span class="token"> </span><span class="token" style="color: #6f42c1;">process</span><span class="token">(</span><span class="token" style="color: #d73a49;">int</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #e36209;">array</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #d73a49;">int</span><span class="token"> </span><span class="token" style="color: #e36209;">count</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">int</span><span class="token"> i </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #b31d28;font-style: italic;">0</span><span class="token">; </span><span class="token" style="color: #b31d28;font-style: italic;">i</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token"> count</span><span class="token">;</span><span class="token"> i</span><span class="token" style="color: #d73a49;">++</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">    </span><span class="token" style="color: #6a737d;"> </span><span class="token" style="color: #6a737d;">   //</span><span class="token" style="color: #6a737d;"> do something
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1374"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1372">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1373'
	>
	This function receives a pointer to an array of integers and processes each of them. But in this case, it is not clear if the function should free the memory passed to it. The language lacks expressiveness to indicate this, so we need to rely on convention and documentation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1377"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1375">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1376'
	>
	Instead, if the function frees the memory, we could name it in such a way to indicate that:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1379"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-c github-light" data-language="c" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">void</span><span class="token"> </span><span class="token" style="color: #6f42c1;">process_and_free</span><span class="token">(</span><span class="token" style="color: #d73a49;">int</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #e36209;">array</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #d73a49;">int</span><span class="token"> </span><span class="token" style="color: #e36209;">count</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">int</span><span class="token"> i </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #b31d28;font-style: italic;">0</span><span class="token">; </span><span class="token" style="color: #b31d28;font-style: italic;">i</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token"> count</span><span class="token">;</span><span class="token"> i</span><span class="token" style="color: #d73a49;">++</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">    </span><span class="token" style="color: #6a737d;"> </span><span class="token" style="color: #6a737d;">   //</span><span class="token" style="color: #6a737d;"> do something
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">f</span><span class="token" style="color: #6f42c1;">ree</span><span class="token">(</span><span class="token">array</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1382"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1380">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1381'
	>
	The idea of ownership is not inherent to memory management; it applies to resources as well as frameworks. For example, the <a href="https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html" target="_blank" rel="noreferrer noopener">Memory Management Programming Guide for Core Foundation</a> lays out the ownership rules for the CoreFoundation framework in detail.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1385"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1383">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1384'
	>
	Before Swift 5.9, the ownership system was largely not exposed to the end user. Swift had a default set of ownership rules that worked well for the majority of use cases, freeing programmers from explicitly thinking about ownership.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1388"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1386">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1387'
	>
	Unfortunately, the only way to opt out of default ownership rules was to manage ownership manually, using a set of <code>Unsafe</code> APIs that require manual allocation and deallocation of memory. This is generally too low-level and error-prone.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1391"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1389">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1390'
	>
	The new Swift 5.9 features were released with the goal of giving programmers the tools to control ownership without sacrificing safety and ergonomics.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1394"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="law-of-exclusivity"></div>
	
			<div class="block-heading" data-id="es-1392">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1393'
	>
	Law of exclusivity</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1397"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1395">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1396'
	>
	<a href="https://github.com/apple/swift-evolution/blob/main/proposals/0176-enforce-exclusive-access-to-memory.md">Enforcement of exclusive access to memory</a>, more commonly referred to as the “Law of exclusivity,” comprises a set of rules that the compiler and runtime enforce to maintain <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/memorysafety/" target="_blank" rel="noreferrer noopener">memory safety</a>. It is the foundational feature for more advanced functionalities outlined in the Swift Ownership manifesto.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1400"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1398">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1399'
	>
	This feature was initially introduced with Swift 4, enforcing exclusivity only in Debug mode. Later, Swift 5 began to enforce exclusivity in Release mode as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1401">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1402'
	>
	<a href="https://forums.swift.org/t/review-se-0176-enforce-exclusive-access-to-memory/5836/11" target="_blank" rel="noreferrer noopener">The impact on typical programs is minimal</a>, as the conditions under which exclusivity violations occur are quite specific. Still, they can easily become relevant as program complexity grows.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1408"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1404">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1405'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1406'
	>
	To achieve memory safety, Swift requires exclusive access to a variable in order to<br />
modify that variable.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1407'
	>
	<a href="https://www.swift.org/blog/swift-5-exclusivity">Swift.org</a></div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1411"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1409">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1410'
	>
	Let’s look at an example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1413"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">var</span><span class="token"> x </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> global variable</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func addGlobalX</span><span class="token">(</span><span class="token">y</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    y </span><span class="token" style="color: #d73a49;">+= x
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">addGlobalX(</span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">x</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1416"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1414">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1415'
	>
	In this example, the <code>addGlobalX</code> function is called with the <code>inout</code> argument <code>x</code>, requiring exclusive access to variable <code>x</code> via parameter <code>y</code> for the duration of <code>addGlobalX</code>. However, since function <code>addGlobalX</code> accesses <code>x</code> directly, the exclusivity of the <code>inout</code> parameter <code>y</code> is violated.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1419"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1417">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1418'
	>
	If this seems contrived, it probably is. As we mentioned, the conditions under which exclusivity violation happens are quite specific.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1422"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1420">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1421'
	>
	Probably the most common example of code that was previously allowed but now violates exclusivity is the following:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1424"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">var</span><span class="token"> array </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [</span><span class="token" style="color: #005cc5;">1</span><span class="token">, </span><span class="token" style="color: #005cc5;">2</span><span class="token">, </span><span class="token" style="color: #005cc5;">3</span><span class="token">]
</span></span><span class="line"><span class="token" style="color: #005cc5;">swap</span><span class="token">(</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">array</span><span class="token">[</span><span class="token" style="color: #005cc5;">0</span><span class="token">]</span><span class="token">, </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">array</span><span class="token">[</span><span class="token" style="color: #005cc5;">1</span><span class="token">]</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1427"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1425">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1426'
	>
	As the compiler suggests, a simple solution to this problem is:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1429"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">var</span><span class="token"> array </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [</span><span class="token" style="color: #005cc5;">1</span><span class="token">, </span><span class="token" style="color: #005cc5;">2</span><span class="token">, </span><span class="token" style="color: #005cc5;">3</span><span class="token">]
</span></span><span class="line"><span class="token">array.</span><span class="token">swapAt(</span><span class="token" style="color: #005cc5;">0</span><span class="token">, </span><span class="token" style="color: #005cc5;">1</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1432"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1430">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1431'
	>
	This “workaround” was implemented as part of <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0173-swap-indices.md" target="_blank" rel="noreferrer noopener">SE-0173 Add MutableCollection.swapAt</a>. Apart from being more readable, it is required for legal reasons.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1435"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1433">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1434'
	>
	Why exclusivity enforcement is important</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1438"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1436">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1437'
	>
	You might be asking yourself, why does all of this matter in the first place?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1441"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1439">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1440'
	>
	As outlined in the <a href="https://www.swift.org/blog/swift-5-exclusivity/" target="_blank" rel="noreferrer noopener">Swift blog (Motivation chapter)</a>, there are various aspects to consider, but for this article, we will talk about two of them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1445"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1442">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1443'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-1444'
	>
	<strong>Enforcement legalizes performance optimization while protecting memory safety</strong></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1448"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1446">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1447'
	>
	Consider the following example of a contrived Swift function:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1450"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func addAndReset</span><span class="token">(</span><span class="token">x</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">y</span><span class="token">: </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">count</span><span class="token">: </span><span class="token" style="color: #005cc5;">Int</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> i </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> i &lt;</span><span class="token" style="color: #d73a49;"> cou</span><span class="token">nt </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        x </span><span class="token" style="color: #d73a49;">+= y
</span></span><span class="line"><span class="token">        i </span><span class="token" style="color: #d73a49;">+= 1
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    y </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1453"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1451">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1452'
	>
	To delve into this code further, we will use <a href="https://godbolt.org" target="_blank" rel="noreferrer noopener">Compiler Explorer</a>. Compiler Explorer is a powerful tool for understanding low-level code as it provides access to generated assembly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1456"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1454">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1455'
	>
	<strong>Note</strong>: Don’t be afraid of the assembly. In this article, we will annotate and shorten assembly snippets to make them concise and understandable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1459"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1457">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1458'
	>
	If we select the Swift 3 compiler, the generated assembly is:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1461"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">addAndReset(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">count:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    mov rax, qword ptr</span><span class="token"> </span><span class="token">[</span><span class="token">rdi</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Move x into register rax</span><span class="token">
</span></span><span class="line"><span class="token">.</span><span class="token">LBB1_2</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Loop</span><span class="token">
</span></span><span class="line"><span class="token">    add rax, qword ptr</span><span class="token"> </span><span class="token">[</span><span class="token">rsi</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Read memory pointed to by y and add to rax register</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1464"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1462">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1463'
	>
	On the other hand, the Swift 5.9 compiler emits the following assembly:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1466"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">adddAndReset(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #d73a49;">inout</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">, </span><span class="token">count:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    mov rax, qword ptr</span><span class="token"> </span><span class="token">[</span><span class="token">rdi</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Move x into register rax</span><span class="token">
</span></span><span class="line"><span class="token">    mov rcx, qword ptr</span><span class="token"> </span><span class="token">[</span><span class="token">rsi</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Move y into register rcx</span><span class="token">
</span></span><span class="line"><span class="token">.</span><span class="token">LBB1_2</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Loop</span><span class="token">
</span></span><span class="line"><span class="token">    add rax, rcx </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Add contents of register rcx to rax</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1469"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1467">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1468'
	>
	Here, we can observe a clear difference:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1471"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-1470'
	>
	<strong>Without the assumption of exclusivity, every loop iteration needs to read the value from the memory location instead of using a register.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1474"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1472">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1473'
	>
	The reason for this is that the compiler is not allowed to assume that <em>x</em> and <em>y</em> are not the same variable, as is the case if you call this function in the following way:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1476"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">var</span><span class="token"> x </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">addAndReset(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">x</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">x</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1479"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1477">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1478'
	>
	This requires the compiler to be conservative and limits optimization opportunities. In Swift 5.9, this code is not allowed and is rejected by the compiler.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1482"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1480">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1481'
	>
	This issue is not specific to Swift. Consider an equivalent C code snippet:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1484"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">void </span><span class="token">add_and_reset(</span><span class="token">int </span><span class="token" style="color: #d73a49;">*</span><span class="token">x</span><span class="token">, </span><span class="token">int </span><span class="token" style="color: #d73a49;">*</span><span class="token">y</span><span class="token">, </span><span class="token">int count</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    int i </span><span class="token" style="color: #d73a49;">= cou</span><span class="token">nt;
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> (i </span><span class="token" style="color: #d73a49;">&gt; 0) </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">*x = *x +</span><span class="token" style="color: #d73a49;"> *y</span><span class="token" style="color: #d73a49;">;
</span></span><span class="line"><span class="token">        i</span><span class="token" style="color: #d73a49;">++;
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    y </span><span class="token" style="color: #d73a49;">= 0;
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1487"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1485">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1486'
	>
	This code sample suffers from the same issue – every loop iteration reads the memory location of <em><code>y</code></em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1490"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1488">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1489'
	>
	The solution to this problem in C is to use the <a href="https://en.wikipedia.org/wiki/Restrict" target="_blank" rel="noreferrer noopener">restrict keyword</a>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1492"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">void </span><span class="token">add_and_reset(</span><span class="token">int </span><span class="token" style="color: #d73a49;">*</span><span class="token">restrict x</span><span class="token">, </span><span class="token">int </span><span class="token" style="color: #d73a49;">*</span><span class="token">restrict y</span><span class="token">, </span><span class="token">int count</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1495"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1493">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1494'
	>
	However, in C, nothing is preventing us from calling this function with the same pointer. Swift is much more powerful in this regard.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1499"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-1496">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-1497'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-1498'
	>
	<strong><strong>Exclusivity rules are needed to give the programmer control of ownership and move-only type</strong></strong></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1502"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1500">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1501'
	>
	In a very simplistic model, calling a function in Swift with an argument of a value type will copy the contents of that value type onto the stack.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1505"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1503">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1504'
	>
	When that argument is not modified, it could be possible to avoid copying and providing direct access to the original storage location. If Swift aims to support such a construct of “shared” value, that value must remain valid during the entire function call. Allowing other code to interact with the same storage location simultaneously would require the compiler to copy the value to avoid undefined behavior. This defeats the purpose of the idea of “shared”.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1508"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1506">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1507'
	>
	Dynamic enforcement performance considerations</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1511"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1509">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1510'
	>
	When the compiler can check exclusiveness statically, it will do so. However, in some situations, this is not practical. Class properties use dynamic enforcement, meaning the program needs to track active access to a property dynamically.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1514"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1512">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1513'
	>
	Let’s examine this simple Swift class:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1516"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class X</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var y:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1519"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1517">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1518'
	>
	If we inspect the generated assembly code, we can see the generated setter and getter for <code>y</code>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">output.</span><span class="token">X</span><span class="token">.</span><span class="token">y</span><span class="token">.</span><span class="token">getter</span><span class="token"> </span><span class="token" style="color: #d73a49;">:</span><span class="token"> Swift.</span><span class="token" style="color: #005cc5;">Int</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    call swift_beginAccess</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span><span class="line"><span class="token">    call swift_endAccess</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">output.</span><span class="token">X</span><span class="token">.</span><span class="token">y</span><span class="token">.</span><span class="token">setter</span><span class="token"> </span><span class="token" style="color: #d73a49;">:</span><span class="token"> Swift.</span><span class="token" style="color: #005cc5;">Int</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    call swift_beginAccess</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span><span class="line"><span class="token">    call swift_endAccess</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1522">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1523'
	>
	And we can see that they are wrapped in <code>swift_beginAccess</code> and <code>swift_endAccess</code>. This would certainly have some performance impact on accessing the variable and can be disabled by:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1526"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class X</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@exclusivity</span><span class="token">(</span><span class="token">unchecked</span><span class="token">)</span><span class="token"> </span><span class="token">var y:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token" style="color: #d73a49;">= 0
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1529"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1527">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1528'
	>
	To understand the impact of this, we will use <a href="https://github.com/ordo-one/package-benchmark" target="_blank" rel="noreferrer noopener">Package Benchmark</a>. Package Benchmark is an excellent Swift package that allows us to output many statistics in a user-friendly way. You can run benchmarks from the <a href="https://github.com/infinum/iOS-Swift-Ownership">associated sample code</a> by executing the following command:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1531"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">swift </span><span class="token" style="color: #d73a49;">package</span><span class="token"> benchmark </span><span class="token" style="color: #d73a49;">--</span><span class="token">target ExclusivityCheck </span><span class="token" style="color: #d73a49;">--</span><span class="token">scale
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1534"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1532">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1533'
	>
	The following chart shows the overhead of exclusivity checking when accessing class property:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1537"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1538">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/03/Graph_1-1400x735.webp				media='(max-width: 699px)'
				type=image/webp								height="735"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/03/Graph_1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1260"
															width="2400"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1623"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1540">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1543"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="swift-ownership-system"></div>
	
			<div class="block-heading" data-id="es-1541">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1542'
	>
	Swift’s default ownership system</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1546"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1544">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1545'
	>
	Before diving into the details of Swift&#8217;s default ownership system, let’s clarify what ownership means for value types compared to reference types:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1549"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1547">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1548'
	>
	<li>To take ownership of a value type, we need to copy it</li><li>To take ownership of a reference type, we need to increase its reference count</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1552"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1550">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1551'
	>
	Before Swift 5.9, there was no way to control ownership of parameters passed to functions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1555"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1553">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1554'
	>
	Instead, Swift’s default argument passing semantics were as follows:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1558"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1556">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1557'
	>
	<li>Initializers <strong>take</strong> ownership of parameters passed to them</li><li>Functions <strong>do not take</strong> ownership of parameters passed to them</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1561"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1559">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1560'
	>
	But what does this mean in practice? Let’s explore a small example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1563"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class B</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class A</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">init(x: </span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> b </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">B(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> a </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">A(</span><span class="token">x:</span><span class="token"> b</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1566"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1564">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1565'
	>
	Looking at the assembly code generated by the compiler in Godbolt, we observe the following:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1568"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">main</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span><span class="line"><span class="token">    call swift_retain</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">call (</span><span class="token">output.</span><span class="token">A</span><span class="token">.</span><span class="token">__allocating_init(</span><span class="token">x:</span><span class="token"> output.</span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt; out</span><span class="token">put.</span><span class="token">A</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1571"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1569">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1570'
	>
	We can see that before calling <code>A.init</code>, the compiler inserts a retain. The reason is that, by default, initializers are taking ownership of their arguments, and to do so, they need to be passed with a +1 retain count.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1574"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1572">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1573'
	>
	On the other hand, this short code snippet:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1576"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">B</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">A</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">f</span><span class="token">(</span><span class="token" style="color: #6f42c1;">x</span><span class="token">: </span><span class="token" style="color: #005cc5;">B</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">let</span><span class="token"> </span><span class="token" style="color: #005cc5;">b</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">B</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">let</span><span class="token"> </span><span class="token" style="color: #005cc5;">a</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">A</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">a</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">f</span><span class="token">(</span><span class="token" style="color: #6f42c1;">x</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">b</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1579"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1577">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1578'
	>
	compiles to:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1581"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">main</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span><span class="line"><span class="token">    </span><span class="token">call (</span><span class="token">output.</span><span class="token">A</span><span class="token">.</span><span class="token">f(</span><span class="token">x:</span><span class="token"> output.</span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt; ())</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1584"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1582">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1583'
	>
	We can see that there is no retain before calling <code>A.f</code>. That is because, by default, functions do not take ownership of their arguments.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1587"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1585">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1586'
	>
	But what if a function needs ownership of an argument? For example, in this case:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class B</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class A</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">var b:</span><span class="token"> B</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func f</span><span class="token">(</span><span class="token">x</span><span class="token">: </span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">b</span><span class="token"> </span><span class="token" style="color: #d73a49;">= x
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> b </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">B(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> a </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">A(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">a.</span><span class="token">f(</span><span class="token">x:</span><span class="token"> b</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1592"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1590">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1591'
	>
	In this case, the function will retain the argument:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1594"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">output.</span><span class="token">A</span><span class="token">.</span><span class="token">f(</span><span class="token">x:</span><span class="token"> output.</span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">...
</span></span><span class="line"><span class="token">    call swift_retain</span><span class="token" style="color: #d73a49;">@PLT</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> store into self</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1597"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1595">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1596'
	>
	You might wonder why initializers are not borrowing as well. The reasoning would be – if an initializer doesn’t need ownership of an argument, we avoid the extra retain. If it needs it, it can retain it in the same way as functions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1600"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1598">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1599'
	>
	To understand this, let’s look at this example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1602"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class B</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> </span><span class="token">class A</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">var b:</span><span class="token"> B</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">init(x: </span><span class="token">B</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">b</span><span class="token"> </span><span class="token" style="color: #d73a49;">= x
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> b </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">B(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> a </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">A(</span><span class="token">x:</span><span class="token"> b</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1605"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1603">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1604'
	>
	In this example, when we initialize <code>b</code><em>, </em>it is automatically retained. However, pay attention that <code>b</code><em> </em>is not used anymore. So we create <code>b</code> just to pass it to <code>A.init</code>. In this case, <code>b</code> can pass ownership to <code>A.init</code><em>,</em> and no extra retain needs to be emitted.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-1606'
	>
	<strong>Swift has made some choices for its default ownership system that, in practice, offer a good trade-off for most common use cases.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1608">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1609'
	>
	Performance impact of reference counting</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1613"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1611">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1612'
	>
	To get a better understanding of why these choices are important, we will examine a performance benchmark that measures the impact of the retain operation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1616"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1614">
	<h4	class='typography typography--size-30-text js-typography block-heading__heading'
	data-id='es-1615'
	>
	Retain release</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1619"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1617">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1618'
	>
	You can run this performance benchmark by executing:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1621"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">swift</span><span class="token"> </span><span class="token" style="color: #005cc5;">package</span><span class="token"> </span><span class="token" style="color: #005cc5;">benchmark</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">target</span><span class="token"> </span><span class="token" style="color: #005cc5;">Retain</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">scale</span><span class="token">
</span></span></code></pre></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1626"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1624"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1625">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/03/Graph_2-1-1400x735.webp				media='(max-width: 699px)'
				type=image/webp								height="735"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/03/Graph_2-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1260"
															width="2400"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1666"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1627">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1630"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1628">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1629'
	>
	Keep in mind that this only demonstrates the performance impact of retain. When we retain an object, we usually need to release it, making the impact even more significant.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1633"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="borrowing-consuming"></div>
	
			<div class="block-heading" data-id="es-1631">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1632'
	>
	Borrowing and consuming parameter modifiers</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1636"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1634">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1635'
	>
	<a href="https://github.com/apple/swift-evolution/blob/main/proposals/0377-parameter-ownership-modifiers.md" target="_blank" rel="noreferrer noopener">SE-0377</a> introduced new function parameter modifiers: <code>borrowing</code> and <code>consuming</code>. Syntactically, they are used in the same position as <code>inout</code> and are mutually exclusive with it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1639"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1637">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1638'
	>
	Semantically, the low-level meaning of these operations can be summarized in the following table:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1642"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-1641>
	
<div
	class="wrapper"
	data-id="es-1640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><tbody><tr><td><strong>Modifier</strong></td><td><strong>Caller</strong></td><td><strong>Callee</strong></td></tr><tr><td><strong>borrowing</strong></td><td>Remains owner of original value.<br><br>No need to copy or retain value.<br><br>Responsible for keeping it alive for the duration of the callee.</td><td>No need for a release.<br><br>No implicit copying allowed.<br><br>Explicit copying is required with a copy operator.</td></tr><tr><td><strong>consuming</strong></td><td>It can either give ownership of the original value to the callee OR retain or copy the value if it requires ownership of its own value.</td><td>Required to release the value.</td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1645"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1643">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1644'
	>
	To understand the performance impact of these annotations, we will actively work against Swift’s default ownership system. This means:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1648"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1646">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1647'
	>
	<li>Using the <code>init</code> parameter in a borrowing way</li><li>Using the function parameter in a consuming way</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1651"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1649">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1650'
	>
	Borrowing init</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1654"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1652">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1653'
	>
	Let’s consider the following example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1656"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class BorrowingInit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">let first:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token">
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">init(tes</span><span class="token">t</span><span class="token">: </span><span class="token">Test</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        first </span><span class="token" style="color: #d73a49;">= test.x
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">init(bor</span><span class="token">rowingTest</span><span class="token">: </span><span class="token" style="color: #d73a49;">borrowing</span><span class="token"> Test</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        first </span><span class="token" style="color: #d73a49;">= borrowi</span><span class="token">ngTest.</span><span class="token">x</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1659"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1657">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1658'
	>
	What is the performance difference between calling <code>init(test:)</code> and <code>init(borrowingTest:)</code>? </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1662"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1660">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1661'
	>
	You can run the performance benchmark for this example by executing:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1664"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">swift </span><span class="token" style="color: #d73a49;">package</span><span class="token"> benchmark </span><span class="token" style="color: #d73a49;">--</span><span class="token">target BorrowingInit </span><span class="token" style="color: #d73a49;">--</span><span class="token">scale
</span></span></code></pre></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1669"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1667"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1668">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/03/Graph_4-1400x735.webp				media='(max-width: 699px)'
				type=image/webp								height="735"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/03/Graph_4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1260"
															width="2400"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1688"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1670">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1673"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1671">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1672'
	>
	Consuming function</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1676"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1674">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1675'
	>
	Let’s consider the following example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1678"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class ConsumingFunc</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">var test:</span><span class="token"> Test</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">init() {</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func assignTest</span><span class="token">(</span><span class="token">consumingTest</span><span class="token">: </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> Test</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">test</span><span class="token"> </span><span class="token" style="color: #d73a49;">= consumi</span><span class="token">ngTest
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func assignTest</span><span class="token">(</span><span class="token">test</span><span class="token">: </span><span class="token">Test</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">test</span><span class="token"> </span><span class="token" style="color: #d73a49;">= test
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1681"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1679">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1680'
	>
	What is the performance difference of calling <code>assignTest(test:)</code> vs <code>assignTest(consumingTest:)</code>?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1684"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1682">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1683'
	>
	You can run this benchmark by executing:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1686"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">swift </span><span class="token" style="color: #d73a49;">package</span><span class="token"> benchmark </span><span class="token" style="color: #d73a49;">--</span><span class="token">target ConsumingFunction </span><span class="token" style="color: #d73a49;">--</span><span class="token">scale
</span></span></code></pre></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1689"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1690">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/03/Graph_5-1400x735.webp				media='(max-width: 699px)'
				type=image/webp								height="735"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/03/Graph_5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1260"
															width="2400"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1733"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1692">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1695"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1693">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1694'
	>
	Compiler optimizations</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1698"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1696">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1697'
	>
	Even without annotating parameters such as borrowing, the compiler can sometimes have visibility that the initializer borrows the argument and can optimize away unnecessary ARC traffic. For compiler optimization tips and tricks, check out <a href="https://github.com/apple/swift/blob/main/docs/OptimizationTips.rst" target="_blank" rel="noreferrer noopener">this document</a>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1701"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1699">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1700'
	>
	However, compiler optimizations depend on the optimization mode, code structure, and other factors that are not always in our control. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1704"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1702">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1703'
	>
	For performance-critical code, we want <strong>guaranteed predictable</strong> behavior, which the new parameter modifiers provide.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1707"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="consume-operator"></div>
	
			<div class="block-heading" data-id="es-1705">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1706'
	>
	Consume operator</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1710"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1708">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1709'
	>
	Introduced in <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0366-move-function.md" target="_blank" rel="noreferrer noopener">SE-0366</a>, the consume operator allows us to end the lifetime of a variable. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1713"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1711">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1712'
	>
	For example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1715"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class X</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> x </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">X(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">consume</span><span class="token"> x
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1718"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1716">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1717'
	>
	After we consume <code>x</code><em>, </em>the<em> </em>attempt to use it will throw a compiler error “x used after consume.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1721"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1719">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1720'
	>
	This is great for passing ownership of local variables explicitly to the initializer and works well with its <code>consuming</code> counterpart.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1724"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1722">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1723'
	>
	For example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1726"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class X</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">class Y</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">init(x: </span><span class="token" style="color: #d73a49;">consuming</span><span class="token"> X</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> x </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">X(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> y </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Y(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #d73a49;">consume</span><span class="token"> x</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1729"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1727">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1728'
	>
	The performance implications of this are shown in the chart below, but you can run this benchmark by executing:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1731"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">swift </span><span class="token" style="color: #d73a49;">package</span><span class="token"> benchmark </span><span class="token" style="color: #d73a49;">--</span><span class="token">target ConsumeOperator </span><span class="token" style="color: #d73a49;">--</span><span class="token">scale
</span></span></code></pre></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1736"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1734"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1735">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2024/03/Graph_6-1400x735.webp				media='(max-width: 699px)'
				type=image/webp								height="735"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2024/03/Graph_6.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1260"
															width="2400"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1757"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1737">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1740"
	 data-animation='slideFade' data-animation-target='inner-items'>
				<div class="wrapper__anchor" id="conclusion"></div>
	
			<div class="block-heading" data-id="es-1738">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1739'
	>
	Powerful and still beginner-friendly</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1743"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1741">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1742'
	>
	While the new borrowing and consuming modifiers can be considered “advanced” features, understanding them at a basic level provides a better insight into how the Swift compiler and optimizer work. It is also critical to understand them for writing low-level code without sacrificing the type safety provided by Swift.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1746"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1744">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1745'
	>
	However, even with these new “advanced” features, Swift remains a beginner-friendly language. As nicely summarized in <a href="https://forums.swift.org/t/a-roadmap-for-improving-swift-performance-predictability-arc-improvements-and-ownership-control/54206" target="_blank" rel="noreferrer noopener">A roadmap for improving Swift performance predictability</a>, “we want these features to fit within the &#8220;progressive disclosure&#8221; ethos of Swift.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1749"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1747">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1748'
	>
	The <a href="https://github.com/apple/swift/blob/main/docs/OwnershipManifesto.md#criteria-for-success" target="_blank" rel="noreferrer noopener">Ownership Manifesto</a> confirms a similar approach:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1752"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1750">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1751'
	>
	<em>“It is the core team&#8217;s expectation that ownership can be delivered as an opt-in enhancement to Swift. Programmers should be able to largely ignore ownership and not suffer for it. If this expectation proves to not be satisfiable, we will reject ownership rather than imposing substantial burdens on regular programs.”</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1755"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1753">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1754'
	>
	You can find the associated source code <a href="https://github.com/infinum/iOS-Swift-Ownership/">here</a>. </p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/swift-ownership/">A Comprehensive Guide to Understanding Ownership in Swift</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>39797https://infinum.com/uploads/2023/07/Au-Sampler-part3-hero-img-min.webp</url>
				</image>
				<title>Uncovering the Secrets of AUSampler’s Missing Documentation</title>
				<link>https://infinum.com/blog/ausampler-missing-documentation/</link>
				<pubDate>Thu, 06 Jul 2023 08:48:53 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=39797</guid>
				<description>
					<![CDATA[<p>We explain the ways of controlling Apple’s AUSampler and discover its hidden secrets – the essential features missing from the official documentation.</p>
<p>The post <a href="https://infinum.com/blog/ausampler-missing-documentation/">Uncovering the Secrets of AUSampler’s Missing Documentation</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1801"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1758">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1761"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1759">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-1760'
	>
	We explain the different ways of controlling Apple’s AUSampler and discover its hidden secrets – the essential features that didn’t make it into the documentation. Find out what they do and how to use them. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1764"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1762">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1763'
	>
	Developer documentation is an area in which Apple has recently made significant improvements. However, when it comes to audio documentation, some challenges persist, particularly for beginners. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1767"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1765">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1766'
	>
	A prime example of this is the case of AUSampler.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1770"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1768">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1769'
	>
	In the first two parts of this blog series, <a href="https://infinum.com/blog/getting-started-with-au-sampler/" target="_blank" rel="noreferrer noopener">Exploring AU Sampler – Apple’s Mysterious Sampler Audio Unit</a> and <a href="https://infinum.com/blog/au-sampler-dynamic-chain-changes/" target="_blank" rel="noreferrer noopener">Can AU Sampler Survive Dynamic Chain Changes?</a>, we delved into some of AUSampler&#8217;s secrets. In this blog post, we aim to provide a comprehensive alternative for the missing AUSampler documentation. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1773"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1771">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1772'
	>
	But, before we proceed, let&#8217;s take a step back and explore the various ways in which AUSampler can be controlled.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1776"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1774">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1775'
	>
	Designing an instrument for AUSampler</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1779"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1777">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1778'
	>
	Apple frameworks offer various ways to utilize AUSampler. One of the simplest ways to start is by using a combination of <code>AVAudioEngine</code> and <code>AVAudioUnitSampler</code>. The very first problem that we need to solve here is to design an instrument that AVAudioSampler can understand, effectively outputting sound for the notes played.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1782"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1780">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1781'
	>
	AUSampler&#8217;s native instrument format is expressed in an <a href="https://help.ableton.com/hc/en-us/articles/209775145-AU-preset-handling" target="_blank" rel="noreferrer noopener">AUPreset file</a>, which is a standard <a href="https://en.wikipedia.org/wiki/Property_list" target="_blank" rel="noreferrer noopener">property list file</a> with a structure understood by each Audio Unit. Unlike some Audio Units with straightforward plist structures, AUSampler&#8217;s configuration is quite complex.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1785"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1783">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1784'
	>
	Instrument hierarchy and various options and keys were discussed in detail in Session 411 at WWDC 2011 (Music in iOS and Lion), unfortunately no longer available in Apple’s archive. In this article, we will take a brief look at the high-level workflow.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1788"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1786">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1787'
	>
	AU Lab AUSampler workflow</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1793"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1789">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1790'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-24-text js-typography blockquote__quote'
	data-id='es-1791'
	>
	AU Lab is a digital mixing application that provides facilities for blending audio from the input of an audio device as well as audio generated by an Audio Unit Instrument or Generator. In addition, AU Lab can host Audio Unit effects and route audio through these effects.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1792'
	>
	AU Lab 2.3 Documentation</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1796"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1794">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1795'
	>
	Due to the complexity of AUSampler’s instrument format, it is almost impossible to configure it manually. This is why AU Lab has emerged as the go-to tool for creating and editing AUSampler instruments. Packaged with the Additional Tools For Xcode, AU Lab can be downloaded on the Apple Developer website.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1799"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1797">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1798'
	>
	Once we install it, we can add an instance of AUSampler through the <em>Edit <em>→</em> Add Audio Unit Instrument <em>→</em> AUSampler </em>menu. This action will present a custom AUSampler view, allowing users to modify various instrument properties. Once satisfied with the configuration, the preset can be exported for further use.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1804"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1802"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1803">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/07/image1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="685"
															width="839"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1816"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1808">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1807"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1805">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1811"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1809">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1810'
	>
	​Saved presets are stored in a specific location. To access them, go to: <em>~/Library/Audio/Presets/Apple/AUSampler</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1814"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1812">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1813'
	>
	However, you can also easily navigate to them within AU Lab by pressing CMD+P, selecting a preset, and choosing &#8216;Show in Finder&#8217; from the menu.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1819"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1817"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1818">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/07/image4-1400x938.webp				media='(max-width: 699px)'
				type=image/webp								height="938"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/07/image4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1339"
															width="1999"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1862"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1823">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1822"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1820">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1826"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1824">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1825'
	>
	The default AUSampler property list files are more than 300 lines long! Here is an example of a preset’s high-level structure with irrelevant details removed: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1828"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Instrument</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Layers</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Amplifier</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Connections</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Envelopes</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Filters</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">LFOs</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Oscillator</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Zones</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">array</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">name</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">string</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">Default Instrument</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">string</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">fine tune</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #005cc5;">0.0</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">gain</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #005cc5;">0.0</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">pan</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #005cc5;">0.0</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">real</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">voice count</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">key</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">integer</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #005cc5;">64</span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">integer</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">dict</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1831"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1829">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1830'
	>
	Once you have obtained the AUPreset file, you can proceed to load it into <code>AVAudioUnitSampler</code>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1833"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">open</span><span class="token"> </span><span class="token" style="color: #005cc5;">func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">loadPreset</span><span class="token">(</span><span class="token" style="color: #005cc5;">at</span><span class="token"> </span><span class="token" style="color: #005cc5;">url</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">URL</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">throws</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1836"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1834">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1835'
	>
	This allows you to integrate the customized instrument into your audio app and take advantage of the rich capabilities offered by AUSampler.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1839"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1837">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1838'
	>
	Enabling a dynamic experience with AUSampler</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1842"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1840">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1841'
	>
	While AUPreset files allow us to statically configure the sampler, music apps are more fun and enjoyable when they are interactive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1845"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1843">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1844'
	>
	We would like to allow performers to play notes and adjust their instrument parameters in real-time. This dynamic experience allows them to receive immediate feedback and enhance their creativity.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1848"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1846">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1847'
	>
	How can we achieve such a dynamic experience?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1851"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1849">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1850'
	>
	Controlling AUSampler using Connections</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1854"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1852">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1853'
	>
	In the context of AUSampler, connections provide a powerful mechanism to map source events to destination events, allowing for real-time updates and control. When we add an instrument in AU Lab or any other compatible environment, a default set of connections is automatically created.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1857"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1855">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1856'
	>
	Let&#8217;s take a specific example to illustrate the concept of connections. One common connection is the &#8216;Key Velocity&#8217; connection, which maps the velocity of the pressed key to the gain of a specific layer in the instrument. In simpler terms, when a performer hits a note with more force or velocity, it will cause a louder sound to be produced.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1860"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1858">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1859'
	>
	By establishing this connection, we can create a more expressive and nuanced playing experience.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1865"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1863"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1864">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/07/image5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="685"
															width="839"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1874"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1869">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1868"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1866">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1872"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1870">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1871'
	>
	Similarly, we can set up a &#8216;Gain&#8217; connection, where the expression pedal controls the gain, or volume level, of the played notes:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1877"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1875"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1876">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/07/image2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="685"
															width="839"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1983"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1881">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1880"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1878">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1884"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1882">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1883'
	>
	Let’s break down the structure of a connection:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1887"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1885">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1886'
	>
	<li><strong>Name</strong> &#8211; The name of the connection. It helps users identify the specific connection within the system.</li><li><strong>Layer</strong> &#8211; A layer can contain multiple connections, and each connection belongs to a specific layer. This helps in organizing and separating different sound sources, effects, or parameters that are being controlled.</li><li><strong>Source</strong> &#8211; A source event that initiates or triggers the connection. This can be a range of things such as MIDI note on/off, controller input, or another parameter change.</li><li><strong>Destination</strong> &#8211; The destination is the parameter that the source event influences. For instance, the source event may be a MIDI note-on event, and the destination could be the pitch of a note or the volume of a sound.</li><li><strong>Via</strong> &#8211; The &#8220;Via&#8221; parameter often represents an intermediate control that the original source event has to pass through before it reaches its destination. It can be used to add additional control to the connection. For instance, the &#8216;Via&#8217; parameter can be used to have a modulation wheel alter the effect of a key velocity-to-volume connection.</li><li><strong>Invert</strong> &#8211; This allows the control direction to be reversed. In an inverted connection, high source values result in low destination values, and vice versa.</li><li><strong>Transform</strong> &#8211; This determines the shape of the control curve (Linear, Convex, Concave, or Switch).</li><li><strong>Min Max</strong> &#8211; This controls the range of the destination parameter that the source can influence. &#8220;Min&#8221; is the value when the source is at its lowest, and &#8220;Max&#8221; is the value when the source is at its highest.</li><li><strong>Bipolar</strong> &#8211; A &#8220;Bipolar&#8221; parameter is one that has a center value, with both positive and negative deviations from this center value. This is often used with parameters like pitch bend or modulation, where the center value represents no change, and movements away from the center cause an increase or a decrease in the parameter.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1890"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1888">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1889'
	>
	Connections are a great and user-friendly way to set up a dynamic experience. Unfortunately, they only support a limited number of parameters that AUSampler exposes. Additionally, some of them simply don’t work.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1893"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1891">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1892'
	>
	Controlling AUSampler by updating in memory state</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1896"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1894">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1895'
	>
	One useful feature of AudioUnit is its ability to load and export presets using AUPreset files. This functionality allows users to create and save their preferred configurations, making it convenient to switch between presets based on different situations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1899"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1897">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1898'
	>
	When an <code>AUAudioUnit</code> is loaded with an AUPreset file, the state is stored in the<a href="https://developer.apple.com/documentation/audiotoolbox/auaudiounit/1387500-fullstate" target="_blank" rel="noreferrer noopener"> <strong>fullState</strong> property</a>. Any changes made to the configuration are reflected in this property as well. By dumping the contents of the <code>fullState</code> property into a new AUPreset file, users can save and load their customized settings at a later time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1902"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1900">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1901'
	>
	We can use this to our advantage and dynamically modify the <code>fullState</code> property.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1905"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1903">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1904'
	>
	For example, if we want to control the resonance of the sampler, we can utilize the following approach:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1907"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func setResonanceAUPreset</span><span class="token">(</span><span class="token">value</span><span class="token">: </span><span class="token" style="color: #005cc5;">Float</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> instrument </span><span class="token" style="color: #d73a49;">= auA</span><span class="token">udioUnit.</span><span class="token">fullState</span><span class="token" style="color: #d73a49;">![&quot;In</span><span class="token" style="color: #032f62;">strument</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">as!</span><span class="token"> NSDictionary
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> layers </span><span class="token" style="color: #d73a49;">= ins</span><span class="token">trument</span><span class="token">[</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Layers</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">as!</span><span class="token"> NSArray
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> layer </span><span class="token" style="color: #d73a49;">= lay</span><span class="token">ers.</span><span class="token">firstObject</span><span class="token"> </span><span class="token" style="color: #d73a49;">as!</span><span class="token"> NSDictionary
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> filters </span><span class="token" style="color: #d73a49;">= lay</span><span class="token">er</span><span class="token">[</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Filters</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">as!</span><span class="token"> NSDictionary
</span></span><span class="line"><span class="token">    filters.</span><span class="token">setValue(</span><span class="token">value</span><span class="token">, </span><span class="token">forKeyPath:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">resonance</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    auAudioUnit.</span><span class="token">fullState</span><span class="token" style="color: #d73a49;">?[&quot;In</span><span class="token" style="color: #032f62;">strument</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">= ins</span><span class="token">trument
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1910"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1908">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1909'
	>
	This method provides great versatility by allowing us to update any aspect of the sampler dynamically. It&#8217;s important to note that such modifications will require the sampler to reload its state, which will result in a momentary interruption in the sound output.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1913"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1911">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1912'
	>
	Controlling AUSampler by updating hidden properties</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1916"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1914">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1915'
	>
	However, there is another approach that can be considered to be the most powerful. You might have noticed that the AUSampler custom view allows you to control sampler properties in real time. Taking our example of resonance, the resonance knob functions flawlessly in AUSampler custom view. We can play notes, and the resonance is updated instantaneously without any interruption in the sound output.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1919"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1917">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1918'
	>
	Can we somehow achieve the same effect, even when not in custom view?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1922"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1920">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1921'
	>
	In the <a href="https://infinum.com/blog/getting-started-with-au-sampler/" target="_blank" rel="noreferrer noopener">first blog post</a> of this series, we explored how to query the hidden Voice Count property by hooking into <code>AudioUnitGetProperty</code>. In our case, we need to go in the opposite direction and hook into <code>AudioUnitSetProperty</code> instead:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1925"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1923">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1924'
	>
	Intel:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1927"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">rb</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">AudioUnitSetProperty$</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">command</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">po </span><span class="token" style="color: #032f62;">$</span><span class="token" style="color: #24292e;">rsi</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">auto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">continue</span><span class="token" style="color: #005cc5;"> 1</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1930"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1928">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1929'
	>
	ARM:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1932"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">rb</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">AudioUnitSetProperty$</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">command</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">po </span><span class="token" style="color: #032f62;">$</span><span class="token" style="color: #24292e;">x1</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">auto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">continue</span><span class="token" style="color: #005cc5;"> 1</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1935"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1933">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1934'
	>
	This approach will provide us with the secret property ID (4162) that enables us to control the resonance property without any audio interruptions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1938"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1936">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1937'
	>
	The missing AUSampler documentation</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1941"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1939">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1940'
	>
	There is barely any mention of AUSampler property IDs in the <a href="https://developer.apple.com/documentation/audiotoolbox/1534086-ausampler_property_ids" target="_blank" rel="noreferrer noopener">Apple documentation</a>. This is unfortunate because, as it turns out, following our approach of finding the property ID for resonance control, we can find a lot more powerful properties. But one more aspect of <a href="https://developer.apple.com/documentation/audiotoolbox/1440371-audiounitsetproperty" target="_blank" rel="noreferrer noopener">AudioUnitSetProperty</a> remains unclear – <code>inElement</code>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1944"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1942">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1943'
	>
	The documentation simply describes it as:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1946"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">The</span><span class="token"> </span><span class="token" style="color: #005cc5;">audio</span><span class="token"> </span><span class="token" style="color: #005cc5;">unit</span><span class="token"> </span><span class="token" style="color: #005cc5;">element</span><span class="token"> </span><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token" style="color: #005cc5;">the</span><span class="token"> </span><span class="token" style="color: #005cc5;">property</span><span class="token" style="color: #d73a49;">.</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1949"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1947">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1948'
	>
	For global properties, <code>inElement</code> is always zero, but how can we distinguish between resonance for Layer 1 and Layer 2?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1952"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1950">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1951'
	>
	There is a convention that AUSampler uses: every layer item has its base element ID, which increases by 0x00000100 for subsequent layers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1955"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1953">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1954'
	>
	<strong>LFO</strong> &#8211; 0x10000000</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1958"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1956">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1957'
	>
	<strong>Envelope</strong> &#8211; 0x20000000</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1961"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1959">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1960'
	>
	<strong>Filter</strong> &#8211; 0x40000000</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1964"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1962">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1963'
	>
	<strong>Zone</strong> &#8211; 0x70000000</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1967"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1965">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1966'
	>
	<strong>Connections</strong> &#8211; 0x60000000</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1970"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1968">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1969'
	>
	Thus, setting resonance for the given layer index requires the following code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1972"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">AudioUnitSetProperty</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    audioUnit</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    4162</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    kAudioUnitScope_LayerItem</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    0x40000000</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">0x100</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token"> </span><span class="token" style="color: #005cc5;">layerIndex</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #005cc5;">value</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">    UInt32</span><span class="token">(</span><span class="token" style="color: #6f42c1;">Mem</span><span class="token" style="color: #005cc5;">oryLayout</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">Float</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">size</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;"> </span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1975"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1973">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1974'
	>
	This provides us with the knowledge necessary to fully exploit the capabilities of AUSampler.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1978"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1976">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1977'
	>
	<a href="https://docs.google.com/spreadsheets/d/1ZPD-lksPnZQRmJrjQWGeNme9OPHZB8BKnSBir7_MFnI/edit#gid=0" target="_blank" rel="noreferrer noopener">This table we’ve created</a> contains the missing AUSampler documentation with hidden private property IDs and their descriptions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1981"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1979">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1980'
	>
	<a href="https://docs.google.com/spreadsheets/d/1ZPD-lksPnZQRmJrjQWGeNme9OPHZB8BKnSBir7_MFnI/edit#gid=0" target="_blank" rel="noreferrer noopener">This table we’ve created</a> contains the missing AUSampler documentation with hidden private property IDs and their descriptions.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-1986"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1984"
	 data-media-type='embed'>

	<div class="embed block-media__embed" data-id=es-1985>
	<iframe
		class="embed__iframe block-media__embed-iframe"
		src="https://docs.google.com/spreadsheets/d/e/2PACX-1vTSVaxl3MR0Xt9Smt_i5o979X5iXkSxeXOec3u01rUDCU_i6TEud7Oxct5CQSe39rgHSTpBvRzN8EzG/pubhtml?gid=0&#038;headers=false"
		frameborder="0"
		aria-label="Embed iframe"
		allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture;"
		allowfullscreen>
	</iframe>
</div></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2007"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1990">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1989"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1987">
	</div>	</div>
</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1993"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1991">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1992'
	>
	Drive AUSampler to its full potential</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1996"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1994">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1995'
	>
	AUSampler is a powerful sampler that comes out of the box on both macOS and iOS. Its availability as a built-in tool makes it appealing to developers and musicians alike. By harnessing its Connections, AUPreset, and hidden properties mechanisms, we can drive AUSampler to its full potential. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1999"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1997">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1998'
	>
	With its unique features and reliable performance, AUSampler offers a compelling solution for incorporating sampled sounds into music applications. However, it is unfortunate that many of AUSampler&#8217;s features remain hidden from developers. We hope that this article has helped you to familiarize yourself with AUSampler and some of its lesser-known capabilities. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2002"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2000">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2001'
	>
	In the hopes of these features becoming more widely known and used, we’ve filed a feature request for Apple to publicly expose and document these properties: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2005"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2003">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2004'
	>
	If you want to go a little bit deeper, you can find the associated source code <a href="https://github.com/infinum/mysterious-sampler">here</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/ausampler-missing-documentation/">Uncovering the Secrets of AUSampler’s Missing Documentation</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>32107https://infinum.com/uploads/2023/01/AU-Sampler2-HERO.webp</url>
				</image>
				<title>Can AU Sampler Survive Dynamic Chain Changes?</title>
				<link>https://infinum.com/blog/au-sampler-dynamic-chain-changes/</link>
				<pubDate>Wed, 18 Jan 2023 14:24:40 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=32107</guid>
				<description>
					<![CDATA[<p>Continuing our exploration of Apple's AUSampler, we’ve tested it to see if the promise of AVAudioEngine’s dynamic connection abilities holds true. </p>
<p>The post <a href="https://infinum.com/blog/au-sampler-dynamic-chain-changes/">Can AU Sampler Survive Dynamic Chain Changes?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-2039"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2008">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2011"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2009">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2010'
	>
	Apple’s <a href="https://developer.apple.com/documentation/avfaudio/avaudioengine" target="_blank" rel="noreferrer noopener">AVAudioEngine documentation</a> opens with a brave statement:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2013"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2012'
	>
	<em>You can connect, disconnect, and remove audio nodes during runtime with minor limitations. Removing an audio node that has differing channel counts, or that’s a mixer, can break the graph. Reconnect audio nodes only when they’re upstream of a mixer.</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2016"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2014">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2015'
	>
	<code>AVAudioEngine</code> header docs state the same in slightly different words:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2019"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2017">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2018'
	>
	<em>The engine supports dynamic connection, disconnection, and removal of nodes while running, with only minor limitations:</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2022"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-2020">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2021'
	>
	<em>all dynamic reconnections must occur upstream of a mixer</em></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2025"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-2023">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2024'
	>
	<em><em>while removals of effects will normally result in the automatic connection of the adjacent nodes, removal of a node which has differing input vs. output channel counts, or which is a mixer, is likely to result in a broken graph.</em></em></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2028"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2026">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2027'
	>
	In the <a href="https://infinum.com/blog/getting-started-with-au-sampler/" target="_blank" rel="noreferrer noopener">first blog post in our sampler series</a>, we laid the foundations for exploring the world of software audio samplers, while the third part reveals <a href="https://infinum.com/blog/ausampler-missing-documentation/" target="_blank" rel="noreferrer noopener">the secrets of AUSampler&#8217;s missing documentation</a>. In this article, we’ll put AUSampler to the test and see if the promise of <code>AVAudioEngine</code>’s dynamic connection abilities holds true. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2031"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2029">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2030'
	>
	Dynamic chain configuration</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2034"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2032">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2033'
	>
	Before we dive into the specifics of AUSampler, let&#8217;s explore what dynamic chain configuration even means.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2037"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2035">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2036'
	>
	We will start with a simple case of an oscillator. Our goal is to replace the Distortion audio effect with the Equalizer audio effect <strong>dynamically while the oscillator is rendering audio without interruptions.</strong></p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2042"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2040"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2041">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/01/Img-01-1400x321.webp				media='(max-width: 699px)'
				type=image/webp								height="321"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/01/Img-01.webp"
					class="image__img block-media__image-img"
					alt=""
										height="458"
															width="2000"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2048"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2043">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2046"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2044">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2045'
	>
	We can do this in four steps:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2051"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2049"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2050">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/01/Img-2-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1003"
															width="1001"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2162"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2052">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2055"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2053">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2054'
	>
	The code would look something like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2057"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func reconnectDynamically</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    engine.</span><span class="token">attach(</span><span class="token">equalizer</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    engine.</span><span class="token">connect(</span><span class="token">equalizer</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    engine.</span><span class="token">connect(</span><span class="token">oscillator</span><span class="token">, </span><span class="token">to:</span><span class="token"> equalizer</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    engine.</span><span class="token">detach(</span><span class="token">distortion</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2060"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2058">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2059'
	>
	We can take a shortcut here and only detach the node that we want to remove. The engine will take care of the rest.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2063"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2061">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2062'
	>
	To verify that everything is in the correct state, we can print the engine’s description. This will print out the underlying audio graph:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2065"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token" style="color: #005cc5;">engine</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">description</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2067"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">AVAudioEngineGraph</span><span class="token" style="color: #d73a49;">:</span><span class="token"> initialized </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">, running </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">, number </span><span class="token" style="color: #d73a49;">of</span><span class="token"> nodes </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">4</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #d73a49;">********</span><span class="token"> output chain </span><span class="token" style="color: #d73a49;">********</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x6000005b0280</span><span class="token"> </span><span class="token">{</span><span class="token">&#039;auou&#039; &#039;ahal&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">, &#039;I&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000005bdd00</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;aumx&#039; &#039;mcmx&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x6000005bdd00</span><span class="token"> </span><span class="token">{</span><span class="token">&#039;aumx&#039; &#039;mcmx&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">, &#039;I&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token">\</span><span class="token">n  (</span><span class="token">bus0</span><span class="token">, </span><span class="token">en0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x0</span><span class="token">, </span><span class="token">{</span><span class="token">}</span><span class="token">, 
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus1</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000005bcf80</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;aufx&#039; &#039;nbeq&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">,
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000005b0280</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;auou&#039; &#039;ahal&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">,
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x6000005bcf80</span><span class="token"> </span><span class="token">{</span><span class="token">&#039;aufx&#039; &#039;nbeq&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">, &#039;I&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000019bc870</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;aufc&#039; &#039;conv&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">,
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000005bdd00</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;aumx&#039; &#039;mcmx&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">,
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x6000019bc870</span><span class="token"> </span><span class="token">{</span><span class="token">&#039;aufc&#039; &#039;conv&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">, &#039;I&#039;
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x6000005bcf80</span><span class="token">, </span><span class="token">{</span><span class="token">&#039;aufx&#039; &#039;nbeq&#039; &#039;appl&#039;</span><span class="token">}</span><span class="token">,
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2069"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2068'
	>
	You can check what these abbreviations map to by running <code>auval -a</code> in Terminal. This will print out all audio units in your system.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2072"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2070">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2071'
	>
	This graph is mostly consistent. The number of nodes is correct, and everything is wired up correctly. The only anomaly is an instance of `0x0` input in the main mixer. This is an artifact of the removal process. On successive connections, the mixer will reuse this bus. And while it looks suspicious, it seems that it doesn’t do any damage.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2075"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2073">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2074'
	>
	Sampler dynamic chain configuration</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2078"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2076">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2077'
	>
	Now, let’s try to do the same with Sampler. Our goal is to:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2082"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2079">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2080'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2081'
	>
	Play and sustain a note with Sampler</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2086"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2083">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2084'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2085'
	>
	Change the effect dynamically while the note is still playing</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2089"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2087">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2088'
	>
	We can use the same reconnect procedure that worked for the oscillator:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2091"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">equalizer</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">equalizer</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">sampler</span><span class="token">, </span><span class="token">to:</span><span class="token"> equalizer</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">detach(</span><span class="token">distortion</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2094"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2092">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2093'
	>
	However, we’ll hear that the sound is interrupted. Moreover, if we try to play some notes again, we will hear the sine wave instead of our instrument. What happened here?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2097"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2095">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2096'
	>
	In <a href="https://infinum.com/blog/getting-started-with-au-sampler/" target="_blank" rel="noreferrer noopener">the previous article on AUSampler</a> we introduced some tools to help us debug and understand Sampler behavior. We can use what we’ve learned to investigate this problem. The process will be the following:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2098">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2099'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2100'
	>
	Start the engine</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2105"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2102">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2103'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2104'
	>
	Stop the debugger</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2109"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2106">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2107'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2108'
	>
	Add a breakpoint</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2110">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2111'
	>
	4</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2112'
	>
	Perform dynamic node connection</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2117"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2114">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2115'
	>
	5</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2116'
	>
	Observe what is happening</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2120"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2118">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2119'
	>
	Since we don’t have much knowledge about AUSampler’s internals, we will start with a very general breakpoint:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">rb Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token">command </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">frame info</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token">auto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">continue</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2124'
	>
	The Sampler is implemented in C++ and this will print out every invocation of the method that matches this pattern.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2126'
	>
	Make sure to run this on an iOS simulator. As mentioned in the previous article, macOS doesn’t expose any symbols, and the debugger will not be able to find them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2128">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2129'
	>
	If we try to change a node now, we’ll see that several things are called:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">CleanupMemory(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">SetProperty(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">void const</span><span class="token" style="color: #d73a49;">*</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">SetProperty(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">void const</span><span class="token" style="color: #d73a49;">*</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">SetProperty(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">void const</span><span class="token" style="color: #d73a49;">*</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">SetProperty(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">void const</span><span class="token" style="color: #d73a49;">*</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">GetPropertyInfo(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">, </span><span class="token">bool</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">InitializeMemory(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">GetInitializeNoteCount(</span><span class="token">)</span><span class="token"> const
</span></span><span class="line"><span class="token">Sampler</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">GetPropertyInfo(</span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token">, </span><span class="token">unsigned int</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">, </span><span class="token">bool</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2133">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2134'
	>
	We should take special note of the following: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2136">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2137'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-2138'
	>
	<code>Sampler::CleanupMemory</code> is called (which in turn calls: <code>AudioStreamer::Destroy</code>)</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2140">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2141'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-16-text-roman js-typography bullet__paragraph'
	data-id='es-2142'
	>
	<code>Sampler::InitializeMemory</code></p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2144">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2145'
	>
	We don’t know exactly what these methods do, but it is a strong indication that the Sampler is reinitialized and that the audio stream is destroyed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2147'
	>
	AUSampler’s default preset will produce a sine wave. If you hear it, it means that the Sampler has been reset.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2149">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2150'
	>
	What can we do about it? The good news is that the AUSampler is able to handle dynamic reconnections, but before we dive into that, let’s take a tour of the <code>AVAudioEngine</code> audio splitting.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2154"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2152">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2153'
	>
	AVAudioEngine audio splitting</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2155">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2156'
	>
	The <code>AVAudioEngine</code> first introduced splitting support in iOS 9 (see <a href="https://developer.apple.com/videos/play/wwdc2015/507/" target="_blank" rel="noreferrer noopener">Session 507: What’s new in Core Audio from WWDC 2015</a>).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2158">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2159'
	>
	Before that, only one-to-one connections were supported:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2165"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2163"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2164">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/01/Image_001.webp"
					class="image__img block-media__image-img"
					alt=""
										height="466"
															width="1000"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			SOURCE: APPLE WWDC 2015 KEYNOTE		</figcaption>
	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2173"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2166">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2167">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2168'
	>
	Then a new API was introduced:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2171"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">-</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">void</span><span class="token">)</span><span class="token" style="color: #005cc5;">connect</span><span class="token">:</span><span class="token">(</span><span class="token" style="color: #005cc5;">AVAudioNode</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token">)</span><span class="token" style="color: #005cc5;">sourceNode</span><span class="token"> </span><span class="token" style="color: #005cc5;">toConnectionPoints</span><span class="token">:</span><span class="token">(</span><span class="token" style="color: #005cc5;">NSArray</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #005cc5;">AVAudioConnectionPoint</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token">)</span><span class="token" style="color: #005cc5;">destNodes</span><span class="token"> </span><span class="token" style="color: #005cc5;">fromBus</span><span class="token">:</span><span class="token">(</span><span class="token" style="color: #005cc5;">AVAudioNodeBus</span><span class="token">)</span><span class="token" style="color: #005cc5;">sourceBus</span><span class="token"> </span><span class="token" style="color: #005cc5;">format</span><span class="token">:</span><span class="token">(</span><span class="token" style="color: #005cc5;">AVAudioFormat</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token"> </span><span class="token" style="color: #005cc5;">__nullable</span><span class="token">)</span><span class="token" style="color: #005cc5;">format</span><span class="token">
</span></span></code></pre></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2174"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2175">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/01/Imge-002-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="503"
															width="1001"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			SOURCE: APPLE WWDC 2015 KEYNOTE		</figcaption>
	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2207"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2177">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2178">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2179'
	>
	The engine transparently handles internal connections for us, but it’s interesting to see what happens under the hood.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2181">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2182'
	>
	When we have one-to-many connections, the engine will create an instance of the <em>AUMultiSplitter</em> audio unit. This can be confirmed by looking at the underlying graph that we can print:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">AVAudioEngineGraph </span><span class="token" style="color: #005cc5;">0x600002c25c00</span><span class="token" style="color: #d73a49;">:</span><span class="token"> initialized </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">, running </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">, number </span><span class="token" style="color: #d73a49;">of</span><span class="token"> nodes </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">7</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> </span><span class="token" style="color: #d73a49;">********</span><span class="token"> output chain </span><span class="token" style="color: #d73a49;">********</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x600003e23280</span><span class="token"> </span><span class="token">{</span><span class="token">auou rioc appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e28b80</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mcmx appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x600003e28b80</span><span class="token"> </span><span class="token">{</span><span class="token">aumx mcmx appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">3</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e20400</span><span class="token">, </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus1</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e01780</span><span class="token">, </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e23280</span><span class="token">, </span><span class="token">{</span><span class="token">auou rioc appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">node </span><span class="token" style="color: #005cc5;">0x600003e20400</span><span class="token"> </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus2</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e26300</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mspl appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e28b80</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mcmx appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x600003e01780</span><span class="token"> </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e26300</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mspl appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e28b80</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mcmx appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;/</span><span class="token">em</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">node </span><span class="token" style="color: #005cc5;">0x600003e26300</span><span class="token"> </span><span class="token">{</span><span class="token">aumx mspl appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token"> inputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;-</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600002200240</span><span class="token">, </span><span class="token">{</span><span class="token">aumu samp appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">3</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e01780</span><span class="token">, </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus1</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e00b00</span><span class="token">, </span><span class="token">{</span><span class="token">aufx dist appl</span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token"> node </span><span class="token" style="color: #005cc5;">0x600002200240</span><span class="token"> </span><span class="token">{</span><span class="token">aumu samp appl</span><span class="token">}</span><span class="token">, &#039;U&#039;
</span></span><span class="line"><span class="token"> outputs </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token">(</span><span class="token">bus0</span><span class="token">, </span><span class="token">en1</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">(</span><span class="token">bus0</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #005cc5;">0x600003e26300</span><span class="token">, </span><span class="token">{</span><span class="token">aumx mspl appl</span><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2186">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2187'
	>
	Note an instance of the <code>mspl</code> audio unit. It represents an instance of the AUMultiSplitter<em> </em>audio unit responsible for audio splitting.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2189">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2190'
	>
	These are the unit’s header docs:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">kAudioUnitSubType_MultiSplitter
</span></span><span class="line"><span class="token">    An audio unit that sends its input bus to </span><span class="token" style="color: #d73a49;">any</span><span class="token"> number </span><span class="token" style="color: #d73a49;">of</span><span class="token"> output buses.
</span></span><span class="line"><span class="token">    Every output bus gets all channels </span><span class="token" style="color: #d73a49;">of</span><span class="token"> the input bus.
</span></span><span class="line"><span class="token">    This unit&#039;s implementation </span><span class="token" style="color: #d73a49;">is</span><span class="token"> lighter weight than kAudioUnitSubType_Splitter
</span></span><span class="line"><span class="token">    even </span><span class="token" style="color: #d73a49;">for</span><span class="token"> two</span><span class="token"> output buses, and </span><span class="token" style="color: #d73a49;">is</span><span class="token"> recommended over kAudioUnitSubType_Splitter.
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2194">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2195'
	>
	This audio unit turned out to be the key to keeping AUSampler alive while dynamically reconnecting it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2197">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2198'
	>
	Correct setup</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2200">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2201'
	>
	With this knowledge, we are now able to find the correct setup.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2203">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2204'
	>
	Ideally, we would like to do this:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2208"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2209">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/01/Img-3-1400x321.webp				media='(max-width: 699px)'
				type=image/webp								height="321"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/01/Img-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="459"
															width="2000"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2216"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2211">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2214"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2212">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2213'
	>
	However, we realized earlier this wouldn’t work. Instead, let’s do this:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2219"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2217"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2218">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/01/Img-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="356"
															width="1001"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2225"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2220">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2221">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2222'
	>
	These extra two dummy effects give us a fully working sampler. The reconnection process would look like this:</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2228"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2226"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2227">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/01/Img-5-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1220"
															width="1001"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-2269"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2229">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2230">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2231'
	>
	Step 1: Create a Sampler with two static dummy nodes and connect it to them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2234"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">sampler</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">staticDistortion</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">staticDistortion2</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">distortion</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">sampler</span><span class="token">,
</span></span><span class="line"><span class="token">    </span><span class="token">to:</span><span class="token"> [
</span></span><span class="line"><span class="token">           </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> staticDistortion</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">           </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> staticDistortion2</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">           </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> distortion</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">    ],
</span></span><span class="line"><span class="token">    </span><span class="token">fromBus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">,
</span></span><span class="line"><span class="token">    </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">distortion</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">staticDistortion</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">staticDistortion2</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2235">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2236'
	>
	Step 2: Reconnect.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2239"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">engine.</span><span class="token">disconnectNodeOutput(</span><span class="token">distortion</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">detach(</span><span class="token">distortion</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">equalizer</span><span class="token">, </span><span class="token">to:</span><span class="token"> engine.</span><span class="token">mainMixerNode</span><span class="token">, </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">connect(</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">sampler</span><span class="token">,
</span></span><span class="line"><span class="token">    </span><span class="token">to:</span><span class="token"> [
</span></span><span class="line"><span class="token">          </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> staticDistortion</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">          </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> staticDistortion2</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">          </span><span class="token">AVAudioConnectionPoint(</span><span class="token">node:</span><span class="token"> equalizer</span><span class="token">, </span><span class="token">bus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">    ],
</span></span><span class="line"><span class="token">    </span><span class="token">fromBus:</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">,
</span></span><span class="line"><span class="token">    </span><span class="token">format:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2240">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2241'
	>
	If we now add the same breakpoint as in our initial setup, we will see that nothing gets called and the Sampler is not touched on reconnection.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2243'
	>
	Finding this out was pure luck. We had a more complex setup that worked by default. After making some changes to our chain, we found that things got broken and then went down the rabbit hole that brought us to this realization.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2247"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2245">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2246'
	>
	We need two dummy nodes because the splitter node is very sensitive to the number of connections. If we leave it with only one connection, we will get the following error:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2249"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token" style="color: #005cc5;">avae</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #005cc5;">AVAEInternal</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">h</span><span class="token">:</span><span class="token" style="color: #005cc5;">76</span><span class="token"> </span><span class="token" style="color: #005cc5;">required</span><span class="token"> </span><span class="token" style="color: #005cc5;">condition</span><span class="token"> </span><span class="token" style="color: #005cc5;">is</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">:</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">AVAudioEngineGraph</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">mm</span><span class="token">:</span><span class="token" style="color: #005cc5;">3135</span><span class="token">:</span><span class="token" style="color: #005cc5;">GetOutputConnectionPointsForNode</span><span class="token">:</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">numSplitterConnections</span><span class="token"> </span><span class="token" style="color: #d73a49;">==</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #d73a49;">||</span><span class="token"> </span><span class="token" style="color: #005cc5;">numSplitterConnections</span><span class="token"> </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">)</span><span class="token">]</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2252"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2250">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2251'
	>
	Tricky, yet important </h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2255"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2253">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2254'
	>
	While quite tricky, we’ve seen that the AUSampler in combination with AVAudioEngine is capable of picking up dynamically added or removed nodes. This use case is very important for some apps, and while going to the AudioUnit level is always an option, it also requires us to sacrifice the convenience of the <code>AVAudioEngine</code> API.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2258"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2256">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2257'
	>
	Please note that the <code>AVAudioPlayerNode</code> is not immune to this problem either. If we try to connect new nodes to the <code>AVAudioPlayerNode</code> during playback, the playback will stop and we will need to schedule buffers/files again.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2259">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2260'
	>
	Furthermore, it’s puzzling that introducing a splitter prevents the Sampler from cleanup; it would seem that shouldn’t be necessary.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2264"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2262">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2263'
	>
	We have filed both of these as bugs to Apple.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2267"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2265">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2266'
	>
	You can find the associated source code <a href="https://github.com/infinum/mysterious-sampler" target="_blank" rel="noreferrer noopener">here</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/au-sampler-dynamic-chain-changes/">Can AU Sampler Survive Dynamic Chain Changes?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>27349https://infinum.com/uploads/2022/08/AUSampler_Blogpost.webp</url>
				</image>
				<title>Exploring AU Sampler – Apple&#8217;s Mysterious Sampler Audio Unit</title>
				<link>https://infinum.com/blog/getting-started-with-au-sampler/</link>
				<pubDate>Thu, 11 Aug 2022 08:08:31 +0000</pubDate>
				<dc:creator>Josip Ćavar</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=27349</guid>
				<description>
					<![CDATA[<p>Getting acquainted with Apple's powerful, yet underexplored sampler audio unit. We set the stage and learn how to use a simple toolbox.</p>
<p>The post <a href="https://infinum.com/blog/getting-started-with-au-sampler/">Exploring AU Sampler – Apple&#8217;s Mysterious Sampler Audio Unit</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-2491"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-2270">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2273"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2271">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2272'
	>
	A hardware sampler is a device that takes recorded pieces of audio data called “samples” and can play them back on a key press. While <a href="https://www.theguardian.com/music/2009/sep/28/whats-that-sound-sampler" target="_blank" rel="noreferrer noopener">the history of hardware sampling</a> is interesting, it is fair to say that, due to their flexibility, software samplers nowadays prevail.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2276"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2274">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2275'
	>
	A software sampler does exactly the same thing as a hardware sampler, but with a lot more freedom. And while Apple hides its Sampler in GarageBand and Logic Pro, they do expose the Sampler audio unit and its wrapper <code>AVAudioUnitSampler</code>. This seems to be a “Lite” version of their Pro tools Sampler.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2279"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2277">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2278'
	>
	The AUSampler plugin can be found in both Logic and GarageBand as a Plugin. In GarageBand, Go to <em>Track → Plugins → AU Instruments → Apple → AUSampler</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2282"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2280">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2281'
	>
	This article is only the beginning. We continue our exploration of Apple&#8217;s sampler audio unit in <a href="https://infinum.com/blog/au-sampler-dynamic-chain-changes/" target="_blank" rel="noreferrer noopener">the next blog post in the AUSampler series</a>, where we test it to see if the promise of AVAudioEngine’s dynamic connection abilities holds true. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2283">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2284'
	>
	The trouble begins</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2286">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2287'
	>
	Don’t think it’s simple. It is a rich and complex component that can achieve a lot and get you very far. Some of its features include:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-2289">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-2290'
	>
	<li>Streaming samples from a disk</li><li>Sharing samples in the memory</li><li>Voice-stealing capabilities</li><li>Zone mapping</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2294"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2292">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2293'
	>
	Apple first introduced this API in iOS 5 and improved it further with the introduction of the <code>AVAudioEngine</code> API in iOS 8. Unfortunately, it is largely undocumented. There are two (very useful) tech notes, one about <a href="https://developer.apple.com/library/archive/technotes/tn2283/_index.html" target="_blank" rel="noreferrer noopener">loading instruments</a> and the other one about <a href="https://developer.apple.com/library/archive/technotes/tn2331/_index.html" target="_blank" rel="noreferrer noopener">controlling the sampler in real-time</a>. Additionally, there are a few old WWDC videos, but some of them are from 2012 and Apple has removed them from their site, so you’d need to get them from other sources. And that about covers it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2297"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2295">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2296'
	>
	Luckily, Apple released the AU Lab app that includes the AUSampler plugin and showcases many of the sampler features. It doesn’t just showcase them, it’s an essential tool for importing, editing and exporting your instruments in AUSampler’s native format.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2299"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2298'
	>
	AU Lab is a great simple app that includes other audio units, such as AUAudioFilePlayer, and many effects. It allows you to play with them in a simple interface. A great tool for comparing the output of your setup with the expected output.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2300">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2301'
	>
	This app will prove fundamental in building our understanding of some more intricate (not to say buggy) behaviors. And Sampler is not short on those.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2305"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2303">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2304'
	>
	Sampler crashes when not attached to the engine</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2308"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2306">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2307'
	>
	What do you think will happen in the following case?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">var sampler:</span><span class="token"> AVAudioUnitSampler</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">AVAudioUnitSampler(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">esampler.</span><span class="token">loadPreset(</span><span class="token">at:</span><span class="token"> url</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">sampler </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2313"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2311">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2312'
	>
	The app will crash with:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">ASSERTION FAILED</span><span class="token" style="color: #d73a49;">:</span><span class="token"> unbalanced reference count
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2316">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2317'
	>
	To work around this, you will need to attach the sampler to the engine before deallocating it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2320"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> engine </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">AVAudioEngine(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">var sampler:</span><span class="token"> AVAudioUnitSampler</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">AVAudioUnitSampler(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">sampler.</span><span class="token">loadPreset(</span><span class="token">at:</span><span class="token"> url</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">attach(</span><span class="token">sampler</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">engine.</span><span class="token">detach(</span><span class="token">sampler</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">sampler </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2322"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2321'
	>
	<strong>We have filed this bug to Apple under FB10136468, and this was fixed in macOS 13 Beta 4.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2325"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2323">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2324'
	>
	Open file limit</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2328"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2326">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2327'
	>
	Imagine you have the following setup:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2331"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2329"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2330">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2022/08/AUSampler_In-page_01-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="453"
															width="1000"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2334"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2332">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2333'
	>
	Each Sampler loads a different instrument with 50 samples. What do you think will happen?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2337"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2335">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2336'
	>
	At some point, when loading an instrument to one of the samplers, you will get:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2339"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">SampleManager.</span><span class="token">cpp</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #005cc5;">434</span><span class="token">   Failed to load sample &#039;sample.</span><span class="token">caf</span><span class="token">&#039;</span><span class="token" style="color: #d73a49;">:</span><span class="token"> error </span><span class="token" style="color: #005cc5;">-42</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2342"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2340">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2341'
	>
	This is not an error in the sampler itself, but an OS that tries to load too many files at the same time. The default limit for the maximum number of open file descriptors per process is 256. You can verify this by running:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2344"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">ulimit</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">n</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2347"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2345">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2346'
	>
	This can be fixed by increasing the limit:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2349"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">var limit:</span><span class="token"> rlimit </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">rlimit(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">getrlimit(</span><span class="token">RLIMIT_NOFILE</span><span class="token">, </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">limit</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">limit.</span><span class="token">rlim_cur</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> limit
</span></span><span class="line"><span class="token">setrlimit(</span><span class="token">RLIMIT_NOFILE</span><span class="token">, </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">limit</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">getrlimit(</span><span class="token">RLIMIT_NOFILE</span><span class="token">, </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">limit</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2352"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2350">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2351'
	>
	Hidden Voice Count limit</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2355"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2353">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2354'
	>
	Imagine you have a Sampler with 50 samples. Each note triggers all of them. What will happen if you sustain a lot of notes?&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2358"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2356">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2357'
	>
	Well, it turns out that there is a limit to the number of concurrently playing samples. It is 128 on iOS and 256 on macOS.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2361"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2359">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2360'
	>
	But what do you expect will happen when the limit is reached? Probably that voice stealing will kick in and kill the very first note. But no, it actually ignores any <strong>new </strong>notes sent to the Sampler.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2363"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2362'
	>
	We have filed this bug to Apple under FB9835828, and this was fixed in macOS 13 Beta 4.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2366"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2364">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2365'
	>
	Please note that there is a distinction between Voice Count and the number of playing samples. Voice Count of 1 can represent many concurrently playing samples.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2369"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2367">
	<p	class='typography typography--size-24-text js-typography block-paragraph__paragraph'
	data-id='es-2368'
	>
	How do you know if a very quiet sample is playing? AULab’s Voice Count indicator is very useful in this situation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2372"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2370">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2371'
	>
	To tackle those, we will need to go off-road and perform somewhat unconventional steps:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2375"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-2373">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-2374'
	>
	<li>Disassemble frameworks of interest</li><li>Attach a debugger to AU Lab</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2378"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2376">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2377'
	>
	Frameworks layout</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2381"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2379">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2380'
	>
	To prepare ourselves for this quest, we first need to have a high-level overview of the frameworks involved.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2384"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2382">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2383'
	>
	AUSampler plugin</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2387"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2385">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2386'
	>
	When you load AUSampler Audio Unit Instrument in AU Lab, you are presented with the UI that controls it. An Audio Unit can expose the UI, and what we see in AU Lab is AUSampler’s UI. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2390"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2388"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2389">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2022/08/AUSampler_In-page_02.webp"
					class="image__img block-media__image-img"
					alt=""
										height="750"
															width="1000"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2393"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2391">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2392'
	>
	You can load AUSampler’s UI from your apps by using the <a href="https://developer.apple.com/documentation/audiotoolbox/auaudiounit/1516626-requestviewcontroller" target="_blank" rel="noreferrer noopener">requestViewController</a> API on AUSampler audio unit.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2395"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-2394'
	>
	Presenting an Audio Unit’s custom UI from your app is a great way to explore the unit. Unfortunately, the rich view is only available in macOS and missing in iOS.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2398"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2396">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2397'
	>
	AUSampler’s UI, as well as the UI’s of many other Apple Audio Units, is implemented in:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2400"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">System</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Library</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Components</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">CoreAudio</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">component</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Contents</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">PlugIns</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">CoreAudioAUUI</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">bundle</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Contents</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">MacOS</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">CoreAudioAUUI</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2401">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2402'
	>
	Sampler implementation</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2406"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2404">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2405'
	>
	The implementation of Sampler Audio Unit in iOS can be found here:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2408"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">~</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Library</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Developer</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Xcode</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">iOS</span><span class="token"> </span><span class="token" style="color: #005cc5;">DeviceSupport</span><span class="token" style="color: #d73a49;">/</span><span class="token">{</span><span class="token" style="color: #005cc5;">IOS_VERSION</span><span class="token">}</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Symbols</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">System</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Library</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Frameworks</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">AudioToolbox</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">framework</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">libEmbeddedSystemAUs</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">dylib</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2411"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2409">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2410'
	>
	In macOS, it can be found here:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2413"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">System</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Library</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Frameworks</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">CoreAudio</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">framework</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Versions</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">A</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Resources</span><span class="token" style="color: #d73a49;">/</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2416"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2414">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2415'
	>
	The dylib is not there but in a <a href="https://mjtsai.com/blog/2020/06/26/reverse-engineering-macos-11-0/" target="_blank" rel="noreferrer noopener">shared dylib cache</a>. Additionally, the macOS version doesn’t expose any symbols, which makes debugging/reverse engineering much more difficult.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2419"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2417">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2418'
	>
	Reversing voice count functionality</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2422"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2420">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2421'
	>
	Let’s move to the useful part and find out how Voice Count is implemented in the AUSampler plugin.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2425"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2423">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-2424'
	>
	Attaching to AU Lab</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2428"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2426">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2427'
	>
	The very first step that we need to do is to attach the debugger to the AU Lab application. We can do this in the following way:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2432"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2429">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2430'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2431'
	>
	Start the process</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2436"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--infinum block-bullet__bullet" data-id="es-2433">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-2434'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-2435'
	>
	In Xcode, go to Debug -&gt; Attach to Process and find our process</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2439"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2437">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2438'
	>
	If you try to do this, it will most likely fail because we are not allowed to attach the debugger to any binary. There are few options:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2442"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-2440">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-2441'
	>
	<li>Disable System Integrity Protection</li><li>Resign AU Lab</li><li>Install virtual machine and disable SIP</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2445"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2443">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2444'
	>
	In this case, resigning is probably the easiest way to achieve what we want:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2447"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">codesign </span><span class="token" style="color: #d73a49;">-</span><span class="token">f </span><span class="token" style="color: #d73a49;">-</span><span class="token">s </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Apple Development: …</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> “</span><span class="token" style="color: #d73a49;">~/Desk</span><span class="token">top</span><span class="token" style="color: #d73a49;">/AU L</span><span class="token">ab Copy.</span><span class="token">app</span><span class="token">”
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2450"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2448">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2449'
	>
	Attaching the debugger should now work. Now that we are inside, what should we do?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2453"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2451">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2452'
	>
	We could do this step by step, but we will take a shortcut and guess that it has to do with <a href="https://developer.apple.com/documentation/audiotoolbox/1439840-audiounitgetproperty" target="_blank" rel="noreferrer noopener">AudioUnitGetProperty</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2456"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2454">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2455'
	>
	Let’s set a breakpoint to it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2458"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">rb</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">AudioUnitGetProperty$</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">command</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">po </span><span class="token" style="color: #032f62;">$</span><span class="token" style="color: #24292e;">rsi</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">auto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">continue</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2461"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2459">
	<p	class='typography typography--size-14-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2460'
	>
	Intel Architecture</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2463"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">rb</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">AudioUnitGetProperty$</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">command</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">po </span><span class="token" style="color: #032f62;">$</span><span class="token" style="color: #24292e;">x1</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">auto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">continue</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2466"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2464">
	<p	class='typography typography--size-14-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2465'
	>
	ARM Architecture</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2469"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-2467">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-2468'
	>
	<li><strong>rb</strong> – create a regex breakpoint</li><li><strong>&#8211;command</strong> – execute a command. Print $rsi which is a second argument to a function (on Intel) and property id that we are interested in</li><li><strong><em>&#8211;</em>-auto-continue</strong> – do not stop on a breakpoint</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2472"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2470">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2471'
	>
	This gives us a secret voice count property id which is 4104 in this case. We are now able to implement this in our own code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2474"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">AudioUnitGetProperty</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    audioUnit</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    4104</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    kAudioUnitScope_Global</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    0</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #005cc5;">count</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #005cc5;">countSize</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2477"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-2475">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-2476'
	>
	Only the beginning</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2480"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2478">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2479'
	>
	With this blog post, we’ve just scratched the surface on Apple&#8217;s mysterious sampler audio unit, powerful yet underexplored.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2483"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2481">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2482'
	>
	We set the stage and learned how to use a simple toolbox to tackle more of Sampler’s intricacies.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2486"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2484">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2485'
	>
	You can find the associated source code <a href="https://github.com/infinum/mysterious-sampler" target="_blank" rel="noreferrer noopener">here</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2489"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-2487">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-2488'
	>
	Stay tuned for more.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/getting-started-with-au-sampler/">Exploring AU Sampler – Apple&#8217;s Mysterious Sampler Audio Unit</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>