<?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/kresimir-valjevac/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Wed, 08 Apr 2026 07:17:45 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7871https://infinum.com/uploads/2019/07/combine-makes-swiftui-shine-0.webp</url>
				</image>
				<title>Combine’s What Makes SwiftUI Really Shine</title>
				<link>https://infinum.com/blog/combine-makes-swiftui-shine/</link>
				<pubDate>Thu, 18 Jul 2019 13:05:00 +0000</pubDate>
				<dc:creator>Krešimir Valjevac</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/combine-makes-swiftui-shine/</guid>
				<description>
					<![CDATA[<p>We still haven’t decided on what’s the best approach to SwiftUI’s declarative way of building UI architecture-wise.</p>
<p>The post <a href="https://infinum.com/blog/combine-makes-swiftui-shine/">Combine’s What Makes SwiftUI Really Shine</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-446"
	 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-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	It’s time to start catching up with <em>Combine</em>!</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-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	If you’ve been with me and remember the <a href="https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/">initial breakdown using SwiftUI</a>, here’s what I wanted to do:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-99">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-100'
	>
	<li>Make a List</li><li>Make a Row for that List</li><li>Create a view model</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	We still haven’t decided on what’s the best approach to <em>SwiftUI’s</em> declarative way of building UI architecture-wise, but it seems to be leaning heavily towards <em>MVVM</em>, or at least some variant of it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	Since it seems pretty natural to use, we’re going with that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	Creating the ViewModel</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	We need to start off with several things in mind:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-114">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-115'
	>
	<li>How to represent the <em>model</em> in the <em>view</em></li><li>How to update the <em>model</em> when text changes</li><li>How to update the <em>view</em> for <em>model</em> changes</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	First things first, the view needs to read values from the state of the view model. The model will be updating its state when it receives events from the <code>URLSession.DataTaskPublisher</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	If you’re familiar with <em>RxSwift</em>, you’ll know that you can achieve that by binding streams of data to UI elements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	In the case of <em>SwiftUI</em>, it’ll actually re-render the component that needs to be updated. So, when building a list of rows and that list updates, the UI will end up adjusting itself to accommodate for the changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-126">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-127'
	>
	With all that in mind, let’s make a model which represents a single <em>GitHub</em> repository.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-129">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-130'
	>
	Repository model</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 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 Repository</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Identifiable</span><span class="token">, </span><span class="token" style="color: #6f42c1;">Decodable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">let id:</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 name:</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 fullName:</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 description:</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><span class="line"><span class="token">   </span><span class="token">let stargazersCount:</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">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	A simple struct with some attributes that conforms to <code>Decodable</code>. Those of you with a keen eye might’ve noticed something new—and that’s a protocol called <code>Identifiable</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	The only requirement of the protocol is that the object has an <code>id</code>, which is then used by <code>Equatable</code> under the hood. That’s great! But… where is it identified? <em>SwiftUI</em> uses it for its <code>List</code> element which does diffing, insertion and deletion for us.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-140">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-141'
	>
	How cool is that?! No more headaches with index paths. ?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-143">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-144'
	>
	Repository view model</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-146">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-147'
	>
	The single most important thing to do is to conform to the <code>BindableObject</code> protocol. The object uses that to notify the framework when it receives changes. Changes are then sent to the view, which then updates the layout.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-149">
	
	<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-150'>
	<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-151'
	>
	Note: If you’ve used RxSwift, AnyPublisher in essence is the well known asObservable() operator.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 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 RepositoryViewModel</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BindableObject </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;"> BindableObject conformance</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">let didChange:</span><span class="token"> AnyPublisher</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Void</span><span class="token">, </span><span class="token" style="color: #005cc5;">Never</span><span class="token">&gt;</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;"> Data model</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">var repositories:</span><span class="token"> </span><span class="token">[</span><span class="token">Repository</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;">init</span><span class="token">(</span><span class="token">repositories</span><span class="token">: </span><span class="token">[</span><span class="token">Repository</span><span class="token">]</span><span class="token"> </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 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">repositories</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> repositories
</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	To satisfy the protocol, we need the <code>didChange</code> property, which is typed as <code>AnyPublisher&lt;Void, Never&gt;</code>. It’s pretty cool that we don’t need a concrete type, the framework only expects us to signal when there are updates in the pipeline!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-160'
	>
	Since we’re also binding to the UI, errors need to be handled before passing values to the publisher. Hence the second type, which is represented as <code>Never</code>.</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-heading" data-id="es-162">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-163'
	>
	View Model integration</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-165">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-166'
	>
	I’ll concentrate only on the <code>ListView</code> and the <code>RepositoryRowView</code>, since the implementation is exactly the same across all of them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-168">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-169'
	>
	<li>ListView</li></ul></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">struct ListView</span><span class="token"> </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" style="color: #d73a49;">@ObjectBinding</span><span class="token"> </span><span class="token">var viewModel:</span><span class="token"> RepositoryViewModel</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token" style="color: #d73a49;">@State</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&quot;</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">NavigationView</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">TextField(</span><span class="token">$text</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</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">List(</span><span class="token">viewModel.</span><span class="token">repositories</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> repository </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token">RepositoryRowView(</span><span class="token">repository:</span><span class="token"> repository</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">listStyle(</span><span class="token">.</span><span class="token">grouped</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">environment(</span><span class="token">\.</span><span class="token">defaultMinListRowHeight</span><span class="token">, </span><span class="token" style="color: #005cc5;">50</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">navigationBarTitle(</span><span class="token">.</span><span class="token" style="color: #d73a49;">init</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">GitHub search</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 class="token">
</span></span><span class="line"><span class="token">       .</span><span class="token">colorScheme(</span><span class="token">.</span><span class="token">dark</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">
</span></span><span class="line"><span class="token">#</span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">DEBUG</span><span class="token">
</span></span><span class="line"><span class="token">struct ListView_Previews</span><span class="token"> </span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PreviewProvider </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 previews:</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">ListView(</span><span class="token">viewModel:</span><span class="token"> .</span><span class="token" style="color: #d73a49;">init</span><span class="token">(</span><span class="token">repositories:</span><span class="token"> </span><span class="token">RepositoriesMock(</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><span class="line"><span class="token">#</span><span class="token" style="color: #d73a49;">endif</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-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-173">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-174'
	>
	<code>ListView</code> requires a few simple changes. Instead of a fixed range that we passed to the <code>List</code> initially, we’re now passing the <code>repositories</code> property of the model.<br>If <code>Repository</code> is not conforming to the <code>Identifiable</code> protocol, a convoluted error might pop up in this moment, so double check that in case of any weirdness.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-176">
	
	<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-177'>
	<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-178'
	>
	Note: RepositoriesMock is a simple array of hardcoded repositories, which is passed for preview purposes. This enables you to see your data in the handy preview window on the right of the editor.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-181">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-182'
	>
	All that’s left to do now is to add the <code>Repository</code> to the rest of the subviews.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-184">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-185'
	>
	<li>RepositoryRowView</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 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 RepositoryRowView</span><span class="token"> </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 repository:</span><span class="token"> Repository</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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">DetailsContainerView(</span><span class="token">repository:</span><span class="token"> repository</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">Spacer(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">StarsContainerView(</span><span class="token">repository:</span><span class="token"> repository</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">
</span></span><span class="line"><span class="token">struct RepositoryRowView_Previews</span><span class="token"> </span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PreviewProvider </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 previews:</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;">return</span><span class="token"> </span><span class="token">RepositoryRowView(</span><span class="token">repository:</span><span class="token"> RepositoriesMock</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">   </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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-189">
	
	<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-190'>
	<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-191'
	>
	Note: When you add a new view by hand, a preview won’t be generated out-of-the-box. To get it to work, simply add struct RepositoryRowView_Previews which needs to implement the PreviewProvider.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-194">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-195'
	>
	Pretty simple, right?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-197">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-198'
	>
	The exact same thing needs to be done for both the <code>DetailsContainerView</code> and the <code>StarsContainerView</code>, so I won’t dive into that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-200">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-201'
	>
	Wrapping up the View Model</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-203">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-204'
	>
	We’ve already started by adding a publisher that’s responsible of notifying the view about updates.</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-paragraph" data-id="es-206">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-207'
	>
	What about the changes of the actual data source, that is, the repositories array inside of the view model?<br>Thankfully, <code>URLSession</code> provides a publisher just for that!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	We also need to pass any text changes from the view to the view model. It then needs to initiate an API call and provide information about the update.</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-paragraph" data-id="es-212">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-213'
	>
	Taking a look at the <code>ListView</code> again, we can see the <code>@State</code> property wrapper that’s used to track text changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-216"
	 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 ListView</span><span class="token"> </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" style="color: #d73a49;">...</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token" style="color: #d73a49;">@State</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&quot;</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;">...</span><span class="token">
</span></span><span class="line"><span class="token">       </span><span class="token">TextField(</span><span class="token">$text</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</span><span class="token">)</span><span class="token">
</span></span><span class="line"><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">}</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-217">
	
	<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-218'>
	<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-219'
	>
	Note: The $ symbol means that we’re mutating the state instead of passing it by value, i.e. we’re making it mutable or reference-alike.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-224"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-222">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-223'
	>
	Since we have no use of that property in the view anymore, we can move it into the model! We can use it to track changes internally and simply notify the view when we’re done.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-227"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-225">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-226'
	>
	Let’s tweak both the model and the list. We’ll start with the list since it’s simpler:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 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 ListView</span><span class="token"> </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" style="color: #d73a49;">@ObjectBinding</span><span class="token"> </span><span class="token">var viewModel:</span><span class="token"> RepositoryViewModel</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;">...</span><span class="token">
</span></span><span class="line"><span class="token">       </span><span class="token">TextField(</span><span class="token">viewModel</span><span class="token">[</span><span class="token">\.</span><span class="token" style="color: #005cc5;">text</span><span class="token">]</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</span><span class="token">)</span><span class="token">
</span></span><span class="line"><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">}</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-230">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-231'
	>
	The <code>@State var text</code> was replaced by binding the text field to a keypath which points to the <code>text</code> property of the view model. Going further, let’s adjust the model now:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-234"
	 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 RepositoryViewModel</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BindableObject </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;"> BindableObject conformance</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">let didChange:</span><span class="token"> AnyPublisher</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Void</span><span class="token">, </span><span class="token" style="color: #005cc5;">Never</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Public properties</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">var repositories:</span><span class="token"> </span><span class="token">[</span><span class="token">Repository</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><span class="line"><span class="token">   </span><span class="token">var text:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</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" style="color: #d73a49;">didSet</span><span class="token"> </span><span class="token">{</span><span class="token"> _textDidChange.</span><span class="token">send(</span><span class="token">text</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><span class="line"><span class="token">   </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Private properties</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: #d73a49;">let</span><span class="token"> _textDidChange </span><span class="token" style="color: #d73a49;">=</span><span class="token"> PassthroughSubject</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #005cc5;">String</span><span class="token">, </span><span class="token" style="color: #005cc5;">Never</span><span class="token" style="color: #d73a49;">&gt;</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;">private</span><span class="token"> </span><span class="token">var _cancellable:</span><span class="token"> Cancellable</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;">init</span><span class="token">(</span><span class="token">repositories</span><span class="token">: </span><span class="token">[</span><span class="token">Repository</span><span class="token">]</span><span class="token"> </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 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">repositories</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> repositories
</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-235">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-236'
	>
	This concludes all the properties necessary to make the view model work! Not so bad, right?<br>Concentrating on said properties, we can see the following:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-240"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-238">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-239'
	>
	<li><code>var text: String</code> to which we bind text changes from the view, which forwards its value to the <code>_textDidChange</code> subject</li><li><code>let _textDidChange: PassthroughSubject&lt;String, Never&gt;</code> which is a private property used to notify the view model that there were some changes in the view</li><li><code>var _cancellable: Cancellable?</code> which we can use to cancel any ongoing work</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-243"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-241">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-242'
	>
	To elaborate, for each character input in the textfield, our internal subject will get notified through the setter of the <code>text</code> variable. This then initiates an API call.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-246"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-244">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-245'
	>
	That API call is going to return a <code>cancellable</code> which we store and call on <code>deinit</code> to clean up the resources when needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-249"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-247">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-248'
	>
	Woah, wait, what’s a <code>subject</code> now? Well, since I talked about publishers already—I can paraphrase that <em>a Subject in its most simplest term is a publisher into which you’re able to write values</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-252"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-250">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-251'
	>
	Remember, publishers are read-only and are strictly used to pass data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-255"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-253">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-254'
	>
	On the other hand, a subject can be used as a bridge between reactive and non-reactive code, since it’s able to receive data in its stream.<br>We’ll use that to publish text changes through the stream which will result in an API call returning the <code>Repositories</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-258"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-256">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-257'
	>
	That’s a lot to chew through, but bear with me and let’s just pour those words into code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-260"
	 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 RepositoryViewModel</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BindableObject </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;"> BindableObject conformance</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">let didChange:</span><span class="token"> AnyPublisher</span><span class="token">&lt;</span><span class="token" style="color: #005cc5;">Void</span><span class="token">, </span><span class="token" style="color: #005cc5;">Never</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Public properties</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">var repositories:</span><span class="token"> </span><span class="token">[</span><span class="token">Repository</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><span class="line"><span class="token">   </span><span class="token">var text:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</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" style="color: #d73a49;">didSet</span><span class="token"> </span><span class="token">{</span><span class="token"> _textDidChange.</span><span class="token">send(</span><span class="token">text</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><span class="line"><span class="token">   </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Private properties</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: #d73a49;">let</span><span class="token"> _textDidChange </span><span class="token" style="color: #d73a49;">=</span><span class="token"> PassthroughSubject</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #005cc5;">String</span><span class="token">, </span><span class="token" style="color: #005cc5;">Never</span><span class="token" style="color: #d73a49;">&gt;</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;">private</span><span class="token"> </span><span class="token">var _cancellable:</span><span class="token"> Cancellable</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Init</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token" style="color: #d73a49;">init</span><span class="token">(</span><span class="token">repositories</span><span class="token">: </span><span class="token">[</span><span class="token">Repository</span><span class="token">]</span><span class="token"> </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 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">repositories</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> repositories
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">       </span><span class="token" style="color: #d73a49;">let</span><span class="token"> search </span><span class="token" style="color: #d73a49;">=</span><span class="token"> _textDidChange
</span></span><span class="line"><span class="token">           .</span><span class="token" style="color: #005cc5;">filter</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">!</span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token" style="color: #005cc5;">isEmpty</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">debounce(</span><span class="token">for:</span><span class="token"> .</span><span class="token">seconds(</span><span class="token" style="color: #005cc5;">0.3</span><span class="token">)</span><span class="token">, </span><span class="token">scheduler:</span><span class="token"> DispatchQueue.</span><span class="token">main</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">flatMapLatest</span><span class="token"> </span><span class="token">{</span><span class="token"> RepositoryViewModel.</span><span class="token">_getRepositories(</span><span class="token">using:</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token">, </span><span class="token">existingRepositories:</span><span class="token"> repositories</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">share(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">       didChange </span><span class="token" style="color: #d73a49;">=</span><span class="token"> search
</span></span><span class="line"><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;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</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">receive(</span><span class="token">on:</span><span class="token"> DispatchQueue.</span><span class="token">main</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><span class="line"><span class="token">       _cancellable </span><span class="token" style="color: #d73a49;">=</span><span class="token"> search
</span></span><span class="line"><span class="token">           .</span><span class="token">tryMap</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">try</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token">get(</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">catch</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token"> Publishers.</span><span class="token">Just(</span><span class="token">repositories</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;">assign</span><span class="token">(</span><span class="token">to:</span><span class="token"> \.</span><span class="token">repositories</span><span class="token">, </span><span class="token">on:</span><span class="token"> </span><span class="token" style="color: #005cc5;">self</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: #6a737d;">///</span><span class="token" style="color: #6a737d;"> Deinit</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">       _cancellable</span><span class="token" style="color: #d73a49;">?</span><span class="token">.</span><span class="token">cancel(</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">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-261">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-262'
	>
	If this is a bit intimidating, fret not—I’ll go over the operators to make it a bit easier to grasp.</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-heading" data-id="es-264">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-265'
	>
	What’s a flatMapLatest?</h3></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'
	>
	I’ve already mentioned how we’re pushing all text changes into the <code>_textDidChange</code> subject.<br>These get sent into the <code>flatMapLatest</code> operator.<br>If you’re using the first beta of <em>Combine</em>, you won’t be able to find it—you need to make it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-270">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-271'
	>
	Essentially, <code>flatMapLatest</code> can be derived into <code>map</code> and <code>switchToLatest</code> operators. But why do we need it?</p></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'
	>
	Well, <code>map</code> is the same old <code>map</code> provided in <em>Swift</em>, it maps an input to a desired output. We need that to map the search <code>String</code> into an API call returning <code>Repositories</code>.<br>Okay… but what about the <code>switchToLatest</code> operator?</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-paragraph" data-id="es-276">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-277'
	>
	Imagine that you’re typing in a textfield—typing is quite fast.<br>For each character you type, an API call will be made. If we did that we’d absolutely trash the server with all that traffic.</p></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'
	>
	This is where <code>switchToLatest</code> operator comes in handy. It <em>automatically cancels</em> any previously sent events and continues on with the latest one! That way, we only take whatever text we have for the last character coming into the stream.</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'
	>
	Making the operator is pretty straightforward:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-286"
	 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;">Publisher</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">func flatMapLatest</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: #6f42c1;">Publisher</span><span class="token">&gt;</span><span class="token">(</span><span class="token">_ transform</span><span class="token">: </span><span class="token" style="color: #d73a49;">@escaping</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">Self</span><span class="token">.Output</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</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"> </span><span class="token">AnyPublisher</span><span class="token">&lt;</span><span class="token">T.Output, T.Failure</span><span class="token">&gt;</span><span class="token"> </span><span class="token" style="color: #d73a49;">where</span><span class="token"> </span><span class="token">T.Failure </span><span class="token" style="color: #d73a49;">==</span><span class="token"> </span><span class="token" style="color: #005cc5;">Self</span><span class="token">.Failure</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"> </span><span class="token">map(</span><span class="token">transform</span><span class="token">)</span><span class="token">.</span><span class="token">switchToLatest(</span><span class="token">)</span><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 class="token">
</span></span><span class="line"><span class="token">}</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-289"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-287">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-288'
	>
	Let’s (de)bounce forward</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-290">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-291'
	>
	You might’ve also noticed the <code>debounce</code> operator.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-293">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-294'
	>
	Along with <code>debounce</code>, <code>throttle</code> is also one of the operators that saves lives when using <em>RxSwift</em>, so it’s only natural that it found its place in <em>Combine</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-296">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-297'
	>
	So what’s so magical about it? Putting it simply, it does not let any events in the stream pass the point where debounce is placed, as long as the time between each of those events is shorter than the provided time interval.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-299">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-300'
	>
	Huh… it doesn’t sound that simple?<br>Think of it as a valve that is automatically shut if a stream of liquid is bigger than what the pipe can support.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-302">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-303'
	>
	So in the case where a user types fast, any character that comes before the period of <code>0.3</code> seconds has elapsed, will end up being dropped.<br>Once the user stops typing or slows down, events will pass freely for further processing.</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-paragraph" data-id="es-305">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-306'
	>
	This makes it perfect for text inputs because it guards against unintentional DDOS attacks and potential wrath of your sysadmins.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-308">
	
	<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-309'>
	<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-310'
	>
	Note: If you aren’t using Combine beta 2, you’ll end up having quite some trouble setting up debounce since the only supported scheduler in the first beta is the ImmediateScheduler, which is no good in this case.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-313">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-314'
	>
	Share your resources!</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-316">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-317'
	>
	Last, but definitely not the least important operator used is <code>share</code>.</p></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'
	>
	If <code>share</code> wasn’t used then each subscription would re-trigger an API call, or putting it simply, resources wouldn’t be <em>shared</em>.</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-paragraph" data-id="es-322">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-323'
	>
	Using it means that the part of the stream before the operator will get reused across all of its subscriptions, instead of getting invoked again. This avoids triggering further API calls on any of our <code>maps</code>, <code>flatMaps</code>, <code>sinks</code>, etc.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-325">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-326'
	>
	Addressing the model updates</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-329"
	 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">didChange </span><span class="token" style="color: #d73a49;">=</span><span class="token"> search
</span></span><span class="line"><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;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</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">receive(</span><span class="token">on:</span><span class="token"> DispatchQueue.</span><span class="token">main</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-332"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-330">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-331'
	>
	Remember when I mentioned that we need to notify the view on view model value changes? We’re doing it here.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-335"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-333">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-334'
	>
	Once the search event arrives (i.e. the API call finished and the data has been decoded), we’ll notify the view.<br>Since we also don’t care about the type here, the event is mapped into <code>Void</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-338"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-336">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-337'
	>
	It is extremely important that any events <strong><em>sent towards the UI are on the Main thread</em></strong>. Failing to do so will result in undefined behaviour, glitches or a crash. Since we’re doing that using the <code>didChange</code> property, we need to move that stream to the main thread.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-341"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-339">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-340'
	>
	Thankfully, Apple provided a method to do that with <em>Combine</em> in beta 2. It’s done by simply calling the <code>receive(on:)</code> operator in the exact moment when you want to switch.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-344"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-342">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-343'
	>
	Do note that <em>any code that executes below that will run on the thread you’ve assigned it on</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-347"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-345">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-346'
	>
	Is it time to finally update our repositories?!</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-350"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-348">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-349'
	>
	Why yes, it is! And we can do that by using the <code>assign</code> operator.<br>If you’ve used <em>RxSwift</em> you already guessed that this is basically its <code>bind</code> counterpart.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-353"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-351">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-352'
	>
	I’ll also make use of Swift 5’s new <code>Result</code> type and its <code>.get()</code> convenience method. This enables unwrapping an enum’s associated value if it exists, without requiring any conditional checks or switch statements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-356"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-354">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-355'
	>
	However, there’s caveat that it throws if there’s no value. Thankfully, <em>Combine</em> has our backs—we can simply use <code>tryMap</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-359"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-357">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-358'
	>
	Swift will raise a red light though, since all errors need to be handled before using <code>assign</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-364"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-360">
	
	<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-361'>
	<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-362'
	>
	Note: If you’re using sink you’re not required to handle the error. Specifically, you’re able to handle that in a block which it provides.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-367"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-365">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-366'
	>
	To remedy that, we’ll need a <code>catch</code> operator.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-370"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-368">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-369'
	>
	It’s important to use <code>catch</code> when passing data to the UI or when you want to keep your stream alive and well. Unhandled errors will terminate the stream – remember, we can only get one subscription and one error event per stream.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-373"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-371">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-372'
	>
	The closure returns an error and expects a publisher back. That gives us the choice either to handle the error and return a new publisher that’ll keep the stream alive, or simply let the error through.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-376"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-374">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-375'
	>
	Since we don’t care about the error in case, returning existing repositories is fine.</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-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">_cancellable </span><span class="token" style="color: #d73a49;">=</span><span class="token"> search
</span></span><span class="line"><span class="token">   .</span><span class="token">tryMap</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">try</span><span class="token"> </span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token">get(</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">catch</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token"> Publishers.</span><span class="token">Just(</span><span class="token">repositories</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;">assign</span><span class="token">(</span><span class="token">to:</span><span class="token"> \.</span><span class="token">repositories</span><span class="token">, </span><span class="token">on:</span><span class="token"> </span><span class="token" style="color: #005cc5;">self</span><span class="token">)</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-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'
	>
	Main difference compared to <em>RxSwift</em> is that the returned value from <code>assign</code> needs to be stored into <code>_cancellable</code> instead of being stored into a <code>DisposeBag</code>.</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'
	>
	Overall usage is exactly the same, the only caveat being that we need to think about it ourselves during deinit and call cancel.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-387"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-385">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-386'
	>
	On the other hand, the default behaviour of <code>DisposeBag</code> can also be achieved.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-390"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-388">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-389'
	>
	If you want to do that, the returned stream needs to be wrapped into <code>AnyCancellable</code>, which requires a closure upon <code>init</code>. That closure is called upon deinit of the class that’s holding the <code>AnyCancellable</code> object.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-393"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-391">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-392'
	>
	In any case, depending on the approach, just be wary to call cancel if needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-396"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-394">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-395'
	>
	And another thing—if you’re wondering, you can do this by using an approach similar to the <code>.subscribe(onNext:)</code> available in <em>RxSwift</em>. Talking <em>Combine</em> though, you’ll want to use the <code>sink</code> operator:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-398"
	 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">_cancellable </span><span class="token" style="color: #d73a49;">=</span><span class="token"> search
</span></span><span class="line"><span class="token">   .</span><span class="token">sink(</span><span class="token">receiveValue:</span><span class="token"> </span><span class="token">{</span><span class="token"> [</span><span class="token" style="color: #d73a49;">unowned</span><span class="token"> </span><span class="token" style="color: #005cc5;">self</span><span class="token">] result </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"> result </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"> repositories</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: #005cc5;">self</span><span class="token">.</span><span class="token">repositories</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> repositories
</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><span class="line"><span class="token">           </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token">error</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 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-401"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-399">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-400'
	>
	And that’s it! Take a deep, relaxing breath if you’ve made it this far, we’re on the home stretch now.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-404"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-402">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-403'
	>
	What’s left to do is to cover the <code>_getRepositories(using:existingRepositories:)</code> method that you might have noticed all the way up there. That’s the method that’s making the API call and getting the data.</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-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;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">func _getRepositories</span><span class="token">(</span><span class="token">using query</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">, </span><span class="token">existingRepositories</span><span class="token">: </span><span class="token">[</span><span class="token">Repository</span><span class="token">]</span><span class="token"> </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: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">AnyPublisher</span><span class="token">&lt;</span><span class="token">Result</span><span class="token">&lt;</span><span class="token">[</span><span class="token">Repository</span><span class="token">]</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" style="color: #005cc5;">Never</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><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"> request </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">_makeRequest(</span><span class="token">using:</span><span class="token"> query</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 class="token" style="color: #d73a49;">return</span><span class="token"> Publishers.</span><span class="token">Empty(</span><span class="token">)</span><span class="token">.</span><span class="token">eraseToAnyPublisher(</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: #d73a49;">let</span><span class="token"> decoder </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">JSONDecoder(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">   decoder.</span><span class="token">keyDecodingStrategy</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> .</span><span class="token">convertFromSnakeCase</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;">return</span><span class="token"> URLSession.</span><span class="token">shared</span><span class="token">
</span></span><span class="line"><span class="token">       .</span><span class="token">dataTaskPublisher(</span><span class="token">for:</span><span class="token"> request</span><span class="token">)</span><span class="token">
</span></span><span class="line"><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">data</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;">decode</span><span class="token">(</span><span class="token">type:</span><span class="token"> Response</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">Repository</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">.</span><span class="token" style="color: #d73a49;">self</span><span class="token">, </span><span class="token">decoder:</span><span class="token"> decoder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><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">success(</span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token">items</span><span class="token">.</span><span class="token" style="color: #005cc5;">sorted</span><span class="token">(</span><span class="token">by:</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">stargazersCount</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">stargazersCount</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 class="token">
</span></span><span class="line"><span class="token">       .</span><span class="token">catch</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token"> Publishers.</span><span class="token">Just(</span><span class="token">.</span><span class="token">success(</span><span class="token">existingRepositories</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">eraseToAnyPublisher(</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></code></pre></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'
	>
	Simple networking stuff.<br>Creating an <code>URLRequest</code> and an appropriate <code>JSONDecoder</code>, which is then used after the <code>dataTaskPublisher</code> retrieves the data needed for decoding.</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-paragraph" data-id="es-410">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-411'
	>
	Speaking of decoding, a really great addition is the <code>decode</code> operator. It enables decoding on the fly, <em>directly</em> on the stream by simply passing in the decoder. This avoids us having to write all of the boilerplate decoding logic, which is always nice.</p></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'
	>
	Be mindful though, since decoding can also <code>throw</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'
	>
	Lastly, the publisher is type erased so that we lose all those wrapping publisher types (the same thing already seen with SwiftUI) and simply return an <code>AnyPublisher&lt;Result&gt;</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-421"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-419">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-420'
	>
	In case that it’s needed, I’m also attaching the <code>URLRequest</code> creation part:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-423"
	 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;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">func _makeRequest</span><span class="token">(</span><span class="token">using query</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: #d73a49;">-&gt;</span><span class="token"> </span><span class="token">URLRequest</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;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> components </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">URLComponents(</span><span class="token">string:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://api.github.com/search/repositories</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 class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">   components.</span><span class="token">queryItems</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [</span><span class="token">URLQueryItem(</span><span class="token">name:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">q</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, </span><span class="token">value:</span><span class="token"> query</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;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> url </span><span class="token" style="color: #d73a49;">=</span><span class="token"> components.</span><span class="token" style="color: #005cc5;">url</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 class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</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;">var</span><span class="token"> request </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">URLRequest(</span><span class="token">url:</span><span class="token"> url</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">   request.</span><span class="token">addValue(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">application/json</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, </span><span class="token">forHTTPHeaderField:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Content-Type</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><span class="line"><span class="token">   </span><span class="token" style="color: #d73a49;">return</span><span class="token"> request
</span></span><span class="line"><span class="token">}</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-426"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-424">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-425'
	>
	And that’s all folks</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-429"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-427">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-428'
	>
	With this in place, we’re done! Searching now works and repositories are listed and sorted depending on their stargazers count.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-432"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-430">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-431'
	>
	I’m excited to see how we’ll be able to improve the code with further updates. Beta 2 has already provided some <em>Foundation</em> awesomeness which made things quite a bit easier.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-435"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-433">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-434'
	>
	Compared to the initial beta, we’ve gotten the <code>dataTaskPublisher</code> on the <code>URLSession</code> which we’d otherwise have to implement ourselves.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-438"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-436">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-437'
	>
	Most importantly, we’ve gotten other schedulers outside of the initially supplied <code>ImmediateScheduler</code> which wasn’t something we could use. That opened up the possibility to use <code>debounce</code> to throttle the events!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-441"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-439">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-440'
	>
	Next time, we’ll be making a details view that’ll show us some basic information about the repository and its author.</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-paragraph" data-id="es-442">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-443'
	>
	Stay tuned!</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/combine-makes-swiftui-shine/">Combine’s What Makes SwiftUI Really Shine</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7862https://infinum.com/uploads/2019/07/swiftui-is-here-to-knock-uikit-out-of-its-shoes-0.webp</url>
				</image>
				<title>SwiftUI Is Here to Knock UIKit out of Its Shoes</title>
				<link>https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/</link>
				<pubDate>Wed, 03 Jul 2019 16:09:00 +0000</pubDate>
				<dc:creator>Krešimir Valjevac</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/swiftui-is-here-to-knock-uikit-out-of-its-shoes/</guid>
				<description>
					<![CDATA[<p>We were kind of expecting a new UI framework that’s packing Swift’s power under the hood, but the extent of it caught us by surprise.</p>
<p>The post <a href="https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/">SwiftUI Is Here to Knock UIKit out of Its Shoes</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-600"
	 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-447">
	</div>

<div class="block-blog-content-main">
	
<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'
	>
	Another WWDC is behind us and oh boy, did they leave us with some cool new kids in town. We were kind of expecting a new UI framework that’s packing Swift’s power under the hood, but the extent of it caught us by surprise.</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'
	>
	As a team, we’ve generally moved in the direction of writing reactive code (mostly using <em>RxSwift</em>), so when we saw that Apple has decided to move in the same direction with <em>Combine</em>, we were thrilled. To add more fuel, they’ve shown SwiftUI and all of its glory. It looked fun and snappy so we decided to give it a test ride.</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'
	>
	So, today we’ll be making a GitHub search app that uses <em>SwiftUI</em> and <em>Combine</em> under the hood.</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-paragraph" data-id="es-457">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-458'
	>
	Apple released beta 2 versions of both frameworks a few weeks ago, so we’ll be going with that, as it makes developers’ lives a bit easier.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-462"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-460">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-461'
	>
	GitHub search</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-465"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-463">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-464'
	>
	We’ll use GitHub search as an example. It’s very straightforward, and given its features supplied with the current SDK, <em>SwiftUI</em> really shines.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-468"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-466">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-467'
	>
	So, what do we want to make? Something like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-471"
	 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-469"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-470">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2019/07/swiftui-is-here-to-knock-uikit-out-of-its-shoes-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="948"
															width="534"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-474"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-472">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-473'
	>
	Here’s the list of components we need to make in order to get this up and running:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-477"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-475">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-476'
	>
	<li>A List view (obviously)</li><li>A Row view to embed the repository, made of several components</li><li>A <code>ViewModel</code> to drive our data</li></ul></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'
	>
	Along with a couple of smaller tweaks and tricks (I’ll get into them shortly), that’s pretty much all we have to do.. That said – let’s dive in!</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-heading" data-id="es-481">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-482'
	>
	Making a list – the old way</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-486"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-484">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-485'
	>
	If you watched most of the SwiftUI related talks, you’ve probably seen this gem. Up until this point, creating a simple list required many steps like adding a <code>UITableView</code> on a screen, implementing the <code>UITableViewDataSource</code> and the <code>UITableViewDelegate</code> to handle cell selection… and that’s just the UI.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-489"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-487">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-488'
	>
	Additionally, developers had to provide the data source on the presentation layer as well as to make sure the indexes are correct if any changes were made to the data source, etc.</p></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'
	>
	Well, not anymore!</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-heading" data-id="es-493">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-494'
	>
	Making a list – the SwiftUI way</h2></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'
	>
	<em>SwiftUI</em> leverages all of that boilerplate that we needed to write before it came with its declarative handywork. It gives us an object (guess the name of that object) that simply takes a list as a data source and turns that into cells.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-501"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-499">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-500'
	>
	That object is called <code>List</code> and it does all the “heavy lifting” under the hood!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-504"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-502">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-503'
	>
	Making a cell is also as simple as making a simple <code>Text(_ stringLiteral:)</code> view inside the list.</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-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 ListView</span><span class="token"> </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><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">List(</span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</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;">Repository</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 class="token">
</span></span><span class="line"><span class="token">}</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-509"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-507">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-508'
	>
	In the most basic of examples, this is our list.</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-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-511'
	>
	However, we’re making a search-enabled app, meaning we’re still missing a <code>TextField</code>. While we’re at it, let’s customize our row in the list as well.</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-paragraph" data-id="es-513">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-514'
	>
	Modifying views in <em>SwiftUI</em> is as simple as calling methods on existing views in our <em>body</em> property. Those methods are known as <code>modifiers</code>.</p></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'
	>
	An important note though – each time you end up calling a modifier, a wrapper view will be created. That wrapper ends up wrapping the view you’re modifying and it’s represented as <code>_ModifiedContent</code>, which itself conforms to the <code>View</code> protocol.</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-paragraph" data-id="es-519">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-520'
	>
	Essentially, with <em>SwiftUI</em>, we’re building wrappers around our views which in the end represent a single view that was built around aforementioned wrappers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-523"
	 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 ListView</span><span class="token"> </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><span class="line"><span class="token">   </span><span class="token" style="color: #d73a49;">@State</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&quot;</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">TextField(</span><span class="token">$text</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</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">List(</span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">top</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">Image(</span><span class="token">systemName:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">folder</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">font(</span><span class="token">.</span><span class="token">subheadline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                       .</span><span class="token">padding(</span><span class="token">.</span><span class="token">top</span><span class="token">, </span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                       .</span><span class="token">foregroundColor(</span><span class="token">.</span><span class="token">secondary</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">VStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">leading</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Repository</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">font(</span><span class="token">.</span><span class="token">headline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                           .</span><span class="token">lineLimit(</span><span class="token" style="color: #005cc5;">2</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                           .</span><span class="token">layoutPriority(</span><span class="token" style="color: #005cc5;">1000</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Description</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">font(</span><span class="token">.</span><span class="token">caption</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                           .</span><span class="token" style="color: #005cc5;">color</span><span class="token">(</span><span class="token">.</span><span class="token">secondary</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                           .</span><span class="token">lineLimit(</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 class="token">layoutPriority(</span><span class="token" style="color: #005cc5;">999</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">padding(</span><span class="token">.</span><span class="token">leading</span><span class="token">, </span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">top</span><span class="token">, </span><span class="token">.</span><span class="token">bottom</span><span class="token">], </span><span class="token" style="color: #005cc5;">10</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">Spacer(</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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">Divider(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   </span><span class="token">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1</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">padding(</span><span class="token">.</span><span class="token">top</span><span class="token">, </span><span class="token" style="color: #005cc5;">2</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">Image(</span><span class="token">systemName:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">star.fill</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">font(</span><span class="token">.</span><span class="token">subheadline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                           .</span><span class="token">foregroundColor(</span><span class="token">.</span><span class="token">yellow</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">padding(</span><span class="token">.</span><span class="token">leading</span><span class="token">, </span><span class="token" style="color: #005cc5;">10</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 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">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-526"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-524">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-525'
	>
	At this point, we’re almost done with the desired layout.</p></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'
	>
	Adding all that vertically-written layouting code creates a lot of noise. On the plus side, a great feature in <em>SwiftUI</em> is that no one is really stopping you from creating another custom view and then simply constructing that inside of a list.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-532"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-530">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-531'
	>
	This way, code can be divided into smaller components that only handle a piece of the data. Let’s see this in action.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-535"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-533">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-534'
	>
	Making a Row</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-538"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-536">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-537'
	>
	We will first move all the code we had into a separate <code>RepositoryRowView</code>. Since there’s already a lot of code even for that single view, we’ll break that down into smaller chunks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-541"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-539">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-540'
	>
	This is the result we’re aiming for:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-544"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-542">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-543'
	>
	<li>Repository view</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-546"
	 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 RepositoryRowView</span><span class="token"> </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">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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">DetailsContainerView(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">Spacer(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">StarsContainerView(</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">
</span></span><span class="line"><span class="token">struct RepositoryRowView_Previews</span><span class="token"> </span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PreviewProvider </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 previews:</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;">return</span><span class="token"> </span><span class="token">RepositoryRowView(</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">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-549"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-547">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-548'
	>
	<li>Repository details container view</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-551"
	 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 DetailsContainerView</span><span class="token"> </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">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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">top</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">Image(</span><span class="token">systemName:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">folder</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">font(</span><span class="token">.</span><span class="token">subheadline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">padding(</span><span class="token">.</span><span class="token">top</span><span class="token">, </span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">foregroundColor(</span><span class="token">.</span><span class="token">secondary</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">VStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">leading</span><span class="token">, </span><span class="token">spacing:</span><span class="token"> </span><span class="token" style="color: #005cc5;">5</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Repository</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">font(</span><span class="token">.</span><span class="token">headline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token">lineLimit(</span><span class="token" style="color: #005cc5;">2</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token">layoutPriority(</span><span class="token" style="color: #005cc5;">1000</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Description</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">font(</span><span class="token">.</span><span class="token">caption</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token" style="color: #005cc5;">color</span><span class="token">(</span><span class="token">.</span><span class="token">secondary</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token">lineLimit(</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 class="token">layoutPriority(</span><span class="token" style="color: #005cc5;">999</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">padding(</span><span class="token">.</span><span class="token">leading</span><span class="token">, </span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">       .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">top</span><span class="token">, </span><span class="token">.</span><span class="token">bottom</span><span class="token">], </span><span class="token" style="color: #005cc5;">10</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">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-552">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-553'
	>
	<li>Repository stars container view</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-556"
	 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 StarsContainerView</span><span class="token"> </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><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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">HStack(</span><span class="token">alignment:</span><span class="token"> .</span><span class="token">center</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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1</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">padding(</span><span class="token">.</span><span class="token">top</span><span class="token">, </span><span class="token" style="color: #005cc5;">2</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">Image(</span><span class="token">systemName:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">star.fill</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">font(</span><span class="token">.</span><span class="token">subheadline</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                   .</span><span class="token">foregroundColor(</span><span class="token">.</span><span class="token">yellow</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">padding(</span><span class="token">.</span><span class="token">leading</span><span class="token">, </span><span class="token" style="color: #005cc5;">10</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">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-559"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-557">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-558'
	>
	<li>List view</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-561"
	 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 ListView</span><span class="token"> </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" style="color: #d73a49;">@State</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&quot;</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">TextField(</span><span class="token">$text</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</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">List(</span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token">RepositoryRowView(</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 class="token">
</span></span><span class="line"><span class="token">}</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-566"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-562">
	
	<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-563'>
	<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-564'
	>
	@State property wrapper enables SwiftUI to handle memory management of the text variable. Since we’re dealing with value types, it means our view can’t be mutated. Text changes as users type, and without the property wrapper, this wouldn’t be possible.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-569"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-567">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-568'
	>
	Design-wise, the screen is almost done!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-572"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-570">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-571'
	>
	You might notice that, compared to the initial image, a navigation bar is missing, as well as the fact that the design incorporates that new, flashy dark mode. Thankfully, both of these changes are extremely simple to make.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-575"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-573">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-574'
	>
	SwiftUI doesn’t use conventional navigation. Instead, it has an appropriate view that handles navigation. The name of the view is <code>NavigationView</code>, shockingly so.<br>This view will serve as a root and it’ll also be used as a means of setting the <code>colorScheme</code> of the entire view hierarchy to <code>.dark</code>.</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-paragraph" data-id="es-576">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-577'
	>
	Since we’re using system colors, iOS will do the heavy lifting, changing the colors of all the views accordingly.</p></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'
	>
	That being said, let’s replace our root <code>VStack</code> with a <code>NavigationView</code>.<br>We’ll also adjust the <code>listStyle</code>, which is the last change we need to make to match the initial design.</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 ListView</span><span class="token"> </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" style="color: #d73a49;">@State</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&quot;</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">NavigationView</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">           </span><span class="token">TextField(</span><span class="token">$text</span><span class="token">, </span><span class="token">placeholder:</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Search...</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">textFieldStyle(</span><span class="token">.</span><span class="token">roundedBorder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">               .</span><span class="token">padding(</span><span class="token">[.</span><span class="token">leading</span><span class="token">, </span><span class="token">.</span><span class="token">trailing</span><span class="token">], </span><span class="token" style="color: #005cc5;">20</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">List(</span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">5</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token">RepositoryRowView(</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">listStyle(</span><span class="token">.</span><span class="token">grouped</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">environment(</span><span class="token">\.</span><span class="token">defaultMinListRowHeight</span><span class="token">, </span><span class="token" style="color: #005cc5;">50</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">           .</span><span class="token">navigationBarTitle(</span><span class="token">.</span><span class="token" style="color: #d73a49;">init</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">GitHub search</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 class="token">
</span></span><span class="line"><span class="token">       .</span><span class="token">colorScheme(</span><span class="token">.</span><span class="token">dark</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">
</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'
	>
	This wraps up the SwiftUI part for now.</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-paragraph" data-id="es-587">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-588'
	>
	We’ve covered a lot. Don’t miss out on the documentation Apple provided, after all, that’s the ultimate guide for everything SwiftUI-related.</p></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'
	>
	The SDK is not yet complete, but if you get up to speed now, you’ll have less catching up later.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-595"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-593">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-594'
	>
	In our next post, we’ll Combine (get it?) SwiftUI with the logic required to run the app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-598"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-596">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-597'
	>
	See you swiftly!</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/">SwiftUI Is Here to Knock UIKit out of Its Shoes</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>