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

					<item>
				<image>
					<url>19255706https://infinum.com/uploads/2024/07/Accessibility_changes_coming_to_iOS-hero-min.webp</url>
				</image>
				<title>A First Look at Apple’s New Accessibility Features in iOS 18</title>
				<link>https://infinum.com/blog/new-accessibility-features-in-ios-18/</link>
				<pubDate>Wed, 03 Jul 2024 13:02:32 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19255706</guid>
				<description>
					<![CDATA[<p>Learn about the game-changing new accessibility features in iOS 18. Explore how Apple is transforming device interaction for all users.</p>
<p>The post <a href="https://infinum.com/blog/new-accessibility-features-in-ios-18/">A First Look at Apple’s New Accessibility Features in iOS 18</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-141"
	 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-36-text js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	<strong>From Eye Tracking and Music Haptics to CarPlay updates, the new accessibility features in iOS 18 promise to transform how users interact with their devices, further strengthening Apple’s position as an accessibility powerhouse.</strong></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'
	>
	Apple’s history of pioneering accessibility features for iOS dates all the way back to 2009. That was when the launch of the iPhone 3GS introduced VoiceOver – still a flagship feature that is typically the first one to become supported in most apps.</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'
	>
	In a recent update, 15 years after the initial VoiceOver release, Apple announced <a href="https://www.apple.com/newsroom/2024/05/apple-announces-new-accessibility-features-including-eye-tracking/" target="_blank" rel="noreferrer noopener">new accessibility features in iOS 18 and iPadOS 18</a>, coming this fall. They are some of the most innovative and complex ones so far. </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'
	>
	Since we got the opportunity to try out the features during beta testing, we can confirm from experience that they are indeed quite impressive. Have you ever imagined being able to control your phone using just your eyes? Or <em>feel</em> the music? By leveraging the power of artificial intelligence, Apple’s ecosystem is becoming more accessible to even more people, and this year feels like a major milestone in the Cupertino company’s accessibility journey.</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-heading" data-id="es-105">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-106'
	>
	Eye Tracking</h2></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'
	>
	A truly revolutionary feature that was originally developed for Apple Vision Pro made its way to iOS and iPadOS. Designed for people with physical disabilities, Eye Tracking offers a completely new way of controlling our phone or tablet. Users can move through app elements and utilize Dwell Control to select each one, enabling additional functions like physical buttons, swipes, and other gestures using only their eyes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-111'
	>
	<strong>Eye Tracking is set up in less than a minute and uses a front-facing camera with advanced AI algorithms to detect and interpret eye movements. It comes with a set of gestures like looking at specific areas or blinking, and you can customize the sensibility and accuracy according to preference. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-113">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-114'
	>
	Further, Eye Tracking can conveniently be triggered from shortcuts or Siri and is integrated with AssistiveTouch, a virtual, on-screen menu that allows users to perform various actions, such as accessing the Home screen, adjusting volume, taking screenshots, and using gestures, without needing to use physical buttons.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-116">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-117'
	>
	Having tested the feature in the very first beta release, we must admit that it still feels a little rough around the edges. However, it will undoubtedly prove very handy in many use cases, which can also be said for Music Haptics.</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-heading" data-id="es-119">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-120'
	>
	Music Haptics</h2></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'
	>
	The feature introduces a new way for people who are deaf or hard of hearing to experience music on the iPhone. When Music Haptics is turned on, the iPhone will use its Taptic Engine to work in sync with the audio to generate patterns of taps, textures, and vibrations.</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'
	>
	The feature not only enhances the Apple Music experience but can add another dimension to sound in third-party apps. Developers can take advantage of Apple’s API and add Music Haptics to their own music applications.</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'
	>
	We should note that this is an iPhone-only feature because the hardware that supports it is not included on the iPad.</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-heading" data-id="es-131">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-132'
	>
	Listen for Atypical Speech &amp; Vocal Shortcuts</h2></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'
	>
	Introduced in May 2023, Atypical Speech has already been available in iOS 17. The feature enhances the communication experience through personalized speech recognition and text-to-speech functionalities.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	Primarily intended for people with acquired or progressive conditions that affect speech, such as cerebral palsy, amyotrophic lateral sclerosis (ALS), or stroke, the feature leverages artificial intelligence to improve speech recognition for a wide range of users.</p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-143">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/Accessibility_changes_coming_to_iOS-in-article-img_5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="944"
															width="1360"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-150"
	 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-145">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-146">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-147'
	>
	In close connection with this, Vocal Shortcuts allows users to perform hands-free actions by using custom voice commands, making the process easier and more efficient. </p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-152">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/Accessibility_changes_coming_to_iOS-in-article-img_4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="944"
															width="1360"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-175"
	 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-154">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-155">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-156'
	>
	This is a perfect example of how an accessibility feature can prove useful not only to people with disabilities but to a far wider group of users. Performing specific actions using voice controls can be very helpful in a number of professional environments, such as medical institutions, car repair shops, or manufacturing facilities, or simply in everyday situations when our hands are occupied, like when we’re cooking or driving. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-158"
	 target='_blank' rel='noopener noreferrer' href='https://infinum.com/blog/digital-product-accessibility/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<h2	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-159'
	>
	Want to learn more about digital product accessibility? Here&#8217;s how to build solutions that leave no user behind.</h2>		</div>

		<button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-161"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-162'
	>
	Read the article </div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-163'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-165">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-166'
	>
	Vehicle Motion Cues</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-169'
	>
	Motion sickness is usually caused by a conflict between what we see and what we feel, which can prevent people from using devices in a moving vehicle.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-171">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-172'
	>
	The Vehicle Motion Cues feature can be turned on in the Control Center, and the device&#8217;s screen will display a set of dots on the edges, animated in sync with the vehicle’s motion. Using on-device sensors, this feature recognizes when a user is in a moving vehicle and responds to its movement accordingly.</p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<div class="video__wrapper" data-id="es-177">
		<video
		class="video block-media__video js-video js-block-media-video video--cursor-takeover-use"
		 loop autoplay playsinline muted preload='metadata'>
		<source  src='https://infinum.com/uploads/2024/07/ScreenRecording_07-02-2024_14-38-34_1.mp4' type='video/mp4' />	</video>
	</div></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-232"
	 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-179">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-181'
	>
	Even though I can’t quite remember the last time I felt motion sickness (and if we decide to ignore the fact that Apple is helping us stay glued to our phones even during road trips), this is a well-functioning feature that has the potential to help many people.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-183">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-184'
	>
	CarPlay</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-186">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-187'
	>
	If you own a vehicle that supports CarPlay, you’ll be able to use Voice Control to navigate the user interface and manage apps hands-free by using your voice. In addition, CarPlay now supports Sound Recognition, which alerts drivers and passengers who are deaf or have hearing difficulties to important auditory cues such as honking cars, sirens, and other noises.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-189">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-190'
	>
	Colorblind users will benefit from Color Filters, which are introduced to the CarPlay interface along with other visual accessibility features like Bold Text and Large Text, improving the UI’s readability and usability.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-192">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-193'
	>
	Other accessibility enhancements </h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-195">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-196'
	>
	Aside from introducing new accessibility features in iOS 18, Apple announced a number of useful updates to some of the existing ones. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-198">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-199'
	>
	<strong>VoiceOver</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-200'
	>
	Users who are blind or have low vision will benefit from new voices, a flexible Voice Rotor, customizable volume control, and the ability to customize keyboard shortcuts on a Mac.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-202">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-203'
	>
	<strong>Magnifier</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-204'
	>
	Introduces a new Reader Mode and easier access to Detection Mode using the Action button. </p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-209"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-206">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-207'
	>
	<strong>Braille</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-208'
	>
	Faster Braille Screen Input, Japanese language support, multi-line braille with Dot Pad, and the option to choose different input and output labels. </p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-210">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-211'
	>
	<strong>Switch Control</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-212'
	>
	The feature will enable the users to use the cameras on their iPhones and iPads to recognize finger-tap gestures as switches.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-217"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-214">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-215'
	>
	<strong>Hover Typing</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-216'
	>
	Users with low vision will be able to display larger text in preferred fonts and colors when typing in text fields.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-218">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-219'
	>
	<strong>Personal Voice</strong></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-220'
	>
	Originally introduced in iOS 17, the feature allows users who have difficulty pronouncing or reading full sentences to create a Personal Voice using shortened phrases, and it will now be available in Mandarin Chinese.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-224"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-222">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-223'
	>
	Discover Apple’s new accessibility features in iOS 18 this fall</h2></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'
	>
	Over the past 15 years, Apple has introduced continuous innovation in the accessibility space, designing a variety of features that benefit all users, but especially those who rely on them the most. Now, leveraging the power of artificial intelligence for new accessibility features in iOS 18, Apple is unlocking new ways of interaction with their devices, making them even more intuitive and impactful.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-230"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-228">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-229'
	>
	With Eye Tracking and Music Haptics at the forefront and a heap of accessibility features to boot, the iPhone strengthens its position as the industry leader in accessibility. Most of these features will be available with the release of iOS 18 and iPadOS 18 this fall, promising an even more inclusive and user-friendly experience for everyone.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/new-accessibility-features-in-ios-18/">A First Look at Apple’s New Accessibility Features in iOS 18</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>51947https://infinum.com/uploads/2024/03/Top-iOS-libraries-hero-min.webp</url>
				</image>
				<title>The Best iOS Libraries in 2024</title>
				<link>https://infinum.com/blog/best-ios-libraries-2024/</link>
				<pubDate>Wed, 13 Mar 2024 14:17:52 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=51947</guid>
				<description>
					<![CDATA[<p>A curated list of the best iOS libraries to support your development efforts in 2024. </p>
<p>The post <a href="https://infinum.com/blog/best-ios-libraries-2024/">The Best iOS Libraries in 2024</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-404"
	 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-233">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-236"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-234">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-235'
	>
	<strong>Third-party libraries shorten development time, provide easy access to additional features, and help us focus on the core aspects of our projects. Once again, we present you with our selection of the best iOS libraries of the year. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-239"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-237">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-238'
	>
	Any iOS engineer&#8217;s day would be much more complicated without the many tools and libraries supporting the development process.</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-paragraph" data-id="es-240">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-241'
	>
	Knowing which libraries to use is essential for shortening development time and finding better solutions to common problems. This article showcases all the libraries our iOS team loves to use and utilize, as well as the ones we have created for our needs.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-243">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-244'
	>
	Libraries never go out of style</h2></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'
	>
	We&#8217;ve been presenting our top selection of libraries since <a href="https://infinum.com/blog/top-10-ios-swift-libraries-every-ios-developer-should-know-about/" target="_blank" rel="noreferrer noopener">2015</a> and showed you some of our favorite ones in <a href="https://infinum.com/blog/top-10-most-useful-iOS-libraries/" target="_blank" rel="noreferrer noopener">2020</a> and <a href="https://infinum.com/blog/ios-libraries-2021/" target="_blank" rel="noreferrer noopener">2021</a>. It is important to write about this topic from time to time since our work is sometimes heavily concentrated on using libraries and even creating new ones. </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-paragraph" data-id="es-249">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-250'
	>
	This year, we&#8217;re bringing a selection of tools we use the most. Some of them are oldies but goldies that continue to stay relevant for our everyday work.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-252">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-253'
	>
	Obligatory side note on using libraries responsibly</h2></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-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-256'
	>
	Keep in mind that using third-party libraries comes with a responsibility. If you plan to use the libraries on the list, or any libraries in fact, you should ask yourself these two questions first:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-258">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-259'
	>
	<li>Do you plan to use the library in only one place for a single feature, bringing no other value to the rest of the app?</li><li>Is this library supported and maintained regularly by its developers?</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-261">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-262'
	>
	If both of your answers are yes, feel free to take it to the next level.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-264">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-265'
	>
	Our selection of the best iOS libraries in 2024 </h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-267">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-268'
	>
	SnapKit</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-270">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-271'
	>
	I couldn&#8217;t imagine a world without <a href="https://github.com/SnapKit/SnapKit" target="_blank" rel="noreferrer noopener">this library</a>, and I would immediately notice it missing from the project. It is a simple and powerful tool for defining constraints, resulting in better, more responsive, and faster development. Its fluent and expressive syntax provides many functionalities, including anchoring views, simplifying aspect ratio, and other advanced features.</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-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"> box </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">UIView(</span><span class="token">)</span><span class="token"> 
</span></span><span class="line"><span class="token">view.</span><span class="token">addSubview(</span><span class="token">box</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">box.</span><span class="token">snp</span><span class="token">.</span><span class="token">makeConstraints</span><span class="token"> </span><span class="token">{</span><span class="token"> constraints </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">  constraints.</span><span class="token">center</span><span class="token">.</span><span class="token">equalToSuperview(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  constraints.</span><span class="token">width</span><span class="token">.</span><span class="token">height</span><span class="token">.</span><span class="token">equalTo(</span><span class="token" style="color: #005cc5;">50</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-275">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-276'
	>
	Firebase</h3></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'
	>
	It&#8217;s hard to call <a href="https://github.com/firebase/firebase-ios-sdk" target="_blank" rel="noreferrer noopener">Firebase</a> just a library since it contains a suite of tools that simplify different aspects of app development, such as authentication, real-time databases, cloud storage, messaging, analytics, crashlytics, and more. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-282"
	 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">Auth.</span><span class="token">auth(</span><span class="token">)</span><span class="token">.</span><span class="token">signIn(</span><span class="token">withEmail:</span><span class="token"> email</span><span class="token">, </span><span class="token">password:</span><span class="token"> password</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> authResult, error </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> error =</span><span class="token" style="color: #d73a49;"> error {
</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;">Error logging in: </span><span class="token" style="color: #032f62;">\(</span><span class="token" style="color: #032f62;">error.</span><span class="token" style="color: #032f62;">localizedDescription</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" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">User logged in successfully!</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-283">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-284'
	>
	Firebase is well adapted across our projects and has become our tool of choice for achieving the goals mentioned above. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-286">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-287'
	>
	KeychainAccess</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-289">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-290'
	>
	<a href="https://github.com/kishikawakatsumi/KeychainAccess" target="_blank" rel="noreferrer noopener">A popular library in Swift</a> with the primary goal of simplifying interaction with the Keychain. It offers a simple and easy set of APIs for storing, retrieving, and managing secure information. We recommend using it if you want to enhance your app&#8217;s security and protect its data from unauthorized access. For example, you can see how easy it is to save and get a password from the Keychain.</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-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"> keychain </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Keychain(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">try</span><span class="token" style="color: #d73a49;">?</span><span class="token"> keychain.</span><span class="token" style="color: #005cc5;">set</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">password</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, </span><span class="token">key:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">myAccount</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> password </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">try</span><span class="token" style="color: #d73a49;">?</span><span class="token"> keychain.</span><span class="token">get(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">myAccount</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-296"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-294">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-295'
	>
	Sourcery</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-299"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-297">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-298'
	>
	<a href="https://github.com/krzysztofzablocki/Sourcery" target="_blank" rel="noreferrer noopener">Sourcery</a> is a powerful code generation tool that automates repetitive tasks using user-defined templates. This is very useful in mocking when you have to create many new testing files that just use different class names. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">span data</span><span class="token" style="color: #d73a49;">-</span><span class="token">es</span><span class="token" style="color: #d73a49;">-</span><span class="token">language</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">c</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">span</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">lass UserViewInterfaceMock</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">ViewInterface</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> setUsernameCalled </span><span class="token" style="color: #d73a49;">= fal</span><span class="token" style="color: #005cc5;">se</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var setUsernameReceivedValue:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func setUsername</span><span class="token">(</span><span class="token">username</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        setUsernameCalled </span><span class="token" style="color: #d73a49;">= true
</span></span><span class="line"><span class="token">        setUsernameReceivedValue</span><span class="token" style="color: #d73a49;">:</span><span class="token"> username    
</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-304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-302">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-303'
	>
	With Sourcery, you need to make your protocol inherit Automockable, and you are all set. Also, the last thing to mention is that Sourcery works with SwiftLint, so all your generated lines will conform to best practices from the beginning.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-305">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-306'
	>
	SwiftLint</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-308">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-309'
	>
	<a href="https://github.com/realm/SwiftLint" target="_blank" rel="noreferrer noopener">SwiftLint</a> is an extensively used and highly configurable library that enforces Swift&#8217;s writing style and conventions for Xcode projects. It helps keep a consistent and readable codebase by applying a set of rules defined by the creator and the development team. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-313"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-311">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-312'
	>
	Lottie</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-316"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-314">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-315'
	>
	<a href="https://airbnb.design/lottie/" target="_blank" rel="noreferrer noopener">Lottie</a> is a valuable tool for developers who are always trying to enhance their apps&#8217; look and feel. It supports vector-based animation, easy installation, cross-platform compatibility, and more. Since animating can be pretty complex, Lottie will easily incorporate complex animations created with tools like Adobe After Effects.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-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;">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;">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 class="token">startAnimating(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">func startAnimating</span><span class="token">(</span><span class="token">)</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    animationView.</span><span class="token">setAnimation(</span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">bird_flying</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> &quot;bird_flying&quot; is an example animation that can be found here: https://lottiefiles.com/17655-bird-flying</span><span class="token">
</span></span><span class="line"><span class="token">    animationView.</span><span class="token">play(</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-321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-319">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-320'
	>
	It is very easy and straightforward to import and configure animations using Lottie.</p></div>	</div>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-325">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-326'
	>
	<a href="https://github.com/danielgindi/Charts" target="_blank" rel="noreferrer noopener">Charts</a> is a library that integrates different charts into iOS applications, providing a very customizable solution for data visualization. It supports different chart types like line, bar, pie, radar, etc. Users can interact with charts through various gestures, animations, and more.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-329"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> entries </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [
</span></span><span class="line"><span class="token">            </span><span class="token">ChartDataEntry(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #005cc5;">1.0</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #005cc5;">10.0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">ChartDataEntry(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #005cc5;">2.0</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #005cc5;">25.0</span><span class="token">)</span><span class="token">,
</span></span><span class="line"><span class="token">            </span><span class="token">ChartDataEntry(</span><span class="token">x:</span><span class="token"> </span><span class="token" style="color: #005cc5;">3.0</span><span class="token">, </span><span class="token">y:</span><span class="token"> </span><span class="token" style="color: #005cc5;">15.0</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;"> Add more data entries as needed</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" style="color: #d73a49;">let</span><span class="token"> dataSet </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">LineChartDataSet(</span><span class="token">entries:</span><span class="token"> entries</span><span class="token">, </span><span class="token">label:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Sample Data</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">dataSet.</span><span class="token">colors</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [.</span><span class="token">systemBlue</span><span class="token">]
</span></span><span class="line"><span class="token">dataSet.</span><span class="token">circleColors</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> [.</span><span class="token">systemBlue</span><span class="token">]
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> data </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">LineChartData(</span><span class="token">dataSet:</span><span class="token"> dataSet</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">lineChartView.</span><span class="token">data</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> data
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-332"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-330">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-331'
	>
	You should note that since iOS 16, Apple has released its own version of charts, and this may be the last time we&#8217;ve written about this tool.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-335"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-333">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-334'
	>
	Kingfisher</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-338"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-336">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-337'
	>
	<a href="https://github.com/onevcat/Kingfisher" target="_blank" rel="noreferrer noopener">Kingfisher</a> is our go-to tool for image loading and caching. You provide an image URL for the tool to download, which sends it to memory and disk caches and then displays it in many UIKit-friendly classes. Kingfisher can also help with async image loading, placeholders, transition effects, processing, and much more. It also has SwiftUI support.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-340"
	 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;"> Basic version</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> url </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">URL(</span><span class="token">string:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://example.com/image.png</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">imageView.</span><span class="token">kf</span><span class="token">.</span><span class="token">setImage(</span><span class="token">with:</span><span class="token"> url</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> SwiftUI version</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">KingfisherSwiftUI</span><span class="token">
</span></span><span class="line"><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">KFImage(</span><span class="token">URL(</span><span class="token">string:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://example.com/image.png</span><span class="token" style="color: #032f62;">&quot;</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-343"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-341">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-342'
	>
	Honorable Mentions</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-346"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-344">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-345'
	>
	Alamofire</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-349"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-347">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-348'
	>
	<a href="https://github.com/Alamofire/Alamofire" target="_blank" rel="noreferrer noopener">Alamofire</a> is one of the best and most used frameworks in iOS development. Its main task is simplifying networking requests, handling responses, authentication, and other useful capabilities the tool provides. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-351"
	 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">AF
</span></span><span class="line"><span class="token"> .</span><span class="token">request(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://api.example.com/data</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">responseJSON</span><span class="token"> </span><span class="token">{</span><span class="token"> response </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;"> Handle response</span><span class="token">
</span></span><span class="line"><span class="token"> </span><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-354"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-352">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-353'
	>
	From top to bottom, you make your request, validate your response, and decode it into necessary data models. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-357"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-355">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-356'
	>
	<strong>RxSwift</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-360"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-358">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-359'
	>
	<a href="https://github.com/ReactiveX/RxSwift?tab=readme-ov-file" target="_blank" rel="noreferrer noopener">Reactive programming</a> is simple, elegant, and powerful. It intends to enable easy composition of asynchronous operations and data streams in the form of Observable objects. Learning this way of working takes time, but once you know it, you&#8217;ll never use it any other way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-362"
	 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">observable
</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> some action })</span><span class="token">
</span></span><span class="line"><span class="token"> .</span><span class="token">disposedBy(</span><span class="token">disposeBag</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-365"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-363">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-364'
	>
	RxCocoa goes hand in hand with RxSwift (since it includes some iOS-specific features). For example, button tappings, text inputs, and all other UI elements are way easier to maneuver when RxCocoa is on.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-367"
	 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"> buttonSelected </span><span class="token" style="color: #d73a49;">=</span><span class="token"> button.</span><span class="token">rx</span><span class="token">.</span><span class="token">tap</span><span class="token">.</span><span class="token">asSignal(</span><span class="token">)</span><span class="token"> 
</span></span><span class="line"><span class="token">buttonSelected
</span></span><span class="line"><span class="token"> .</span><span class="token">emit(</span><span class="token">onNext:</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> some action })</span><span class="token">
</span></span><span class="line"><span class="token"> .</span><span class="token">disposedBy(</span><span class="token">disposeBag</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-370"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-368">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-369'
	>
	To be fair, we have started moving towards Combine where it makes sense, but this process is still ongoing, and we&#8217;ll still heavily utilize Rx in years to come.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-373"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-371">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-372'
	>
	Best iOS libraries developed by Infinum</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-376"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-374">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-375'
	>
	Like any other development team, we are constantly working on new ideas and have created many libraries we use heavily in our projects. Check them out below as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-380"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-377">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-378'
	>
	<a href="https://github.com/infinum/Locker" target="_blank" rel="noreferrer noopener">Locker</a></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-379'
	>
	A lightweight library for handling sensitive data (String type) in Keychain using iOS Biometrics features.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-384"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-381">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-382'
	>
	<a href="https://github.com/infinum/iOS-prince-of-versions" target="_blank" rel="noreferrer noopener">Prince of Versions</a></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-383'
	>
	Used for easier versioning of your applications; allows you to prompt your users to update the app to the newest version.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-388"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-385">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-386'
	>
	<a href="https://github.com/infinum/iOS-SwiftI18n/blob/master/README.md" target="_blank" rel="noreferrer noopener">I18n</a></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-387'
	>
	A library that makes localizing your app much easier by adding custom properties to UI elements and setting up available languages within the code.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-392"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-389">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-390'
	>
	<a href="https://github.com/infinum/ios-collar" target="_blank" rel="noreferrer noopener">Collar</a></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-391'
	>
	This library for analytics debugging can show you different types of analytics collecting data as they happen in the app.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-396"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-393">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-394'
	>
	<a href="https://github.com/infinum/ios-sentinel" target="_blank" rel="noreferrer noopener">Sentinel</a></p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-395'
	>
	A library for configuring a single entry point for every debug tool used.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-399"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-397">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-398'
	>
	Anything to add?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-402"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-400">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-401'
	>
	There are many libraries in the ocean of iOS. Here, we picked some of our favorites that make our lives easier and shorten the development time so we can use them in other productive workflows. If you have another one we might have missed, feel free to contact us on social media. </p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/best-ios-libraries-2024/">The Best iOS Libraries in 2024</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>33541https://infinum.com/uploads/2023/02/iOS-Color-Namg-System-HERO-2.webp</url>
				</image>
				<title>Bullet-Proof Color-Naming System for iOS Development</title>
				<link>https://infinum.com/blog/color-naming-system-ios/</link>
				<pubDate>Fri, 03 Feb 2023 12:02:21 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=33541</guid>
				<description>
					<![CDATA[<p>Make development easier and lives better by introducing and implementing an intuitive color-naming system.</p>
<p>The post <a href="https://infinum.com/blog/color-naming-system-ios/">Bullet-Proof Color-Naming System for iOS Development</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-445"
	 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-405">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-408"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-406">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-407'
	>
	Since my earliest days in iOS development, I have wondered about the best way to work with colors. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-410"
	 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-409'
	>
	<strong>Colors are essential to any app. Choosing the right ones can make your application more intuitive and easier to interact with. Choosing the wrong ones is likely to result in weird and unexpected behaviors. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-413"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-411">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-412'
	>
	If you don’t believe me, try painting an error message green – and wait for the users to get confused.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-416"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-414">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-415'
	>
	After years of using colors in different areas like design, programming, and even cooking, I can conclude that color is a property added to basically everything surrounding us, including us.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-419"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-417">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-418'
	>
	My opening rant aside, the use of colors is an important topic for any development team. A structured approach to color-naming helps in onboarding new team members to our way of working, and what’s more, adding dark mode support becomes easier.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-422"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-420">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-421'
	>
	This article will present our naming system and provide a way of implementing it. The implementation example we use is iOS-based, but the naming principles can be applied on any platform.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-425"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-423">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-424'
	>
	An easy and logical way to name colors in development</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-428"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-426">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-427'
	>
	Our team used to have a confusing naming system that took a lot of time to learn. Wanting to up our efficiency and lessen the confusion, we set out to create a simple system for naming colors that would also be easy to explain to new team members. This way, they can use it much sooner, and as a bonus, save the nerves they would rack trying to discern what color is <code>jupiterSunset</code> and what is <code>tigerCat</code>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-431"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-429">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-430'
	>
	First of all, a good naming system requires you to communicate with the app’s designer. They have their own color palette, which means you have a list of colors you need to name. When deciding what names to use, take into consideration these three simple facts:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-435"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-432">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-433'
	>
	1</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-434'
	>
	Every color already has a name, so there’s no real need to name burgundy red elephant.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-439"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-436">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-437'
	>
	2</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-438'
	>
	Some colors have a more important role in your app than others.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-443"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--number bullet__color--black block-bullet__bullet" data-id="es-440">
	<p	class='typography typography--size-14-text js-typography bullet__dot'
	data-id='es-441'
	>
	3</p>	<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-442'
	>
	Some colors are assigned to elements like buttons, separators, or backgrounds.</p>	</div>
</div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-447">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/02/Frame_2362.webp"
					class="image__img block-media__image-img"
					alt=""
										height="357"
															width="1001"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-457"
	 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-449">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-452"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-450">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-451'
	>
	For example, if our app uses blue as its tint color, it can be called <code>primary</code> color or <code>tint</code> for short. Most text in the app uses some variant between black and white, however, it mostly appears on labels, so we can name the colors <code>LabelPrimary</code>, <code>LabelSecondary</code> and so on. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-455"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-453">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-454'
	>
	Of course, we have to consider shades as well. In our example, there are a couple of shades of blue. If we use the color under number 75 as our primary one, we can use it as a basis for naming the other variants. We follow this logic: a number closer to 0 will mark a darker variant, and the closer we move to 100, the variants are lighter.&nbsp;This is how it would look like: <code>primary</code>, <code>primary25</code>, <code>primary50</code>, <code>primary100</code>.</p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-459">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/02/Frame_2363.webp"
					class="image__img block-media__image-img"
					alt=""
										height="357"
															width="1001"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-475"
	 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-461">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-464"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-462">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-463'
	>
	We can apply the same strategy to error, success, and warning messages. When you’re naming colors used in screens showing those messages, you can combine the color variants with the message type. For example, for an error message, you would name the color used for the bubble <code>error80</code>, the color of the border around it <code>error50</code>, and the color of the message text <code>error</code>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-467"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-465">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-466'
	>
	The last colors to mention are used for <em>structure</em>, like separators, backgrounds, and similar elements whose colors appear only there and nowhere else. Name those colors using their semantic names – <code>separator</code> and <code>background</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-470"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-468">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-469'
	>
	Implementing the color-naming system in iOS</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-473"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-471">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-472'
	>
	Implementing the naming system is short and simple, albeit repetitive. The first step is to add all the colors to your project resources. The image below is an example of how it should look.</p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-477">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/02/Frame_2361.webp"
					class="image__img block-media__image-img"
					alt=""
										height="472"
															width="1001"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-501"
	 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-479">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-482"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-480">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-481'
	>
	Once you have added the colors, you should implement the extension to <code>UIColor</code>. See the code example below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-484"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">extension</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</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><span class="line"><span class="token" style="color: #005cc5;">    static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">primary</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">primary/primary</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">primary20</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">primary/primary20</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    enum</span><span class="token"> </span><span class="token" style="color: #005cc5;">Error</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">error</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">            return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: &quot;</span><span class="token" style="color: #6f42c1;">mes</span><span class="token" style="color: #032f62;">sages/error</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </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" style="color: #005cc5;">    static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">separator</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">separator</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    enum</span><span class="token"> </span><span class="token" style="color: #005cc5;">Label</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">primary</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">            return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: &quot;</span><span class="token" style="color: #6f42c1;">lab</span><span class="token" style="color: #032f62;">el/primary</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        static</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">secondary</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIColor</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">            return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIColor</span><span class="token">(</span><span class="token" style="color: #6f42c1;">named</span><span class="token">: &quot;</span><span class="token" style="color: #6f42c1;">lab</span><span class="token" style="color: #032f62;">el/secondary</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </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-487"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-485">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-486'
	>
	When you’ve added the colors and implemented the necessary extensions, adding new colors is simple, and using them is the same as using system-defined colors. You can add primary colors to buttons through storyboards simply by selecting it, or if you’re using code, by adding <code>.primary</code> to the element’s color property. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-490"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-488">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-489'
	>
	Color within the lines</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-493"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-491">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-492'
	>
	To create a solid naming system you can use consistently, you need to think about all the ways you use certain colors, their priorities, and contextual meaning. Implementing such a system can seem boring at first, but in the long run, it gives you an organized and defined color system and hierarchy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-496"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-494">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-495'
	>
	The added value is that you can extract this type of color system into a library, which you can then share across multiple apps that use the same design language.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-499"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-497">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-498'
	>
	Creating a system may take some additional effort, but it’s worth investing your time and energy because it makes using colors in development significantly easier.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/color-naming-system-ios/">Bullet-Proof Color-Naming System for iOS Development</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>32837https://infinum.com/uploads/2023/01/Pros-and-Cons-of-Building-Storyboard-or-Code-UI_hero.webp</url>
				</image>
				<title>Storyboard or Code? Solving the iOS UI-Building Dilemma</title>
				<link>https://infinum.com/blog/storyboard-code-ui-building-ios/</link>
				<pubDate>Tue, 24 Jan 2023 10:43:20 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=32837</guid>
				<description>
					<![CDATA[<p>Building UI in iOS, you can choose to use storyboards or just code. We explore the pros and cons of both options. </p>
<p>The post <a href="https://infinum.com/blog/storyboard-code-ui-building-ios/">Storyboard or Code? Solving the iOS UI-Building Dilemma</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-532"
	 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-502">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-505"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-503">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-504'
	>
	Learning how to <a href="https://infinum.com/ui-ux-design-services/">build the UI</a> without using storyboards is an option most iOS developers will encounter at some point during their work. You could call it a natural evolution that occurs as our knowledge expands and we start to get a glimpse of a very different world.  </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-508"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-506">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-507'
	>
	The theory behind this way of thinking is quite simple – ditch the storyboard and start writing your views using just code. However, bear in mind that you&#8217;re diving into an ocean of complexity called UIKit without the inflatable floaters a storyboard provides, and you will probably need to take some time to learn new swimming techniques. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-510"
	 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-509'
	>
	When you finally gain some experience, you&#8217;re left with a vast amount of knowledge and a new dilemma: Should you use storyboards?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-513"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-511">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-512'
	>
	The answer is not that simple. Even our iOS team remains neutral on this topic and doesn&#8217;t favor one option over the other by default. Since each comes with its benefits, it&#8217;s a choice based on the project situation and its necessities.</p></div>	</div>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-519"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-517">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-518'
	>
	Why not storyboards? Creating user interfaces using storyboards is simple, and it&#8217;s what Apple recommends to everyone starting out in iOS development. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-520'
	>
	Storyboards are elegant, easy to learn, and more intuitive than using code for everything, at least in the beginning. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-522">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-523'
	>
	It&#8217;s easy to pick an element you want to display and position it on a screen. When you learn how to manipulate these elements to get them to look like you want, then you already know how to use outlets and constraints, connect the views, etc.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-527"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-525">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-526'
	>
	We use storyboards on our projects, and you&#8217;ll find them in practice for many types of screens – from the smallest ones containing only two labels to large scrollable ones where each section has some labels, images, or other elements. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-530"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-528">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-529'
	>
	However, we strive to make everything reusable, which can often get complicated when using storyboards. Not impossible, though. </p></div>	</div>
</div>
</div>		</div>
	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-534">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/01/pros_and_cons_screens-1400x715.webp				media='(max-width: 699px)'
				type=image/webp								height="715"
												width="1400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/01/pros_and_cons_screens-2400x1226.webp				media='(max-width: 1199px)'
				type=image/webp								height="1226"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/01/pros_and_cons_screens.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1400"
															width="2740"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper"
	data-id="es-541"
	 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-536">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-537">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-538'
	>
	The picture above displays how easy it is to create a master-detail screen using storyboards. They are very flexible, meaning you can organize as many view controllers and views as you want into a single storyboard. However, doing so comes at a price. You might be facing extended loading time, as storyboards tend to take more time to load, whereas code files load almost instantly.</p></div>	</div>
</div>
</div>		</div>
	</div>

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

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

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

<div
	class="wrapper"
	data-id="es-591"
	 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-545">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-548"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-546">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-547'
	>
	Experienced iOS developers won&#8217;t take too much time creating simple storyboard views like tables or collection cells with a couple of elements like labels, images, or buttons. It is easy to make some of them reusable, and they are easy to import as views in other storyboards. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-551"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-549">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-550'
	>
	Considering all this, editing storyboards is as simple as the storyboard is. It can get very complicated if you&#8217;re new to a project and have to investigate all the possible views and their options to replace something. Reviewing pull requests can be an even bigger challenge since Storyboards are basically Apple-inspired XML, and this makes it hard to see the important changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-552">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-553'
	>
	Why code?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-557"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-555">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-556'
	>
	On the other hand, writing interfaces using code is sometimes better. Even Apple with its shiny new SwiftUI framework is telling us to do that. In my experience, the switch can be somewhat counterintuitive, and you may feel lost at first, but if you take the time to adjust and learn, you will be absolutely fine. You may even shorten your development time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-559"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-558'
	>
	Writing views in code comes with many benefits. However, they only come to the surface when you use important reusability principles. That way, you can create a complex view by combining several separate views or adding new, extended additions to the existing ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-562"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-560">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-561'
	>
	For example, the code below displays <code>BaseView</code>. In this particular case, it&#8217;s the base every other view will inherit. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-564"
	 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 BaseView</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UIView </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 class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">init(fra</span><span class="token">me</span><span class="token">: </span><span class="token">CGRect</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" style="color: #d73a49;">init</span><span class="token">(</span><span class="token">frame:</span><span class="token"> frame</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">setup(</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><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">required</span><span class="token"> </span><span class="token" style="color: #d73a49;">init?(cod</span><span class="token">er aDecoder</span><span class="token">: </span><span class="token">NSCoder</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" style="color: #d73a49;">init</span><span class="token">(</span><span class="token">coder:</span><span class="token"> aDecoder</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">setup(</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><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">func setup</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">setupLayout(</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"> constraints </span><span class="token" style="color: #d73a49;">= setupCo</span><span class="token">nstraints(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> !constr</span><span class="token" style="color: #d73a49;">ai</span><span class="token">nts.</span><span class="token" style="color: #005cc5;">isEmpty</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            NSLayoutConstraint.</span><span class="token">activate(</span><span class="token">constraints</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><span class="line"><span class="token">    </span><span class="token">func setupLayout</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Method used for overriding</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><span class="line"><span class="token">    </span><span class="token">func setupConstraints</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">[</span><span class="token">NSLayoutConstraint</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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Method used for overriding</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">[</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-567"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-565">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-566'
	>
	We can create any other view in the same way. For example, many apps have elements displaying an image and a label placed horizontally. We&#8217;ll name it <code>BaseListItem</code> for consistency. This class will inherit <code>BaseView</code>, so the methods for setting up the layout and the constraints will also be used. By the way, constraints are a whole other beast, and we won&#8217;t cover them here. When creating UI elements with code, the most important thing is to set the view property <code>translatesAutoresizingMaskIntoConstraints = <strong>false</strong></code>. If you follow my suggestion in the intended way, you make an extension to the UIKit and implement some static method that sets it to false, similar to what our create() method does here. </code></code></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-569"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BaseListItem</span><span class="token">: BaseView </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    private</span><span class="token"> </span><span class="token" style="color: #005cc5;">lazy</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">image</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIImageView</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">create</span><span class="token">()
</span></span><span class="line"><span class="token" style="color: #005cc5;">    private</span><span class="token"> </span><span class="token" style="color: #005cc5;">lazy</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">titleLabel</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">UILabel</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">create</span><span class="token">()
</span></span><span class="line"><span class="token" style="color: #005cc5;">    private</span><span class="token"> </span><span class="token" style="color: #005cc5;">lazy</span><span class="token"> </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">stackView</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIStackView</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">create</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" style="color: #005cc5;">    override</span><span class="token"> </span><span class="token" style="color: #005cc5;">func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">setupLayout</span><span class="token">() {</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        super</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">setupLayout</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" style="color: #005cc5;">        stackView</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">addArrangedSubview</span><span class="token">(</span><span class="token" style="color: #6f42c1;">image</span><span class="token">)
</span></span><span class="line"><span class="token" style="color: #005cc5;">        stackView</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">addArrangedSubview</span><span class="token">(</span><span class="token" style="color: #6f42c1;">titleLa</span><span class="token" style="color: #005cc5;">bel</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">        addSubview</span><span class="token">(</span><span class="token" style="color: #6f42c1;">stackVi</span><span class="token" style="color: #005cc5;">ew</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    override</span><span class="token"> </span><span class="token" style="color: #005cc5;">func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">setupConstraints</span><span class="token">() -</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">NSLayoutConstraint</span><span class="token">]</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        var</span><span class="token"> </span><span class="token" style="color: #005cc5;">constraints</span><span class="token">:</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #005cc5;">NSLayoutConstraint</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">[</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        constraints</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">append</span><span class="token">(</span><span class="token" style="color: #6f42c1;">stackVi</span><span class="token" style="color: #005cc5;">ew</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">pin</span><span class="token">(</span><span class="token" style="color: #6f42c1;">to</span><span class="token">: </span><span class="token" style="color: #6f42c1;">sel</span><span class="token" style="color: #d73a49;">f</span><span class="token">)</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">  return</span><span class="token"> </span><span class="token" style="color: #005cc5;">constraints </span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">configure</span><span class="token">(</span><span class="token" style="color: #6f42c1;">wit</span><span class="token" style="color: #005cc5;">h</span><span class="token"> </span><span class="token" style="color: #005cc5;">item</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">ListItem</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        image</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">item</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">image</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">        titleLabel</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">item</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">title</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">    </span><span class="token">}</span><span class="token">
</span></span><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-572"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-570">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-571'
	>
	Any other view can be added on top of this <code>BaseListItem</code>. This class can be configured and is ready to be used anywhere else with many possible configurations. Essentially, this is more efficient and easier to understand than dragging and dropping elements without realizing what is happening in the background. Writing constraints by hand for the first time can get confusing, but this way, we control the elements exactly how we want.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-575"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-573">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-574'
	>
	When changes do occur, they are easily visible to your colleague in charge of the PR review. They don&#8217;t need to take a lot of time decoding the immersive XML experience and can use it in better ways.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-578"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-576">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-577'
	>
	As mentioned before, our team doesn&#8217;t give preference to any option, and we tend to take the best of both worlds. So in practice, both storyboard-built and code-built UI can be found in our project files.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-580"
	 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-579'
	>
	When you&#8217;re starting to learn Swift, storyboards can be of great help, and when you gather enough experience, writing your own UI is just another adventure on the way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-581">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-582'
	>
	Ready for the future</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-584">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-585'
	>
	You might wonder how useful it is to learn all this since Apple is slowly but surely pushing SwiftUI as the go-to option when developing for their platforms. It&#8217;s been up and running for over three years, and it&#8217;s getting better with every new iteration. Moreover, some features like widgets or live activities can only be implemented using SwiftUI.  </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-587">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-588'
	>
	Still, neither storyboards nor the UIKit are going away anytime soon. I would always recommend learning how to write the UI from code and using storyboards before you dive into SwiftUI. Under the hood, the modern declarative framework is still very dependent on the UIKit, and learning it will give you an excellent basis to start your journey with SwiftUI, even though its logic and ways are much different from the old ways.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/storyboard-code-ui-building-ios/">Storyboard or Code? Solving the iOS UI-Building Dilemma</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19092https://infinum.com/uploads/2022/02/debugging-tools-app-development-0.webp</url>
				</image>
				<title>Debugging Tools to Push Your App Development Forward</title>
				<link>https://infinum.com/blog/debugging-tools-app-development/</link>
				<pubDate>Thu, 17 Feb 2022 13:10:00 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/blog/debugging-tools-app-development/</guid>
				<description>
					<![CDATA[<p>Collar and Sentinel are two libraries for iOS developers that simplify analytics debugging.</p>
<p>The post <a href="https://infinum.com/blog/debugging-tools-app-development/">Debugging Tools to Push Your App Development Forward</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-701"
	 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-592">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-595"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-593">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-594'
	>
	Mobile app consumers, product owners, and developers all have one thing in common – everybody wants a beautiful, functional, and crash-free app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-598"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-596">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-597'
	>
	However, when talking about mobile app development, developers tend to spend so much time just testing the app and checking if everything works correctly in certain conditions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-601"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-599">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-600'
	>
	Depending on the tools we decide to use, we can either waste time reading monosans letters in the logger or have everything implemented in an interactive way so that the information we need is reachable at our fingertips.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-602">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-603'
	>
	We’ve developed two libraries to help you take advantage of debugging and make your life easier.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-605">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-606'
	>
	Collar – a library for analytics debugging</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-608">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-609'
	>
	<a href="https://github.com/infinum/ios-collar">Collar</a> is a library for analytics debugging that can show you three types of analytic collecting data as they happen in the app: events, screens, and user properties.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-612">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2022/02/debugging-tools-app-development-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="700"
															width="1369"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Collar screen		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-616"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-614">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-615'
	>
	It is easy to configure and straightforward to use – it’s as simple as just importing the library and using several methods to collect the data for preview.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-619"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-617">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-618'
	>
	<code>import Collar</code></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-622"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-620">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-621'
	>
	After you’ve imported the library, you can add three analytic collecting types. To collect events, see the code below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-624"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Events</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">AnalyticsCollectionManager</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">log</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">event</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">some_event</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">parameters</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: #032f62;">&quot;</span><span class="token" style="color: #032f62;">param1</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">value1</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">param2</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">value2</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><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: #6a737d;">//</span><span class="token" style="color: #6a737d;"> User properties</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">AnalyticsCollectionManager</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">setUserProperty</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">some_value</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">forName</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">user_property_key</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" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Screen views</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">AnalyticsCollectionManager</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">track</span><span class="token">(</span><span class="token" style="color: #6f42c1;">screenName</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Home</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">screenClass</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">HomeViewController</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-627"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-625">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-626'
	>
	As you can see, collecting the data is simple and does not require much work. However, please remember that Collar does not send out any analytics data to remote services. Developers are left with solving this within their own codebases, and Collar is just there to reflect the current state of the analytics data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-630"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-628">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-629'
	>
	To display events, you can choose to view it as a popup every time when the Collar collects any analytics or at some specific point which will display all of the collected data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-633"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-631">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-632'
	>
	You should insert the line below to view the analytics as a list at a specific point in the code lifecycle.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-636"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-634">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-635'
	>
	<code>AnalyticsCollectionManager.shared.showLogs(from: viewController)</code></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-639"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-637">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-638'
	>
	To see it as a popup every time something gets collected, insert the code below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-641"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Also controllable from settings screen inside logs view</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">LogItemPopupQueue</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">enabled</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Popup dismisses on tap or after defined number of seconds</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">LogItemPopupQueue</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">showOnView</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIApplication</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">keyWindow</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-644"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-642">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-643'
	>
	You can also choose to receive notifications when new logs are added to the list, so your app can observe the <code>AnalyticsCollectionManager.Notification.didUpdateLogs</code> notification.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-647"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-645">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-646'
	>
	Important information</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-650"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-648">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-649'
	>
	Bear in mind that <code>AnalyticsCollectionManager</code> and <code>LogItemPopupQueue</code> are not meant to be used in production builds. The best option is to exclude Collar from your production targets/configurations altogether. This can be done by following the Podfile configuration example below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-653"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-651">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-652'
	>
	<code>pod &amp;#8216;Collar&amp;#8217;, :configurations =&gt; [&amp;#8216;Development-release&amp;#8217;, &amp;#8216;Development-debug&amp;#8217;]</code></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-656"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-654">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-655'
	>
	Sentinel – a library for configuring a single entry point for every debug tool being used</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-659"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-657">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-658'
	>
	<a href="https://github.com/infinum/ios-sentinel">Sentinel</a> is a library created with simplicity in mind. It allows developers to configure a single entry point for every debug tool being used. This library’s primary goal is to give developers the ability to configure the screen with multiple debug tools that will become available on some event (e.g., screen shake, notification, etc.).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-662"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-660">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-661'
	>
	The library is available for both Swift and Objective-C.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-665"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-663">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-664'
	>
	Configuration &amp; Use</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-668"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-666">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-667'
	>
	Sentinel is the main class used to set up the Sentinel that will be used in the application. The Sentinel object can be configured with the setup method by the <code>Configuration</code> object.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-671"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-669">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-670'
	>
	The <code>Configuration</code> object contains multiple objects that define general Sentinel behavior. All the inputs this object needs for initialization are <code>trigger</code>, <code>sourceScreenProvider</code>, and <code>tools</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-674"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-672">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-673'
	>
	The self-explanatory <code>trigger</code> object is a type of <code>Trigger</code> that defines the event that will trigger the Sentinel. This will result in presenting the Sentinel to the developer. At the time of writing this article, three trigger types are supported by default – <code>ShakeTrigger</code>, <code>ScreenshotTrigger</code>, <code>NotificationTrigger</code>. Bear in mind that new triggers can be added as well, they just need to conform to the <code>Trigger</code> protocol.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-677"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-675">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-676'
	>
	<code>SourceScreenProvider</code> is a type that provides the view controller from which Sentinel is presented. For now only one (default) type is supported.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-680"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-678">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-679'
	>
	The array of <code>Tool</code> objects is the last one required for final Sentinel configuration. This type of object represents the tools which will be available for use in Sentinel. Multiple tools are already supported by the library, but you can also create custom ones.<br>To create custom tools, create a new class that conforms to the Tool protocol defined below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-682"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #005cc5;">protocol</span><span class="token"> </span><span class="token" style="color: #005cc5;">Tool</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #005cc5;">name</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">String</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">get</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;">func</span><span class="token"> </span><span class="token" style="color: #6f42c1;">presentPreview</span><span class="token">(</span><span class="token" style="color: #005cc5;">from</span><span class="token"> </span><span class="token" style="color: #005cc5;">viewController</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">UIViewController</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-685"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-683">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-684'
	>
	Based on the code above, you need to provide a <code>name</code> and a <code>presentPreview</code> method, which is used for presenting the tool view controller from the <code>sourceScreenProvider</code> view controller defined in the Sentinel configuration.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-688"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-686">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-687'
	>
	Adding Sentinel to your project is done by defining <code>Sentinel.Configuration</code> and calling the setup method inside the <code>AppDelegate</code>‘s well known <code>application(_:didFinishLaunchingWithOptions:)</code> method. All that said, creating a Sentinel that triggers all the debug tools to display on device shake would look like the code below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-690"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">let</span><span class="token"> </span><span class="token" style="color: #005cc5;">configuration</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Sentinel</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">Configuration</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">sourceScreenProvider</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">SourceScreenProviders</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #d73a49;">default</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">trigger</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">Triggers</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shake</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">tools</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: #6f42c1;">GeneralInfoTool</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: #6f42c1;">UserDefaultsTool</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: #6f42c1;">LoggieTool</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">Sentinel</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">shared</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #6f42c1;">setup</span><span class="token">(</span><span class="token" style="color: #6f42c1;">with</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">configuration</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-693"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-691">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-692'
	>
	Push your app development forward</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-696"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-694">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-695'
	>
	To conclude, both Sentinel and Collar are very useful libraries. The former is a library that helps you save time by organizing all your debug tools into one place, and the latter allows you to observe the flow of analytics data visually.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-699"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-697">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-698'
	>
	You can check them out here: <a href="https://github.com/infinum/ios-collar">Collar</a> and <a href="https://github.com/infinum/ios-sentinel">Sentinel</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/debugging-tools-app-development/">Debugging Tools to Push Your App Development Forward</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>8148https://infinum.com/uploads/2021/08/ios-libraries-2021-0.webp</url>
				</image>
				<title>Most Important iOS Libraries in 2021</title>
				<link>https://infinum.com/blog/ios-libraries-2021/</link>
				<pubDate>Wed, 11 Aug 2021 14:20:00 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/ios-libraries-2021/</guid>
				<description>
					<![CDATA[<p>Our signature blend of the most useful iOS libraries, a fresh batch for 2021.</p>
<p>The post <a href="https://infinum.com/blog/ios-libraries-2021/">Most Important iOS Libraries in 2021</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-932"
	 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-702">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-705"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-703">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-704'
	>
	With another year of experience behind us, we bring you a handy list for every iOS developer’s collection – <strong>the curated list of the best, most important, most useful iOS libraries, updated for 2021</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-708"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-706">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-707'
	>
	If this feels like deja vu, it’s because we published <a href="https://infinum.com/blog/top-10-most-useful-iOS-libraries/">top 10 iOS libraries lists in 2020</a>, as well as the age-old article <a href="https://infinum.com/blog/top-10-ios-swift-libraries-every-ios-developer-should-know-about/">top 10 iOS libraries of 2015</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-711"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-709">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-710'
	>
	Development and testing libraries</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-714"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-712">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-713'
	>
	Those articles proved a great starting point for developers looking to increase their productivity and avoid doing unnecessary work. With the same goal in mind, <strong>we’ve kept some oldies goldies on the list, but added the hottest hits of 2021</strong>. As our knowledge grows, we recognize what stands the test of time and what should be replaced with something new and innovative.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-717"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-715">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-716'
	>
	Speaking of innovation, this time around the libraries are sorted into two categories, development and testing. It might help you navigate faster if you’re looking for something specific.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-720"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-718">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-719'
	>
	We’ve also decided not to limit ourselves with a top-10 format, and just present all the libraries we believe may prove useful.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-723"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-721">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-722'
	>
	Some obligatory side notes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-726"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-724">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-725'
	>
	We’ve said it time and time again: It is <em>really</em> important to <strong>use third-party libraries responsibly</strong>. Here are some points that should help you decide whether a library is worth importing to your project:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-729"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-727">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-728'
	>
	<li>Make sure that the libraries you want to use are <strong>actively maintained and supported</strong>. Working on a long-term project could prove troublesome if it stops compiling because some Swift or iOS change broke the libraries.</li><li>You should <strong>utilise a great part</strong> of the libraries in your projects to make it worth the time, not just a small part of it. As we mentioned before: <em>“Don’t use an excavator where a shovel would suffice.”</em></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-732"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-730">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-731'
	>
	It should also be noted that this list was created by surveying our recent projects and needs, and only contains sources or opinions of the iOS team at Infinum.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-735"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-733">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-734'
	>
	Third-party development libraries</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-738"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-736">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-737'
	>
	RxSwift / RxCocoa</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-741"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-739">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-740'
	>
	The Swift version of <a href="https://github.com/Reactive-Extensions/Rx.NET">Rx</a> tries to port as many concepts from the original version as possible, but some of them have been adapted for a more pleasant and performant integration with the iOS/macOS environment.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-744"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-742">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-743'
	>
	Like the original Rx, its intention is to enable an easy composition of asynchronous operations and event/data streams. KVO observing, async operations and streams are all unified under the <a href="https://github.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md#observables-aka-sequences">abstraction of sequence</a>. This is the reason why Rx is so simple, elegant and powerful.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-747"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-745">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-746'
	>
	Here’s a simple example of how RxSwift can be used to create a logic for enabling a login button that checks two things – whether the username and password have both been entered, and if the password is of appropriate minimum length.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-749"
	 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">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> name </span><span class="token" style="color: #d73a49;">=</span><span class="token"> nameTextField.</span><span class="token">rx</span><span class="token">.</span><span class="token" style="color: #005cc5;">text</span><span class="token">.</span><span class="token">asDriver(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> password </span><span class="token" style="color: #d73a49;">=</span><span class="token"> passwordTextField.</span><span class="token">rx</span><span class="token">.</span><span class="token" style="color: #005cc5;">text</span><span class="token">.</span><span class="token">asDriver(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> isEnabled </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Driver
</span></span><span class="line"><span class="token">    .</span><span class="token">combineLatest(</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">name</span><span class="token">,
</span></span><span class="line"><span class="token">        </span><span class="token">password
</span></span><span class="line"><span class="token">    </span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #d73a49;">!</span><span class="token" style="color: #005cc5;">$0</span><span class="token">.</span><span class="token" style="color: #005cc5;">isEmpty</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #005cc5;">$1</span><span class="token">.</span><span class="token" style="color: #005cc5;">count</span><span class="token"> </span><span class="token" style="color: #d73a49;">&gt;=</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><span class="line"><span class="token">
</span></span><span class="line"><span class="token">isEnabled
</span></span><span class="line"><span class="token">    .</span><span class="token">drive(</span><span class="token">loginButton.</span><span class="token">rx</span><span class="token">.</span><span class="token">isEnabled</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-752"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-750">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-751'
	>
	This is just scratching RxSwift’s surface, but you can already see how it can make your life easier. RxSwift has a steeper learning curve than most libraries you could include in your projects, but once you get the hang of it, you’ll be thankful you did and will probably never look back.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-755"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-753">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-754'
	>
	The other library that RxSwift goes hand in hand with is RxCocoa. It is built around the Cocoa API, making it easier to use in a reactive manner. For example, check out how easy it is to catch all button tap events, without dealing with <em>IBActions</em>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-757"
	 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">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> buttonTapSignal </span><span class="token" style="color: #d73a49;">=</span><span class="token"> loginButton.</span><span class="token">rx</span><span class="token">.</span><span class="token">tap</span><span class="token">.</span><span class="token">asSignal(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">buttonTapSignal
</span></span><span class="line"><span class="token">.</span><span class="token">emit(</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-760"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-758">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-759'
	>
	Note: <a href="https://developer.apple.com/documentation/combine">Combine</a> will probably start slowly sunsetting RxSwift at some point. However, since it requires iOS 13 as the minimum OS version, we’re still not at a point where we can start using it in most projects. Until then, RxSwift will prevail.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-763"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-761">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-762'
	>
	SwiftLint</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-766"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-764">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-765'
	>
	SwiftLint is a tool used to enforce Swift style and conventions, loosely based on <a href="https://github.com/github/swift-style-guide">GitHub’s Swift Style Guide</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-769"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-767">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-768'
	>
	SwiftLint hooks into <a href="http://clang.llvm.org/">Clang</a> and <a href="http://www.jpsim.com/uncovering-sourcekit">SourceKit</a> and uses the <a href="http://clang.llvm.org/docs/IntroductionToTheClangAST.html">AST</a> representation of your source files for more accurate results.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-772"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-770">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-771'
	>
	Its <a href="https://realm.github.io/SwiftLint/rule-directory.html">rule list</a> is quite extensive, and covers pretty much everything you would want to keep track of in a well-maintained project. It also has the option to disable rules per-file or even per-line, but use those responsibly. Silencing a warning about a 700-line file or a too long method is maybe not the best tactic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-775"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-773">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-774'
	>
	Alamofire</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-778"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-776">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-777'
	>
	Alamofire is an elegant and composable way to interface to HTTP network requests. It builds on top of Apple’s <a href="https://developer.apple.com/documentation/foundation/url_loading_system/">URL Loading System</a> provided by the Foundation framework. At the system’s core are the <em>URLSession</em> and <em>URLSessionTask</em> subclasses.<br>Alamofire wraps these APIs, and many others, in an easy-to-use interface and provides a variety of functionalities necessary for modern application development using HTTP<br>networking.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-780"
	 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">
</span></span><span class="line"><span class="token">AF
</span></span><span class="line"><span class="token">    .</span><span class="token">request(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://your.api.url</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">validate(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    .</span><span class="token">responseDecodable(</span><span class="token">of:</span><span class="token"> SomeDecodableObject.</span><span class="token" style="color: #d73a49;">self</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">(</span><span class="token">response</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: #d73a49;">guard</span><span class="token"> </span><span class="token" style="color: #d73a49;">let</span><span class="token"> object </span><span class="token" style="color: #d73a49;">=</span><span class="token"> response.</span><span class="token" style="color: #005cc5;">value</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">        </span><span class="token" style="color: #005cc5;">print</span><span class="token">(</span><span class="token">object</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Your object, decoded and ready to use.</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-783"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-781">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-782'
	>
	From top to bottom, you request the endpoint, validate the response by ensuring the response returned an HTTP status code in the range 200–299 and decode the response into your data model. Easy peasy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-786"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-784">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-785'
	>
	Lottie</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-789"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-787">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-788'
	>
	Let’s be honest, animations in an application make a huge difference. They grasp the user’s attention and steer them through your app’s flow, all the while providing a fun and memorable experience. Since creating animations by hand using <em>UIView</em> or <em>CoreGraphics</em> animations can prove to be quite challenging and time-consuming, Lottie provides us with a perfect tool to incorporate designers’ creations into our applications.<br>Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with <a href="https://github.com/bodymovin/bodymovin">bodymovin</a>, Sketch with <a href="https://github.com/buba447/Lottie-Sketch-Export">Lottie Sketch Export</a>, and from <a href="https://www.haiku.ai/">Haiku</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-791"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><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;">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">startAnimating(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func startAnimating</span><span class="token">(</span><span class="token">)</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    animationView.</span><span class="token">setAnimation(</span><span class="token">named:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">bird_flying</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> &quot;bird_flying&quot; is an example animation that can be found here: https://lottiefiles.com/17655-bird-flying</span><span class="token">
</span></span><span class="line"><span class="token">    animationView.</span><span class="token">play(</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-794"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-792">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-793'
	>
	After importing Lottie into your project, this is all the code needed to add a beautiful animation to your app. Quite a timesaver.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-797"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-795">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-796'
	>
	SVProgressHUD</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-800"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-798">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-799'
	>
	If there was an award for libraries called “Simple integration, huge benefit”, I would undoubtedly hand it out to <a href="https://github.com/SVProgressHUD/SVProgressHUD/blob/master/README.md">SVProgressHUD</a>. Basically, all it does is display the progress of an ongoing task on iOS and tvOS. Using this library is as easy as calling the method;SVProgressHUD is a singleton, so all you have to do is use the methods <code>show()</code> and <code>dismiss()</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-803"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-801">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-802'
	>
	Even though it is simple to use, it can be customized in various ways – from animation type to ring radius, icons, and it even offers haptic feedback on success, info or error statuses.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-806"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-804">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-805'
	>
	KeychainAccess</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-809"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-807">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-808'
	>
	KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS. It makes using Keychain APIs extremely easy and much more manageable to use in Swift.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-812"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-810">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-811'
	>
	Saving data to the Keychain and retrieving it has never been easier:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-814"
	 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">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Save to the keychain</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> valueToSave </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;">Important data</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">Keychain(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #005cc5;">set</span><span class="token">(</span><span class="token">valueToSave</span><span class="token">, </span><span class="token">key:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">key</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" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Get from keychain</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> savedValue </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">try</span><span class="token" style="color: #d73a49;">?</span><span class="token"> </span><span class="token">Keychain(</span><span class="token">)</span><span class="token">.</span><span class="token">get(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">key</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></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-817"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-815">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-816'
	>
	Kingfisher</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-820"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-818">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-819'
	>
	Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It downloads the image from its URL, sends it to both the memory cache and the disk cache, and displays it in an <em>UIImageView</em>, <em>NSImageView</em>, <em>NSButton</em> or <em>UIButton</em>. When you try to retrieve an image with the same URL later, the image will be retrieved from cache and shown immediately.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-822"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Basic version</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> url </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">URL(</span><span class="token">string:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://example.com/image.png</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">imageView.</span><span class="token">kf</span><span class="token">.</span><span class="token">setImage(</span><span class="token">with:</span><span class="token"> url</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> SwiftUI version</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">KingfisherSwiftUI</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><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">KFImage(</span><span class="token">URL(</span><span class="token">string:</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://example.com/image.png</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token" style="color: #d73a49;">!</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-825"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-823">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-824'
	>
	It also provides many powerful additional options such as showing a system indicator and a placeholder image while downloading, built-in updating transitions, extensible image processing and formatting and much more. A must have if you’re working with remote images!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-828"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-826">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-827'
	>
	SnapKit</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-831"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-829">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-830'
	>
	SnapKit is an Auto Layout library that simplifies writing auto layout in code, so that a minimal amount of code is needed, but without losing readability. It is type-safe by design to help you avoid programming errors while coding your user interface.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-833"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> box </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">UIView(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">let</span><span class="token"> container </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">UIView(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">container.</span><span class="token">addSubview(</span><span class="token">box</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">box.</span><span class="token">snp</span><span class="token">.</span><span class="token">makeConstraints</span><span class="token"> </span><span class="token">{</span><span class="token"> make </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">    make.</span><span class="token" style="color: #005cc5;">size</span><span class="token">.</span><span class="token">equalTo(</span><span class="token" style="color: #005cc5;">50</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    make.</span><span class="token">center</span><span class="token">.</span><span class="token">equalTo(</span><span class="token">container</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-836"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-834">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-835'
	>
	It’s also very powerful when it comes to views whose constraints are updated frequently. Remaking constraints is much more pleasant than dealing with Auto Layout by hand:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-838"
	 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">
</span></span><span class="line"><span class="token">func updateBoxSize</span><span class="token">(</span><span class="token">to size</span><span class="token">: </span><span class="token">CGFloat</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    box.</span><span class="token">snp</span><span class="token">.</span><span class="token">remakeConstraints</span><span class="token"> </span><span class="token">{</span><span class="token"> remake </span><span class="token" style="color: #d73a49;">in</span><span class="token">
</span></span><span class="line"><span class="token">        remake.</span><span class="token" style="color: #005cc5;">size</span><span class="token">.</span><span class="token">equalTo(</span><span class="token">size</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-841"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-839">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-840'
	>
	Third-party testing libraries</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-844"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-842">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-843'
	>
	Sourcery</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-847"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-845">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-846'
	>
	<a href="https://github.com/krzysztofzablocki/Sourcery">Sourcery</a> is a library that finally puts a stop to writing repetitive code and creates better architecture and developer workflows. One of Sourcery’s best usages comes with implementing <code>Mocks</code>, and it is usually this kind of code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-849"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">&lt;</span><span class="token">span data</span><span class="token" style="color: #d73a49;">-</span><span class="token">es</span><span class="token" style="color: #d73a49;">-</span><span class="token">language</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">c</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">&gt;&lt;/</span><span class="token">span</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">lass UserViewInterfaceMock</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token">ViewInterface</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> setUsernameCalled </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var setUsernameReceivedValue:</span><span class="token"> </span><span class="token" style="color: #005cc5;">String</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">func setUsername</span><span class="token">(</span><span class="token">username</span><span class="token">: </span><span class="token" style="color: #005cc5;">String</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        setUsernameCalled </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">
</span></span><span class="line"><span class="token">        setUsernameReceivedValue</span><span class="token" style="color: #d73a49;">:</span><span class="token"> username    
</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-852"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-850">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-851'
	>
	With Sourcery, all you need to do is make your protocol inherit <code>Automockable</code>, like in this example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-855"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-853">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-854'
	>
	<code>extension ViewInterface: Automockable {}</code></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-858"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-856">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-857'
	>
	Now you know how Sourcery has been a great help to our team and it is one of our favourite libraries for generating tests.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-861"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-859">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-860'
	>
	Quick &amp; Nimble</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-864"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-862">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-863'
	>
	We’ve put these two libraries together as they usually go hand in hand. <a href="https://quick.readthedocs.io/en/stable/">Quick</a> is a behavior-driven development framework for Swift and Objective-C, while Nimble is used as an assertion framework that makes it easy to match expectations on tests. To get an idea how tests written with these frameworks look like, check the code below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-866"
	 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">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Quick</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Nimble</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">class DolphinSpec</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">QuickSpec </span><span class="token">{</span><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 spec</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">it(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">is friendly</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><span class="line"><span class="token">           </span><span class="token">expect(</span><span class="token">Dolphin(</span><span class="token">)</span><span class="token">.</span><span class="token">isFriendly</span><span class="token">)</span><span class="token">.</span><span class="token">to(</span><span class="token">beTruthy(</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">it(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">is smart</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><span class="line"><span class="token">           </span><span class="token">expect(</span><span class="token">Dolphin(</span><span class="token">)</span><span class="token">.</span><span class="token">isSmart</span><span class="token">)</span><span class="token">.</span><span class="token">to(</span><span class="token">beTruthy(</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><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-869"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-867">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-868'
	>
	OHHTTPStubs</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-872"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-870">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-871'
	>
	OHTTPStubs is a library designed to stub network requests by using method swizzling. It works with <em>NSURLConnection</em>, <em>NSURLSession</em>, <em>AFNetworking</em>, <em>Alamofire</em> or any networking framework that uses Cocoa’s URL Loading System.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-874"
	 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">
</span></span><span class="line"><span class="token">stub(</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">condition:</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token">(</span><span class="token">request:</span><span class="token"> URLRequest</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">Bool</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;"> check whether this api call should be mocked by using the response closure</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;"> return false if it shouldn’t</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">,
</span></span><span class="line"><span class="token">    </span><span class="token">response:</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #005cc5;">_</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> OHHTTPStubsResponse </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;">let</span><span class="token"> path </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;">...path_to_your_file.json</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">fixture(</span><span class="token">filePath:</span><span class="token"> path</span><span class="token">, </span><span class="token">status:</span><span class="token"> </span><span class="token" style="color: #005cc5;">200</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-877"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-875">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-876'
	>
	This library comes in handy in several situations:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-880"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-878">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-879'
	>
	<li>mocking different API responses while the app is in development to check if our UI handles every case correctly,</li><li>easier integration testing by providing baked-in responses to your testing suite,</li><li>implementing a demo mode inside your application which doesn’t reach the actual server, but uses baked-in responses.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-883"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-881">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-882'
	>
	If you’d like to learn more about implementing such a demo mode, you can check out <a href="https://infinum.com/blog/easy-way-to-implement-demo-mode-in-ios-apps/">one of our previous articles</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-886"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-884">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-885'
	>
	RxTest / RxBlocking</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-889"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-887">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-888'
	>
	<a href="https://github.com/ReactiveX/RxSwift/tree/main/RxTest">RxTest</a> and <a href="https://github.com/ReactiveX/RxSwift/tree/main/RxBlocking">RxBlocking</a> are both parts of RxSwift. They are available via separate pods and also require separate imports.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-892"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-890">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-891'
	>
	RxTest is a great addition for testing Rx code. It comes with a <code>TestScheduler</code>, which is a virtual time scheduler. RxTest gives out two types of Observables: <em>HotObservables</em>, which replay time specified events using test scheduler, and <em>ColdObservables</em>, which behave just like regular ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-895"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-893">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-894'
	>
	RxBlocking gives you the power of converting a regular observable sequence to a blocking observable, which blocks the thread it is running on until the sequence times out or completes. This makes it a perfect tool for testing asynchronous tasks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-897"
	 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">
</span></span><span class="line"><span class="token">func testBlocking</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">throws</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">let</span><span class="token"> observable </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Observable.</span><span class="token">of(</span><span class="token" style="color: #005cc5;">10</span><span class="token">, </span><span class="token" style="color: #005cc5;">20</span><span class="token">, </span><span class="token" style="color: #005cc5;">30</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"> result </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">try</span><span class="token"> observable.</span><span class="token">toBlocking(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #005cc5;">first</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">XCTAssertEqual(</span><span class="token">result</span><span class="token">, </span><span class="token" style="color: #005cc5;">10</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-900"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-898">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-899'
	>
	Infinum’s development libraries</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-903"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-901">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-902'
	>
	We also use our own libraries in most of our projects, but since these are our open-source libraries, it did not seem right to steal the spotlight from other popular third-party libraries. However, you can check them out below as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-906"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-904">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-905'
	>
	<a href="https://github.com/infinum/iOS-prince-of-versions"><em>Prince of Versions</em></a> – used for easier versioning of your applications, allows you to prompt your users to update the app to the newest version.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-909"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-907">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-908'
	>
	<a href="https://github.com/infinum/Japx"><em>Japx</em></a> – lightweight <a href="https://jsonapi.org/">JSON:API</a> parser that flattens complex JSON:API structure and turns into simple JSON and vice versa</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-912"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-910">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-911'
	>
	<a href="https://github.com/infinum/Locker"><em>Locker</em></a> – a lightweight library for handling sensitive data (<em>String</em> type) in Keychain using iOS Biometrics features</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-915"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-913">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-914'
	>
	<a href="https://github.com/infinum/iOS-SwiftI18n/blob/master/README.md"><em>I18n</em></a> – a library that allows you to localize your app much easier, by adding custom properties to UI elements and setting up available languages within the code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-918"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-916">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-917'
	>
	<a href="https://github.com/infinum/iOS-Loggie"><em>Loggie</em></a> – used for capturing all HTTP/S requests the app makes and showing them in a simple table view, enabling easier API debugging.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-921"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-919">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-920'
	>
	Also, be sure to check out <a href="https://github.com/infinum/iOS-Nuts-And-Bolts">Nuts &amp; Bolts</a>, Infinum iOS team’s repo containing a centralized collection of commonly shared and reused code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-924"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-922">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-923'
	>
	Anything we forgot to include?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-927"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-925">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-926'
	>
	Do you use the same or similar libraries in your work? Or perhaps you know of other useful libraries that should be included in this list? Let us know via social media – we’re always happy to learn new things about iOS.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-930"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-928">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-929'
	>
	Until next time, happy coding!</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/ios-libraries-2021/">Most Important iOS Libraries in 2021</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7883https://infinum.com/uploads/2021/05/how-to-design-app-for-ipad-0.webp</url>
				</image>
				<title>How to Design an App for iPad in 2021</title>
				<link>https://infinum.com/blog/how-to-design-app-for-ipad/</link>
				<pubDate>Mon, 03 May 2021 09:35:00 +0000</pubDate>
				<dc:creator>Petar Jadek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/how-to-design-app-for-ipad/</guid>
				<description>
					<![CDATA[<p>Great iPad apps shouldn&#8217;t look like lovechildren between a Mac and an iPhone.</p>
<p>The post <a href="https://infinum.com/blog/how-to-design-app-for-ipad/">How to Design an App for iPad in 2021</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1078"
	 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-933">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-936"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-934">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-935'
	>
	Ever since the first iPad release in 2010, this lightweight, big screen device has gotten more powerful hardware with each iteration. It has given developers the opportunity to create a variety of apps, from beautiful, graphic intensive games to Apple Pencil-supported apps for drawing. An iPad can even run things we never would’ve imagined these days.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-939"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-937">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-938'
	>
	However, until WWDC 2019, the software inside the iPad was just a scaled-up version of iOS, minus a few distinct features that were custom-created for the iPad. To say the least, it didn’t look like much.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-942"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-940">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-941'
	>
	At last, an iPadOS?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-945"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-943">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-944'
	>
	Then, in June 2019 at WWDC, Apple finally offered a solution for the problem in the form of the iPadOS 13.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-948"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-946">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-947'
	>
	In the background, it featured everything iOS 13 did, plus some of the functionality features created specifically for the iPad and based on the philosophy of the device itself. In addition to Home Screen, multitasking, Safari, and Sidecar changes, there was also mouse and keyboard support, which marked the beginning of change in how people can use their iPads.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-951"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-949">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-950'
	>
	However, the new features hardly offered any info about designing the apps other than how to adapt the design to the newly introduced dark mode.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-954"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-952">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-953'
	>
	iPadOS 2.0</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-957"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-955">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-956'
	>
	Luckily, in the summer 2020 edition of WWDC, Apple decided to push the iPad experience even further with iPadOS 14, introducing the new Scribble mode, a compact UI, and several essential system-wide redesign features.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-960"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-958">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-959'
	>
	This new design took the best ideas from macOS and iOS and combined them into something that looks new but feels very familiar. It reminded us that the iPad is a device in its own right, and urges designers and developers to make an effort and adapt a digital product’s design according to the device it will run on.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-963"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-961">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-962'
	>
	How to adapt an app to the iPad?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-966"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-964">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-965'
	>
	When adapting your current iPad apps, you should revolve around two goals, or checkpoints, depending on the app and its purpose: layout and user interaction.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-969"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-967">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-968'
	>
	Design and layout app adaptation</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-972"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-970">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-971'
	>
	Can you tell what’s wrong with the user experience in the screen below?</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-974">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-1-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-978"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-976">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-977'
	>
	We can see a tab bar app with the Home screen, and that the enlarged iPhone interface doesn’t really work. By applying a few simple steps, we can make this app easier to navigate and utilize space in a better way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-981"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-979">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-980'
	>
	The sidebar</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-984"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-982">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-983'
	>
	Ever since iPadOS 13, iPad apps come in two width classes – regular and compact.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-987"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-985">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-986'
	>
	Compact sizes are used for slide-over apps. This means that if this app happens to be displayed in its compact width, the sidebar will never appear and the user will navigate through tabs. However, once any app is in its split view or full size, the sidebar is the way to go.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-990"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-988">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-989'
	>
	Apps should never use both the sidebar and tab bar at the same time because it can be confusing to the user. Stick to one option depending on the app width.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-993"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-991">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-992'
	>
	Let’s add the sidebar.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-995">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-2-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-999"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-997">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-998'
	>
	With the iPadOS 14, sidebars do not only display navigation but can also be customized by the user. For example, users can simply drag and drop favorite artists into the sidebar, making the most important content easily accessible. Awesome!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1002"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1000">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1001'
	>
	Sidebars can be toggled with a button that comes automatically, after which the full size of the view will emerge. However, if you want to access it in portrait mode, you have to swipe from the left side to the screen and it will present itself.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1005"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1003">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1004'
	>
	The best use case of the sidebars is quick and easy access to important content. Don’t go too deep into the hierarchy because this kind of UI is not suitable for that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1008"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1006">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1007'
	>
	Content size</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1011"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1009">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1010'
	>
	When talking about content size, always think about displaying it in a sense where you can put as much as possible in a way that is pleasant to the eye and readable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1014"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1012">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1013'
	>
	The next screen shows things you should avoid.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1016">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-3-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1020"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1018">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1019'
	>
	Imagine owning a 12.9 inch iPad Pro and being able to see only six albums at a time. Does that make sense at all? And what if I told you that with a simple readability rule, you could put more content on a single screen, without forcing users to scroll through six things at once?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1023"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1021">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1022'
	>
	Here’s how it works.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1025">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-4-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1029"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1027">
	<h4	class='typography typography--size-24-text js-typography block-heading__heading'
	data-id='es-1028'
	>
	The context</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1032"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1030">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1031'
	>
	This has a lot to do with modals and popovers. If possible, modals should be avoided unless using them really makes sense. Their actions may be better presented as a popover or a simple toolbar.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1035"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1033">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1034'
	>
	The end result of either option is staying in the same context of the screen you are currently on.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1037">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-5-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1041"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1039">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1040'
	>
	For example, using a modal in the screen above doesn’t make sense at all. Since the content behind those actions is under their direct influence, the best way of representing them is within the same context to which they are applied.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1044"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1042">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1043'
	>
	Now, the only thing left is to check whether there is enough space to put them. In this case, the answer is yes.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1046">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-6-1400x895.webp				media='(max-width: 699px)'
				type=image/webp								height="895"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/04/how-to-design-app-for-ipad-6.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1023"
															width="1600"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1050"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1048">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1049'
	>
	This way of displaying actions provides more context to the content and gives the user ability to use these actions much quicker than before.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1053"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1051">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-1052'
	>
	User interaction</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1056"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1054">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1055'
	>
	There have never been more possibilities to use an iPad. What used to be just a multi-touch device nowadays has a pencil, keyboard, and mouse support.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1059"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1057">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1058'
	>
	This means that you can easily integrate keyboard shortcuts into your app. You can also combine multiple interactions to achieve the specific usage functionality. For example, keyboard and mouse combined can be used for selecting items the same way like we’ve been doing it on macOS for years.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1064"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1060">
	
	<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-1061'>
	<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-1062'
	>
	Giving users the possibility of interacting with the app and customizing it the way they like makes for a richer user experience.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1067"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-1065">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-1066'
	>
	Embrace the new design era with iPadOS 14</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1070"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1068">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1069'
	>
	Repeat after me: Great iPad apps shouldn’t be lovechildren between a Mac and an iPhone, stuck in 2016.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1073"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1071">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1072'
	>
	Even though adaptation cannot be applied on every app, or every screen of the app, reorganizing the user interface in order to create a better user experience is probably easier than you think.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1076"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-1074">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-1075'
	>
	So add that sidebar and allow the user to customize it to achieve faster access to their favorite content, and take advantage of the new interaction methods to complement new usability options when developing your next iPad app.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/how-to-design-app-for-ipad/">How to Design an App for iPad in 2021</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>