<?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>Still Using NSNotificationCenter? Try These Alternatives | Infinum</title>
		<atom:link href="https://infinum.com/blog/nsnotificationcenter-alternatives/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/nsnotificationcenter-alternatives/</link>
		<description>Building digital products</description>
		<lastBuildDate>Wed, 08 Apr 2026 14:17:14 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>8019https://infinum.com/uploads/2020/12/NSNotificationCenter-alternatives-0.webp</url>
				</image>
				<title>Still Using NSNotificationCenter? Try These Alternatives</title>
				<link>https://infinum.com/blog/nsnotificationcenter-alternatives/</link>
				<pubDate>Fri, 18 Dec 2020 12:30:00 +0000</pubDate>
				<dc:creator>Hrvoje Hrvoić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/nsnotificationcenter-alternatives/</guid>
				<description>
					<![CDATA[<p>Connecting distant modules in your iOS app with NSNotificationCenter might not be the best way.</p>
<p>The post <a href="https://infinum.com/blog/nsnotificationcenter-alternatives/">Still Using NSNotificationCenter? Try These Alternatives</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-299"
	 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'
	>
	When developing a system in which one module triggers some change, which in some way affects the other, you may stumble upon the problem of communication between <em>non-related code modules</em>. It could be modifying some resource that is used by both modules. If a module does not listen to the changes, it will have the <strong>incorrect data/state</strong>, which means that views depending on that state will show the <strong>wrong UI</strong> to the user.</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'
	>
	<strong>A common way of resolving the mentioned problem on the iOS platform is NotificationCenter</strong>. Nevertheless, some other alternatives can lift your code and increase type safety.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Let’s explore some of them, along with examples.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-102">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-103'
	>
	Communication patterns on iOS</h2></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'
	>
	Communication between iOS objects can be implemented in various ways, the most popular one being the <strong>delegate</strong> pattern. It’s a pattern where some object <em>delegates</em> the work that needs to be done to another object.</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-paragraph" data-id="es-108">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-109'
	>
	The most prominent examples would be UIKit objects (UIViews/ViewControllers), because most of the interaction we have with them is based on the delegate pattern.</p></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'
	>
	Let’s take a widely-used example: the UITableView. Both <em>datasource</em> (used to specify list content) and <em>delegate</em> (used for list UI customization) properties on table view are used to delegate work to an object that uses it. Most often, that will be the view controller.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	With the evolution of the Swift closure syntax, we can use closure callbacks for that purpose. There are other older options like key-value observation and target-action pattern, but those are tied to the Objective C runtime, so we won’t get too deep into that.</p></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'
	>
	Further along, the delegate pattern is often used for event callbacks between two screens in the navigation stack. Delegates are commonly passed via <em>dependency injection</em>, which can be seen in the following snippet:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Code inside view controller</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> nextVc </span><span class="token" style="color: #d73a49;">=</span><span class="token">  </span><span class="token">SomeViewController(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">nextVc.</span><span class="token">delegate</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">self</span><span class="token">
</span></span><span class="line"><span class="token">navigationController.</span><span class="token">pushViewController(</span><span class="token">nextVc</span><span class="token">, </span><span class="token" style="color: #d73a49;">…)
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> For example, In VIPER architecture, inside Wireframe/Router</span><span class="token">
</span></span><span class="line"><span class="token">func showNextScreen</span><span class="token">(</span><span class="token">delegate</span><span class="token">: </span><span class="token">Delegate</span><span class="token">)</span><span class="token">  </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> nextPresenter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">NextScreenPresenter(</span><span class="token" style="color: #d73a49;">…, </span><span class="token">delegate:</span><span class="token"> delegate</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    wireframe.</span><span class="token">show(</span><span class="token" style="color: #d73a49;">…)
</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-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-122">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-123'
	>
	That’s nice and all, but what happens with screens/view controllers that <strong>are not correlated</strong>? How will they communicate events and data?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	Think about the situation when you have some <strong>distant</strong> screens in your app and a change in one of them will need to reflect on the other? In a tab-based application, you could have profile info hidden somewhere under one tab navigation stack. The second one, perhaps a settings screen in some other tab, wants to tell the first one: <em>Hey, I changed the settings that make your current data incorrect, you have to reload!</em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-128">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-129'
	>
	It is a problem when you can’t inject the first screen as a delegate because you <strong>don’t have its reference</strong> by the time you are creating the second one. In this example, the settings screen is clueless about the profile info screen. Also, what if the settings screen wants to inform more than one screen about the change? In that case, the delegate pattern won’t help because, in its nature, it is used for <strong>1-to-1</strong> object communication.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-131">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-132'
	>
	<strong>How to solve that problem?</strong></p></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'
	>
	We must have some shared subject where interested screens/views can subscribe and observe some app-wide events. The Subject, let’s call it that, will hold the list of subscribed objects (<em>Observers</em>) and notify them accordingly when some change happens. How does the Subject know a change has happened? The place (view) where the change occurs has to inform the Subject about the change. The Subject should provide the interface for specifying that events have happened. Also, the Subject does not need to know who its Observers are. They can be subscribed to a particular topic/event, as can be seen in <a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">Pub-Sub</a> pattern, a loose-coupled implementation of the <a href="https://en.wikipedia.org/wiki/Observer_pattern">Observer pattern</a>. It will basically act as a <strong>middleman/event channel</strong> between publishers and subscribers/observers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-137">
	
	<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-138'>
	<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-139'
	>
	When the subject is informed of a change, it will react accordingly, i.e. it will notify all observers.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-142">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-143'
	>
	Exploring NSNotificationCenter and alternative solutions</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-145">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-146'
	>
	Imagine that you’re building a music app and working on a screen that shows a list of songs. This song list changes over time, for example, when a user adds a new favorite song. Whenever this list changes somewhere in the app, the song list screen has to refresh.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-148">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-149'
	>
	Let’s say we want to show a <em>SongListViewController</em> which will show the list of songs in a UITableView. Also, it will handle the data source change via the <em>didUpdate(song:, action:)</em> method where the <code>song</code> property is a song model, and the action is an enum that represents three possible cases of actions available for a song: Update, delete, and create.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">func didUpdate</span><span class="token">(</span><span class="token">song</span><span class="token">: </span><span class="token">Song</span><span class="token">, </span><span class="token">action</span><span class="token">: </span><span class="token">Action</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">switch</span><span class="token"> action </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">update</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;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> index </span><span class="token" style="color: #d73a49;">=</span><span class="token"> datasource.</span><span class="token">firstIndex(</span><span class="token">where:</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">id</span><span class="token"> </span><span class="token" style="color: #d73a49;">==</span><span class="token"> song.</span><span class="token">id</span><span class="token"> </span><span class="token">}</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        datasource</span><span class="token">[</span><span class="token">index</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> song
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> .</span><span class="token">delete</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;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> index </span><span class="token" style="color: #d73a49;">=</span><span class="token"> datasource.</span><span class="token">firstIndex(</span><span class="token">where:</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">id</span><span class="token"> </span><span class="token" style="color: #d73a49;">==</span><span class="token"> song.</span><span class="token">id</span><span class="token"> </span><span class="token">}</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        datasource.</span><span class="token" style="color: #005cc5;">remove</span><span class="token">(</span><span class="token">at:</span><span class="token"> index</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">create</span><span class="token" style="color: #d73a49;">:</span><span class="token">
</span></span><span class="line"><span class="token">        datasource.</span><span class="token" style="color: #005cc5;">append</span><span class="token">(</span><span class="token">song</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">    tableView.</span><span class="token">reloadData(</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-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-153">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-154'
	>
	The common solution: NotificationCenter</h3></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'
	>
	Apple has provided a Pub-Sub pattern for change observation in the Cocoa library called the NSNotificationCenter (<strong>NotificationCenter</strong> in Swift). NotificationCenter is a place where all notifications are posted to and are observed from. Each notification must have a unique way to identify itself, which is the NSNotificationName (<strong>Notification.Name</strong> in Swift). Similarly, if we were to observe, or listen, to any channel, we would call on the observe method available to us through NotificationCenter.default and perform some type of action based on this listening. There are two ways we can subscribe to changes in the NotificationCenter:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-159">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-160'
	>
	<li>selector-based (target-action pattern)</li><li>closure-based</li></ul></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">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-163'
	>
	Selector based</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-166"
	 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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Note: No need to manually remove observer on deinit here, since we are using selector based addObserver</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Subscription is removed automatically since iOS 9</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class SongListViewControllerNCSelector</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongListViewController </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" style="color: #d73a49;">let</span><span class="token"> notificationCenter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> NotificationCenter.</span><span class="token">default</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;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func viewDidLoad</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">        notificationCenter.</span><span class="token">addObserver(</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><span class="line"><span class="token">            </span><span class="token">selector:</span><span class="token"> </span><span class="token" style="color: #005cc5;">#selector</span><span class="token">(</span><span class="token">receiveSongDidUpdate(notification:)</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">name:</span><span class="token"> notificationName</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">object:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@objc</span><span class="token"> </span><span class="token">func receiveSongDidUpdate</span><span class="token">(</span><span class="token">notification</span><span class="token">: </span><span class="token">Notification</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">guard</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">let</span><span class="token"> updatedSong </span><span class="token" style="color: #d73a49;">=</span><span class="token"> notification.userInfo</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;">song</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">as?</span><span class="token"> Song,
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">let</span><span class="token"> action </span><span class="token" style="color: #d73a49;">=</span><span class="token"> notification.userInfo</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;">action</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">as?</span><span class="token"> Action
</span></span><span class="line"><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">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">didUpdate(</span><span class="token">song:</span><span class="token"> updatedSong</span><span class="token">, </span><span class="token">action:</span><span class="token"> action</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-169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-167">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-168'
	>
	Closure/block based:</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-171"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class SongListViewControllerNCClosure</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongListViewController </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 observationToken:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Any</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;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> notificationCenter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> NotificationCenter.</span><span class="token">default</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;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func viewDidLoad</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;">super</span><span class="token">.</span><span class="token">viewDidLoad(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        observationToken </span><span class="token" style="color: #d73a49;">=</span><span class="token"> notificationCenter.</span><span class="token">addObserver(</span><span class="token">forName:</span><span class="token"> notificationName</span><span class="token">, </span><span class="token">object:</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">, </span><span class="token">queue:</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 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">] notification </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;">guard</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">let</span><span class="token"> updatedSong </span><span class="token" style="color: #d73a49;">=</span><span class="token"> notification.userInfo</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;">song</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">as?</span><span class="token"> Song,
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">let</span><span class="token"> action </span><span class="token" style="color: #d73a49;">=</span><span class="token"> notification.userInfo</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;">action</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">] </span><span class="token" style="color: #d73a49;">as?</span><span class="token"> Action
</span></span><span class="line"><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">}</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">didUpdate(</span><span class="token">song:</span><span class="token"> updatedSong</span><span class="token">, </span><span class="token">action:</span><span class="token"> action</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><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> On deiinit of class that wraps/holds the observation token you should remove subscription</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;"> Otherwise it will stay alive, this only happens when using closure based addObserver method</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;"> As discussed here https://oleb.net/blog/2018/01/notificationcenter-removeobserver/</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        notificationCenter.</span><span class="token">removeObserver(</span><span class="token">observationToken</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-174"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-172">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-173'
	>
	Pros</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-177"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-175">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-176'
	>
	<li>using a natively provided solution from Foundation</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-178">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-179'
	>
	Cons</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-181">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-182'
	>
	<li>it is not <em>type-safe</em> – you have to wrap the object of the change under the <strong>userInfo</strong> parameter, which is a [AnyHashable: Any]? dictionary – downcasting the <em>Any</em> placeholder type on the receiver side</li><li>relying on a dictionary key which most of the time will be some string – that became better with Notification. Name</li><li>closure based subscription – you have to unsubscribe manually, or else you’re bound to have memory leaks popping up</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-184">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-185'
	>
	Note: In a multithreaded application, notifications are always <em>delivered on the thread in which the notification was posted</em>, which may not be the same thread in which an observer registered itself. That may be important when updating UI after a model change in the background that posts notification (you would have to dispatch to the main queue).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-187">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-188'
	>
	Custom solution</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-190">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-191'
	>
	If you are an experimental person and tend to implement custom solutions, you could go and see what can be improved in NotificationCenter. For example, making a subscription code in Swift’s type-safety spirit. The implementation of Subject that holds the subscriber can be seen <a href="https://github.com/hhrvoic/observation-ios/blob/master/Observation.playground/Pages/Custom%20Observer.xcplaygroundpage/Sources/CustomSubject.swift">here</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-193">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-194'
	>
	We can expose methods that are required for a particular observation use case in a separate protocol, in this case called <em>SongObserver</em>. Also, to distinguish observation use cases, we can use an enum that will define what can be observed in our app, <em>ObservedType</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">protocol SongObserver</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Observer </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func didUpdate</span><span class="token">(</span><span class="token">song</span><span class="token">: </span><span class="token">Song</span><span class="token">, </span><span class="token">action</span><span class="token">: </span><span class="token">Action</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">enum ObservedType</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">case</span><span class="token"> </span><span class="token">song
</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-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-199'
	>
	Also, our Subject has to expose some interface which will be used for subscription, defined in a <a href="https://github.com/hhrvoic/observation-ios/blob/de8a834fe7101a0026018a58f8d3c642662623ba/Observation.playground/Pages/Custom%20Observer.xcplaygroundpage/Sources/CustomSubject.swift#L25">protocol</a>.</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-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">protocol SubjectProtocol</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func subscribe</span><span class="token">(</span><span class="token">_ observer</span><span class="token">: </span><span class="token">Observer</span><span class="token">, </span><span class="token">for types</span><span class="token">: </span><span class="token">ObservedType…</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;">…rest of protocol methods</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-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'
	>
	Our view controller can now use the Subject for subscribing to song changes:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-207"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class SongListViewControllerCO</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongListViewController </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">let subject:</span><span class="token"> SubjectProtocol </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Subject.</span><span class="token">shared</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">deinit</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">SongListViewController: released from VC stack</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        subject.</span><span class="token">unsubscribeReleasedObservers(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">func viewDidLoad</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;">print</span><span class="token">(</span><span class="token">“SongListViewController</span><span class="token" style="color: #d73a49;">:</span><span class="token"> subscribing </span><span class="token" style="color: #d73a49;">for</span><span class="token"> s</span><span class="token">ong changes”)
</span></span><span class="line"><span class="token">        subject.</span><span class="token">subscribe(</span><span class="token" style="color: #005cc5;">self</span><span class="token">, </span><span class="token">for:</span><span class="token"> .</span><span class="token">song</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><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-208">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-209'
	>
	Since SongListViewControllerCO inherits from the base controller (SongListViewController) which already implements the <em>didUpdate(song:, action:)</em> method, we can just conform to the SongObserver interface and we are good to go.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-212"
	 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;">SongListViewControllerCO</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongObserver </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-215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-213">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-214'
	>
	This approach works well because it offers us type safety. However, the downside is (as with any custom implementation) that you have to do most of the heavy lifting to get everything started: subscriber list filtering, managing subscriptions, observer lifecycles, thinking about memory leaks, and so on.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-216">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-217'
	>
	Rx to the rescue</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-219">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-220'
	>
	RxSwift is part of Rx/ReactiveX family, which is a cross-platform API used for <em>asynchronous programming using observable streams</em>. Everything that can produce values in some period is an <em>Observable</em> or a stream of events/values. Those streams can be composed and transformed via a massive collection of operators that Rx gives us on the plate. Subscribe to stream, and <em>voila!</em>, you are ready to go.</p></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'
	>
	A good example of a stream can be a chain of API calls that go one after another or messages received through a socket. In our example with songs, we can represent updates on a song as a stream of actions that happen on a specific song.</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 see how our song observing example would look like using RxSwift:</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" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class Subject</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> shared </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Subject(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">init</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" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> songDidUpdate </span><span class="token" style="color: #d73a49;">=</span><span class="token"> PublishRelay</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">(</span><span class="token">Song</span><span class="token">, </span><span class="token">Action</span><span class="token">)</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class SongListViewControllerRxBasic</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongListViewController </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> subject </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Subject.</span><span class="token">shared</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;"> Subscriptions are disposed by the DisposeBag when VC deallocates</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"> disposeBag </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">DisposeBag(</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;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func viewDidLoad</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;">super</span><span class="token">.</span><span class="token">viewDidLoad(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        subject
</span></span><span class="line"><span class="token">            .</span><span class="token">songDidUpdate</span><span class="token">
</span></span><span class="line"><span class="token">            .</span><span class="token">asObservable(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            .</span><span class="token">subscribe(</span><span class="token">onNext:</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">]</span><span class="token"> </span><span class="token">(</span><span class="token">song</span><span class="token">, </span><span class="token">action</span><span class="token">)</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" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">didUpdate(</span><span class="token">song:</span><span class="token"> song</span><span class="token">, </span><span class="token">action:</span><span class="token"> action</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 class="token">disposed(</span><span class="token">by:</span><span class="token"> disposeBag</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-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'
	>
	In the example above, you can see that subscribing to changes of an object can be easily made with RxSwift. When an object is updated, onNext closure will be called. When the song is updated with some action, <code>Subject.shared.songDidUpdate.accept((song, action))</code> can be called from any place to notify subscribers. In some cleaner architecture, this Subject would be commonly passed via dependency injection, and it would be <strong>hidden behind the interface</strong> so it could be mockable for unit tests, but that’s a subject for another discussion.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-233">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-234'
	>
	Side note: <em>PublishRelay</em> is a type of observable that can also push/accept values into the stream. Think of it as a pipe that can emit elements, but can also accept new ones from outside.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-236">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-237'
	>
	Also, we can go even further and use <a href="https://github.com/ReactiveX/RxSwift/tree/master/RxCocoa">RxCocoa</a> which provides a beautiful set of reactive extensions for Cocoa/UIKit views. Bindings are nicely written with the declarative style, which is a great thing for readability. For example, if UITableView is one’s weapon of choice for showing lists, RxCocoa offers convenience for binding the data source stream to its cells. This means reloading the cells whenever the data source changes are given to us out of the box. There is no need to implement UITableViewDataSource methods and reload data manually on tableView when the source of data changes. Works like a charm!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-240"
	 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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> UITableViewDatasource implementation not needed</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class SongListViewControllerRxBinding</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongListViewController </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> songStore </span><span class="token" style="color: #d73a49;">=</span><span class="token"> SongStore.</span><span class="token">shared</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"> disposeBag </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">DisposeBag(</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;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func viewDidLoad</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;">super</span><span class="token">.</span><span class="token">viewDidLoad(</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;"> Datasource is defined in code below by binding to tableView.rx.items (reactive way), clear the delegate just in case</span><span class="token">
</span></span><span class="line"><span class="token">        tableView.</span><span class="token">dataSource</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">nil</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        songStore
</span></span><span class="line"><span class="token">            .</span><span class="token">songs</span><span class="token">
</span></span><span class="line"><span class="token">            .</span><span class="token">bind(</span><span class="token">to:</span><span class="token"> tableView.</span><span class="token">rx</span><span class="token">.</span><span class="token">items</span><span class="token">)</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">]</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: #005cc5;">_</span><span class="token">, </span><span class="token">item</span><span class="token">)</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" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Closure for returning cell that is configured with song item</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">let</span><span class="token"> cell </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">self</span><span class="token">.</span><span class="token">instantiateCell(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                cell.</span><span class="token">configure(</span><span class="token">with:</span><span class="token"> item</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"> cell
</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">disposed(</span><span class="token">by:</span><span class="token"> disposeBag</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-243"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-241">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-242'
	>
	Combine &amp; SwiftUI</h3></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'
	>
	As many readers already know, Apple has provided <a href="https://developer.apple.com/xcode/swiftui/">SwiftUI</a>, a new UI framework that allows the declarative definition of views and binding them to the data in a reactive/async manner using the Combine framework. We have already written a lot about it, feel free to check our <a href="https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/">initial post</a> on SwiftUI. Also, make sure you are in the loop with the <a href="https://infinum.com/blog/swiftui-2/">SwiftUI 2.0 changes</a></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'
	>
	Combine is pretty similar to RxSwift and if you already mastered or played around with RxSwift code it should be no problem to at least scratch the surface of Combine. There is also a <a href="https://github.com/CombineCommunity/rxswift-to-combine-cheatsheet">cheatsheet</a> for an easier move from RxSwift to Combine. Combine is a key player in delivering awesome new features that SwiftUI provides such as two-way binding, automatic refreshing of the views that depend on explicitly defined state variables. Also, the usage of property wrappers as a relatively new Swift feature makes it all less boilerplate. Let’s take an example with the list of songs and now implement SwiftUI!</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-heading" data-id="es-250">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-251'
	>
	ObservableObject</h4></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'
	>
	In the example below, SongStore is created and will be used for both storing the songs and notifying the changes. SongStore conforms to the <a href="https://developer.apple.com/documentation/combine/observableobject">ObservableObject</a> protocol, which means it can send a change to its subscribers just before any of its property changes by using default <strong>objectWillChange</strong> <em>Publisher</em> (specified by the protocol itself).</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'
	>
	<em>Publisher</em> can be thought of as <em>Observable</em> in RxSwift world, something that emits a stream of values. When <em>ObservableObject</em> is used in combination with the <strong>@Published</strong> property wrapper, Swift compiler provides synthesized protocol implementation so it emits changes to the Subscriber when any of its <em>@Published</em> properties change. It is anti-boilerplate shorthand so the <code>objectWillChange.send()</code> method does not have to be invoked manually by the programmer when some property changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-259">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-260'
	>
	The example below shows how the SwiftUI view will connect to a SongStore to show a song and automatically refresh on a change in a song list.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">class SongStore</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ObservableObject </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" style="color: #d73a49;">init</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" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> shared </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SongStore(</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;"> When value is changed, publisher under the hood will automatically trigger send()</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;"> and view that observes this will automatically update its body</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@Published</span><span class="token"> </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">var songs:</span><span class="token"> </span><span class="token">[</span><span class="token">Song</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> HardcodedSongs.</span><span class="token">ironMaiden</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SongStore</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token">func didUpdate</span><span class="token">(</span><span class="token">songs</span><span class="token">: </span><span class="token">[</span><span class="token">Song</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">songs</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> songs
</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-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-264">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-265'
	>
	This is what our view will look like:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-268"
	 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;">Song</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Identifiable </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">struct SongListRow</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 item:</span><span class="token"> Song</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">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;">6</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">item.</span><span class="token">name</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">Text(</span><span class="token">item.</span><span class="token">author</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">}</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 SongList</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Whenever this object changes (when song array changes) view will re-render it’s body</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@EnvironmentObject</span><span class="token"> </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">var songStore:</span><span class="token"> SongStore</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"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">ForEach(</span><span class="token">songStore.</span><span class="token">songs</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> song </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">SongListRow(</span><span class="token">item:</span><span class="token"> song</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-271"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-269">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-270'
	>
	If you are seeing SwiftUI code for the first time you will maybe have mixed feelings. It looks easy to read because of its declarative nature, but how does it really work under the hood?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-274"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-272">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-273'
	>
	Under the hood</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-275">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-276'
	>
	In the code above we can see the implementation of a plain SwiftUI view for representing one row in the song list (<em>SongListRow</em>). It will just show Song in a vertical stack in a title-subtitle manner. <em>SongList</em> will be used as a view that will show a list of songs where each song is represented with SongListRow. Here we are using <em>SongStore</em> as an environment object which means it is appropriate to be used by other views in the environment. Since SongStore is <strong>ObservableObject</strong>, whenever it changes, the list will automatically re-render.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-278">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-279'
	>
	This happens <a href="https://www.dictionary.com/browse/automagically" target="_blank" rel="noreferrer noopener">automagically</a> because <strong>@EnvironmentObject</strong> property wrapper indicates that the songStore property is also a state of SwiftUI view. Whenever the state changes, SwiftUI will automatically refresh the part of a view that depends on it. What happens in the background is that SwiftUI view subscribes to <em>objectWillChange</em> Publisher that ObservableObject uses to emit changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-281">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-282'
	>
	The advantage of using EnvironmentObject is that now our shared instance of SongStore is in the environment and ready to be consumed by other SwiftUI views just by specifying @EnvironmentObject inside the property definition. By that, the <strong>injection has to be done only once</strong> (via environmentObject modifier). Another benefit is that <strong>all dependent views refresh</strong> when some of them modify the environment object. Since all views point to the same model in the environment, if one view changes that model, all views will immediately re-render.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> songList </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">SongList(</span><span class="token">)</span><span class="token">.</span><span class="token">environmentObject(</span><span class="token">SongStore.</span><span class="token">shared</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-288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-286">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-287'
	>
	More about the different state variables and what purpose they can be used can be seen in last year’s data flow <a href="https://developer.apple.com/videos/play/wwdc2019/226/">WWDC session</a>. Fresh-out-of the-oven WWDC updates from this year can be seen in this <a href="https://developer.apple.com/videos/play/wwdc2020/10040">video</a>. There is also a nice cheatsheet shared by Chris Eidhof (founder of objc.io) on when to use which property wrapper if you ever get in a dilemma. Also, a nice <a href="https://swiftuipropertywrappers.com/">page</a> expands on it in a couple more words.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-289">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-290'
	>
	Several alternatives to NSNotificationCenter</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-294"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-292">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-293'
	>
	There are many approaches to how your code can react to app-wide changes, so developers have many options to choose from. As seen, there isn’t just the NotificationCenter, but also RxSwift and Combine on the plate. Of course, if you like to experiment, you can always come up with your own system for app-wide callbacks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-297"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-295">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-296'
	>
	If you’re interested in them, a playground project with the examples mentioned in the article can be found <a href="https://github.com/hhrvoic/observation-ios">here</a>, and if you have any tips &amp; tricks of your own, do share!</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/nsnotificationcenter-alternatives/">Still Using NSNotificationCenter? Try These Alternatives</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>