<?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>Developing iOS Apps Using VIPER: 3 Years Later | Infinum</title>
		<atom:link href="https://infinum.com/blog/developing-ios-apps-using-viper-3-years-later/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/developing-ios-apps-using-viper-3-years-later/</link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 09 Apr 2026 07:28:10 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7974https://infinum.com/uploads/2018/09/developing-ios-apps-using-viper-3-years-later-0.webp</url>
				</image>
				<title>Developing iOS Apps Using VIPER: 3 Years Later</title>
				<link>https://infinum.com/blog/developing-ios-apps-using-viper-3-years-later/</link>
				<pubDate>Thu, 06 Sep 2018 17:00:00 +0000</pubDate>
				<dc:creator>Damjan Vujaklija</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/developing-ios-apps-using-viper-3-years-later/</guid>
				<description>
					<![CDATA[<p>Talking about the touchy subject of architecture in iOS development, and how we tackle this issue at Infinum.</p>
<p>The post <a href="https://infinum.com/blog/developing-ios-apps-using-viper-3-years-later/">Developing iOS Apps Using VIPER: 3 Years Later</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-160"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	If you’re familiar with iOS development, there’s a big chance you know that architecture is a touchy subject. We won’t go over that particular problem here since there are a lot of good posts on the web that already cover that. Instead, we’ll talk about how we tackle this issue at Infinum.</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-heading" data-id="es-96">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-97'
	>
	How we got here</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Apple’s proposed MVC architecture wasn’t bad for many of our smaller apps, especially when we started with iOS development. However, as our projects grew more extensive and complex, it became harder to handle many cases cleanly and consistently. So, we started searching for something else and finally came across VIPER.</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'
	>
	When we started diving into this new architecture, our iOS team counted ten people, so we were already a bit late to the party. Now that this number has doubled, I cannot imagine working in an agency environment without a well-defined project architecture. Of course, if you are a one-man band, that doesn’t mean you don’t need a suitable architecture for yourself and all future developers coming to the project. But the need for this is even more apparent in an agency environment.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	VIPER is not a silver bullet by any means, nor is any other architecture. But when you have circa 40 projects being switched between 20 people where the assignments can be anything from a 15-minute bug-fix to a couple of months worth of development, you want to have a well-defined and standardized architecture that everyone understands and uses correctly. That allows anyone from a junior newcomer to a seasoned smart-ass to know the where, what, and why, making it easier to get the job done correctly and fast.</p></div>	</div>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	To give a concise introduction, the VIPER architecture is an implementation of <a href="https://8thlight.com/blog/uncle-bob/">Uncle Bob’s</a> <a href="https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html">clean architecture</a>. To put it into the context of iOS, what used to be a (possibly massive) <em>UIViewController</em> is now a module consisting of 5 elements:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-114">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-115'
	>
	<li><em>View</em> contains only view logic. It is the most reusable component.</li><li><em>Interactor</em> handles data fetching and abstracts the data store.</li><li><em>Presenter</em> connects the <em>View</em> and the <em>Interactor</em> and as such contains most business logic. It is the least reusable component.</li><li><em>Entity</em> refers to the actual models.</li><li><em>Router</em> (also commonly referred to as <em>Wireframe</em>) handles navigation logic, initializes and sets up the <em>Router/Presenter/View/Interactor</em> communication.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-117">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-118'
	>
	Where we started</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	There are a bunch of great posts on the web that talk about the VIPER architecture for iOS apps. Many don’t go into accurate detail about how to implement this architecture in real life.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	When we started with VIPER, we tried a couple of different approaches on real-life projects. This allowed us to figure out what works and what doesn’t quickly. Here are some of the methods we tried that didn’t end up feasible:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-126">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-127'
	>
	<li>one master router that handles navigation throughout the whole app</li><li>interfaces for everything, everywhere, all the time</li><li>object references hierarchy based on object responsibilities</li><li>writing all classes and interfaces manually</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-129">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-130'
	>
	Where we wound up</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-132">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-133'
	>
	After a couple of months of trial and error, we got to some excellent solutions and approaches:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-135">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-136'
	>
	<li>one router per module (in practice, one module refers to one UIViewController)</li><li>use interfaces mainly between main components (View, Interactor, Presenter, Entity, Router) and other classes that require reusability and testability</li><li>object references hierarchy based on what works well with the native technology – our module lifecycle is covered with the UIViewController lifecycle since the View has a solid reference to the Presenter, which has a reliable reference for the rest of the elements in the module</li><li>using template code generators is maybe the most crucial point which allowed us to speed up development dramatically and also normalize the way we write these components – for instance, all our interfaces for a module are inside one Interfaces.swift file which allows you to quickly get a good grasp of the entire module’s behavior and responsibilities</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-138">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-139'
	>
	These are just a couple of broad points we iterated over. There were also other minor points like naming, folder structure, standardization of navigation, data passing, etc.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-141">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-142'
	>
	We finally distilled the actual architecture implementation into templates. We open-sourced <a href="//github.com/infinum/iOS-VIPER-Xcode-Templates">VIPER Xcode templates on Github</a> with an in-detail description of how they should be used and why.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-144">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-145'
	>
	The takeaway</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-147">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-148'
	>
	It is not easy to fully grasp the theory and practice behind VIPER. We think we found a way to utilize all of its merits because our implementation stays true to the theory behind it, but we also made the learning curve much less steep by using templates and well-defined rules.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-151'
	>
	The main issue with VIPER, and to some degree with other non-standard architectures, is that you sometimes have to work against the native API’s standard usage. There is no such thing as free abstraction, but we were willing to pay for ours since the pros outweighed the cons.</p></div>	</div>

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

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-154">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2018/09/developing-ios-apps-using-viper-3-years-later-1-1400x840.webp				media='(max-width: 699px)'
				type=image/webp								height="840"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2018/09/developing-ios-apps-using-viper-3-years-later-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="846"
															width="1410"
										loading="lazy"
					 />
					</picture>

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

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	After more than three years of using VIPER, we’re still trying out new things now and then to stay sharp, but we’ve adopted it as a company-wide standard for any project with more than a couple of screens or lasting more than a couple of sprints. We’re still on the VIPER bandwagon and very happy to ride along.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/developing-ios-apps-using-viper-3-years-later/">Developing iOS Apps Using VIPER: 3 Years Later</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>