<?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>Make Your iOS Apps Come Alive with Live Activities | Infinum</title>
		<atom:link href="https://infinum.com/blog/live-activities-in-ios-apps/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/live-activities-in-ios-apps/</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>28922https://infinum.com/uploads/2022/10/Live-Activities.webp</url>
				</image>
				<title>Make Your iOS Apps Come Alive with Live Activities</title>
				<link>https://infinum.com/blog/live-activities-in-ios-apps/</link>
				<pubDate>Tue, 18 Oct 2022 09:52:06 +0000</pubDate>
				<dc:creator>Zvonimir Medak</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=28922</guid>
				<description>
					<![CDATA[<p>Live Activities are supported for all phones that can run iOS 16.1, so find out what’s required to integrate them into your iOS apps. </p>
<p>The post <a href="https://infinum.com/blog/live-activities-in-ios-apps/">Make Your iOS Apps Come Alive with Live Activities</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-316"
	 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-14-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	SUMMARY</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-36-text js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	While Android devices have generally gone in the direction of having just a camera cutout or even an under-the-screen camera, Apple has created a brand new user experience with the new camera housing – the notch. Here&#8217;s how to implement it in iOS.</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'
	>
	Apple introduced widgets in iOS 14, allowing us to have glanceable information on our home screens. </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-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	But what if we went a step further and provided contextually relevant information that pops up when needed and doesn’t overstay its welcome? And what if that was done in a way that works seamlessly with the biggest front-facing update our iPhones have seen since the introduction of the notch? No more what ifs – Meet Dynamic Island.</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-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-105"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-106">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-1-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-1-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

	</figure></div></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'
	>
	We’ve covered our feelings about the <a href="https://infinum.com/blog/start-designing-for-dynamic-island-and-live-activities/">Dynamic Island and live activities from the design perspective</a>, and now is the time to show you how to implement them.</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'
	>
	iPhone 14 Pro and 14 Pro Max are the only devices that support the Dynamic Island, but Live Activities are supported for all phones that can run iOS 16.1. So let’s see what’s needed to integrate them into your applications. </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-heading" data-id="es-114">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-115'
	>
	The Live Activity lifecycle, explained</h2></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'
	>
	Lifecycle is one of the most important things to remember when creating apps. Live Activity can be in three states:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-120">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-121'
	>
	<li>Not-started</li><li>Running</li><li>Ended</li></ul></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'
	>
	Your application can have multiple live activities at once, so it’s important to keep track of every activity. Before starting an activity, you must specify what data it needs to use. Since we’re talking about a Live Activity, you can guess that there will be some data that will change over time. Your Live Activity data will be separated into dynamic and static data. Dynamic data can be updated over time and static can’t. </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'
	>
	For example, we’ll take a look at the <strong>FormulaAttributes</strong> structure which will contain both types of data.</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-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 FormulaAttributes</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ActivityAttributes </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">typealias RaceState </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">ContentState</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;"> Here you will provide the dynamic data</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">struct ContentState</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Codable</span><span class="token">, </span><span class="token" style="color: #6f42c1;">Hashable </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">var driverInFront:</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">var driverTeam:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span 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;"> Here you will provide static data</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var lastPlaceDriver:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></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-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-132'
	>
	After starting the activity, it can stay live for eight hours before it ends up being terminated by the system. Eight is enough for most activity use cases, but sometimes you can have an 8-hour flight in which case you wouldn’t be able to track the whole duration with the 8-hour limitation. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-134'
	>
	Once the Live Activity is live and running, you can update the dynamic data of the activity. One thing to note is that you <strong>can’t update</strong> <strong>the Live Activity via API calls like you can with other widgets</strong>. Instead, you must update it via your application or push notifications.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-136">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-137'
	>
	After you end it, the Live Activity will still be available on the Lock Screen for another four hours by default. You can specify if you want to terminate the Lock Screen Live Activity immediately or the system will do it for you after four hours.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-139">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-140'
	>
	Ensure that you update the Live Activity after it ends if you’re not immediately removing it from the Lock Screen to reflect its proper state. That way, your users will have the latest information and know that the Live Activity has ended with the latest results.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-142">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-143'
	>
	How many views does the Live Activity have?</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'
	>
	As mentioned before, you can show the Live Activity on the Lock Screen, Dynamic Island, or a banner on devices that don’t support the Dynamic Island. When you’re developing for devices that have the Dynamic Island support, there are five views:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-148">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-149'
	>
	<li>Minimal</li><li>Leading</li><li>Trailing</li><li>Expanded</li><li>Lock Screen</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-151">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-152'
	>
	Every single one of these views can be different from the other.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-154">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-155'
	>
	Minimal view</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-159"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-157">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-158'
	>
	As the name suggests, it should be minimal, eg. an image that uniquely represents your app. The Minimal view is shown when multiple Live Activities are running at once on the right-hand side of the Dynamic Island with slight padding. Tapping on the view will lead the user straight into your app.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-161">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-2-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-2-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-165"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-163">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-164'
	>
	Leading and Trailing view</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-168"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-166">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-167'
	>
	The leading view will be shown on the left-hand side of Dynamic Island. You can specify some current information from your app related to the Live Activity. Just be careful not to stuff too much information inside the view.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-171"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-169">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-170'
	>
	The trailing view will be shown on the right-hand side of the Dynamic Island. It works just like the leading view, which you can see on the image below for the Formula1 tracking Live Activity ​​that we’ll develop in this example.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-173">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-3-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-3-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-177"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-175">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-176'
	>
	Expanded view</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-178">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-179'
	>
	The expanded view will be shown once the user long-presses the Live Activity and it should be used to display more information about the activity. In our example, we’ll specify which driver is in front and which one is the last. As you can see in the image below, Max is already in first with Latifi sitting in last – a familiar sight if you’ve been watching F1 lately.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-182">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-4-1-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-4-1-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-4-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

	</figure></div></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'
	>
	This example is quite simple – you can customize it by setting the views in particular regions of the expanded view, and the system will try to size them correctly based on the views you’ve provided. You can check out the image below to see which regions are covered with the expanded view.</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-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-187"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-188">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-5-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-5-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-190">
	<h2	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-191'
	>
	Lock Screen view</h2></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&#8217;ll use a similar example to show how it looks on the Lock Screen. An important note here is that we can use a different view for this case. It allows us to reuse the existing UI or create new situation-dependent views for Dynamic Island and Live Activities separately. You can see an example of this below.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-197">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-7-1400x588.webp				media='(max-width: 699px)'
				type=image/webp								height="588"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2022/10/Asset-7-2400x1008.webp				media='(max-width: 1199px)'
				type=image/webp								height="1008"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/Asset-7.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1150"
															width="2738"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-199">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-200'
	>
	Getting your first Live Activity Live</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-204"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-202">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-203'
	>
	First of all, Live Activities are available from iOS 16.1, and I’ll be using Beta Xcode 14.1 for this example.</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-paragraph" data-id="es-205">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-206'
	>
	After you’ve decided on which app you want to liven up, head into Xcode, and under the targets section, you can find a “+” sign where you can add a widget extension.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-209">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2022/10/widget-1400x957.webp				media='(max-width: 699px)'
				type=image/webp								height="957"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2022/10/widget.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1266"
															width="1852"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-211">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-212'
	>
	After you’ve added the widget extension head into the&nbsp;<strong>Info.plist</strong>&nbsp;file of your application and add a boolean flag for the Supports Live Activities permission and set it to YES.</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-paragraph" data-id="es-214">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-215'
	>
	Now we’re ready to get this show on the road. First, we’ll define the&nbsp;<strong>FormulaAttributes</strong>&nbsp;I’ve mentioned above. It conforms to the&nbsp;<strong>ActivityAttributes</strong>&nbsp;protocol which helps us define dynamic data inside our structure. Make sure that when you create the&nbsp;<strong>FormulaAttributes.swift</strong>&nbsp;file you include it in both the App and the Widget target.&nbsp;</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-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-217'
	>
	Before we dive into the code, when starting your Activity your application has to be in the foreground while you can update or end it in the background.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-219">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-220'
	>
	Starting the Live Activity</h2></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'
	>
	First, we’ll add a button and a reference to our Activity inside the <strong>ContentView</strong>. The Activity will be set as optional since we want to create it when we need it and the reference is kept so we can update the correct Live Activity later.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-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 ContentView</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">var activity:</span><span class="token"> Activity</span><span class="token">&lt;</span><span class="token">FormulaAttributes</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var body:</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">VStack(</span><span class="token">spacing:</span><span class="token"> </span><span class="token" style="color: #005cc5;">20</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">Button(</span><span class="token">action:</span><span class="token"> </span><span class="token">{</span><span class="token"> activity </span><span class="token" style="color: #d73a49;">= startActivi</span><span class="token">ty(</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">, </span><span class="token">label:</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Start Activity</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-227">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-228'
	>
	The compiler will complain that there’s no startActivity function and we’ll add it inside a private extension on the <strong>ContentView</strong>. The <strong>startActivity</strong> function will return the newly created Activity.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-231"
	 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;">extension</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ContentView</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 startActivity</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">Activity</span><span class="token">&lt;</span><span class="token">FormulaAttributes</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">var activity:</span><span class="token"> Activity</span><span class="token">&lt;</span><span class="token">FormulaAttributes</span><span class="token">&gt;</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;">let</span><span class="token"> attributes </span><span class="token" style="color: #d73a49;">= Formula</span><span class="token">Attributes(</span><span class="token">lastPlaceDriver:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Nicholas Latifi</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;">d</span><span class="token" style="color: #d73a49;">o</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"> contentState </span><span class="token" style="color: #d73a49;">= FormulaAttr</span><span class="token">ibutes.</span><span class="token">ContentState(</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">driverInFront:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Max Verstappen</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,
</span></span><span class="line"><span class="token">                </span><span class="token">driverTeam:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Red Bull racing</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            activity </span><span class="token" style="color: #d73a49;">= try Activit</span><span class="token">y</span><span class="token" style="color: #d73a49;">&lt;FormulaAttri</span><span class="token">butes</span><span class="token" style="color: #d73a49;">&gt;.request(att</span><span class="token">ributes:</span><span class="token"> attributes</span><span class="token">, </span><span class="token">contentState:</span><span class="token"> contentState</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" style="color: #d73a49;">catch</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">error.</span><span class="token">localizedDescription</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</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"> activity
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-234"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-232">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-233'
	>
	Now that we’ve covered the implementation of our Live Activity, we can start looking into activity updates.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-235">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-236'
	>
	Updating the Live Activity</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-240"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-238">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-239'
	>
	Add another button inside the content view just like the one we added in order to start the activity and call the <strong>updateActivity</strong> function. Inside the private extension of the <strong>ContentView</strong> add the following function:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 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 updateActivity</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">Task</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"> contentState </span><span class="token" style="color: #d73a49;">= Formula</span><span class="token">Attributes.</span><span class="token">ContentState(</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">driverInFront:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">not Lewis Hamilton</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">driverTeam:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Mercedes</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> 
</span></span><span class="line"><span class="token">        </span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">await</span><span class="token"> activity</span><span class="token" style="color: #d73a49;">?.update(</span><span class="token">using:</span><span class="token"> contentState</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-243">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-244'
	>
	The function will get the reference we kept for our activity and call the <strong>.update(using:)</strong> function with some new content. It is wrapped inside a <strong>Task</strong> since it’s an async function.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-246">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-247'
	>
	This example shows how to update our Live Activity from the app, but as mentioned before, you can also do that using push notifications. The code would differ a bit from our example and you’d have to start the Live Activity by specifying the <strong>pushType</strong> parameter. You’d need to send the <strong>pushToken</strong> from your Live activity to the server so it can receive notifications.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-249">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-250'
	>
	Ending the Live Activity</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-252">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-253'
	>
	Ending the Live Activity can also be done via notifications or from the app. As I’ve mentioned before, make sure that you have updated the Live Activity with the latest information before you end it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-255">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-256'
	>
	Add another button to the&nbsp;<strong>ContentView</strong>&nbsp;which will reference the&nbsp;<strong>endActivity</strong>&nbsp;function. Inside the private extension of the&nbsp;<strong>ContentView</strong>&nbsp;add the following function:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-259"
	 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 endActivity</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">Task</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">for</span><span class="token"> activit</span><span class="token">y </span><span class="token" style="color: #d73a49;">in</span><span class="token"> Activity</span><span class="token" style="color: #d73a49;">&lt;FormulaA</span><span class="token">ttributes</span><span class="token" style="color: #d73a49;">&gt;.activit</span><span class="token">ies </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">await</span><span class="token"> activity.</span><span class="token" style="color: #005cc5;">end</span><span class="token">(</span><span class="token">dismissalPolicy:</span><span class="token"> .</span><span class="token">immediate</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-262"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-260">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-261'
	>
	The&nbsp;<strong>endActivity</strong>&nbsp;function goes through all of the started Live Activities with the&nbsp;<strong>FormulaAttributes</strong>&nbsp;and ends them while specifying that it should remove the Lock Screen activity immediately. Just like the&nbsp;<strong>update(using:)</strong>&nbsp;function, the&nbsp;<strong>end(dismissalPolicy:)</strong>&nbsp;is an async function as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-263">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-264'
	>
	Live Activity user interface</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-268"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-266">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-267'
	>
	Since we’re using only the Live Activity Widget for this example, we’ll annotate it with @main. If you’re using more Widgets, please add them to a <strong>WidgetBundle</strong>. The code below shows the user interface for our formula Widget which was used for prior screenshots.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-270"
	 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;">@main</span><span class="token">
</span></span><span class="line"><span class="token">struct FormulaActivityWidget</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Widget </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"> WidgetConfiguration </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">ActivityConfiguration(</span><span class="token">for:</span><span class="token"> FormulaAttributes.</span><span class="token" style="color: #d73a49;">self</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> context </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;"> Create a view here which will be shown on the Lock Screen and on the Home Screen as a banner</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;"> For the devices which don&#039;t support the Dynamic Island</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token"> </span><span class="token">dynamicIsland:</span><span class="token"> </span><span class="token">{</span><span class="token"> context </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">DynamicIsland</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> This content will be shown when the user expands the island</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">DynamicIslandExpandedRegion(</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">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">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Driver in front is </span><span class="token" style="color: #032f62;">\(</span><span class="token" style="color: #032f62;">context.</span><span class="token" style="color: #032f62;">state</span><span class="token" style="color: #032f62;">.</span><span class="token" style="color: #032f62;">driverInFront</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;"> ?</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                        </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Last place driver is </span><span class="token" style="color: #032f62;">\(</span><span class="token" style="color: #032f62;">context.</span><span class="token" style="color: #032f62;">attributes</span><span class="token" style="color: #032f62;">.</span><span class="token" style="color: #032f62;">lastPlaceDriver</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token">}</span><span 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">}</span><span class="token"> </span><span class="token">compactLeading:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> This view is shown on the left side of the Dynamic Island</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;">?</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 class="token">compactTrailing:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> This view is shown on the right side of the Dynamic Island</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;">timer</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 class="token">minimal:</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> This view will be shown when there are multiple activities running at ones</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;">?</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 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-273"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-271">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-272'
	>
	Inside the Widget, we specify the <strong>ActivityConfiguration</strong> and which Attributes it’s going to use. First, we’ll set the views on the Dynamic Island, and afterwards we’ll add the Lock Screen one. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-276"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-274">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-275'
	>
	As it’s a simple example, I’ve only used the center region of the Expanded view to set some data inside. Afterward, there are closures describing which part of the Dynamic Island it covers so you can put whichever view you want it to show.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-279"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-277">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-278'
	>
	Now we can set the Lock Screen and the Home banner view. Here’s a Lock Screen view which will have a reference to the context from our attributes so it can be updated properly.</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-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 LockScreenLiveActivityView</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 context:</span><span class="token"> ActivityViewContext</span><span class="token">&lt;</span><span class="token">FormulaAttributes</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">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">Text(</span><span class="token">“Driver </span><span class="token" style="color: #d73a49;">in</span><span class="token"> front </span><span class="token" style="color: #d73a49;">is</span><span class="token"> \</span><span class="token">(</span><span class="token">context.</span><span class="token">state</span><span class="token">.</span><span class="token">driverInFront</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">?“)
</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">Text(</span><span class="token">“Last place driver </span><span class="token" style="color: #d73a49;">is</span><span class="token"> \</span><span class="token">(</span><span class="token">context.</span><span class="token">attributes</span><span class="token">.</span><span class="token">lastPlaceDriver</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">?“)
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        .</span><span class="token">activitySystemActionForegroundColor(</span><span class="token">.</span><span class="token">white</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        .</span><span class="token">activityBackgroundTint(</span><span class="token">.</span><span class="token">cyan</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-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'
	>
	After you’ve created the Lock Screen view, initialize it inside the closure for the <strong>ActivityConfiguration</strong>. And there you have it, you can now run the app and test it out.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-287"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-285">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-286'
	>
	Adding DeepLinking inside the Expanded view</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-290"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-288">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-289'
	>
	Since the Live Activity is a Widget, it can deep link into your app. Every Live Activity view can lead to a different place inside your app, but Apple still recommends that the leading and trailing views lead to the same place. DeepLinking is a great tool to add inside the expanded view where you can have multiple views, some of which could navigate where you need them.</p></div>	</div>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-296"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-294">
	<ul	class='typography typography--size-18-text-roman js-typography lists__typography'
	data-id='es-295'
	>
	<li>Live Activities can be disabled in the Settings App. You can check if that’s the case and provide a proper explanation to the user, telling them what they’re missing out on</li><li>Make sure to handle the errors with care. Users can have multiple Live Activities running at the same time, and you could also reach a state where your app started too many activities. Make sure you’re not one of the offenders that does this</li><li>The system ignores any animation modifiers when defining the user interface of the Live Activity, but you can modify the animations Apple’s using to create a more unique experience</li><li>Live Activities will be rendered in Dark Mode when the Always-On Retina is on</li><li>Use app updates alongside push notification updates. Sometimes the user won’t receive a push notification due to not having an internet connection or if the Live Activity has ended.</li><li>When using push notifications, the system might throttle your push notifications, and the user might not receive them if you’ve sent too many notifications. This is crucial if you’re building a Live Activity for Formula where you’ll have a lot of updates on the grid. One way to still send a push notification is to send a low-priority one, but no one can guarantee that the user will receive it</li><li>The system can display Live Activities even on devices that don’t support the Dynamic Island as a banner on the Home Screen, but only if the app determines that the update is important enough to interrupt people</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-299"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-297">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-298'
	>
	The finish line</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-300">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-301'
	>
	Live Activities are a new way to show information at a glance. The animations and different views make Live Activities unique from other widgets. Tailor the Live Activities to your app’s needs and make it a unique yet pleasant experience that the users can enjoy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-305"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-303">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-304'
	>
	PS. We probably don’t even need to update our Live Activity since Max most likely won.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-308"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-306">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-307'
	>
	Hope you enjoyed the article and happy coding, we’re looking forward to seeing your own live activities out in the wild!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-311"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-309">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-310'
	>
	Useful links</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-314"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-312">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-313'
	>
	<li><a target="_blank" href="https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities" rel="noreferrer noopener">https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities</a></li><li><a target="_blank" href="https://developer.apple.com/documentation/activitykit/update-and-end-your-live-activity-with-remote-push-notifications" rel="noreferrer noopener">https://developer.apple.com/documentation/activitykit/update-and-end-your-live-activity-with-remote-push-notifications</a></li><li><a target="_blank" href="https://developer.apple.com/documentation/activitykit" rel="noreferrer noopener">https://developer.apple.com/documentation/activitykit</a></li></ul></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/live-activities-in-ios-apps/">Make Your iOS Apps Come Alive with Live Activities</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>