SlideShare a Scribd company logo
Introduction to VIPER
Architecture
Hendy Christianto
Why VIPER?
• MVC - Massive View Controller
• What goes into View Controllers?
• Data sources for Views (UITableViews)
• Business Logic
• Application Flows
• Transition between view controller
What is VIPER?
• Based on clean architecture to Uncle Bob’s
clean architecture.
• Basically a new architecture, introduced on 2014
• Used to resolve “Massive View Controller”
• Using “Single Responsibility” as a principle
Architecture of VIPER
View
• The View is passive
• Waits for the Presenter to give content to display
• Detect user interaction
• The view is an abstract interface
View Cont’d
@protocol SignInEmailView <NSObject>
- (void)setEmailLabelText:(NSString *)email;
- (void)setPasswordLabelText:(NSString *)password;
@end
#import <UIKit/UIKit.h>
#import "SignInEmailView.h"
@interface ViewController : UIViewController <SignInEmailView>
@end
only protocols, abstract interface
implements SignInEmailView interface
View Presenter
setPasswordLabelText:
Presenter
• Tells the view what to display
• Handle events
Presenter Cont’d
@implementation ViewController
#pragma mark -
#pragma mark View Interface
- (void)setEmailLabelText:(NSString *)email {
self.emailLabel.text = email;
}
- (void)setPasswordLabelText:(NSString *)password {
self.passwordLabel.text = password;
}
- (void)setErrorMessage:(NSString *)error {
self.errorLabel.text = error;
}
#pragma mark -
#pragma mark IBAction
- (IBAction)buttonLoginClicked:(id)sender {
[self.presenter didLoginWithEmail:self.emailTextField.text
password:self.passwordTextField.text];
}
PresenterView
buttonLoginClicked:
didLoginWithEmail: password:
Interactor
signInWithEmail:password:
@implementation SignInPresenter
#pragma mark -
#pragma mark Wireframe Update UI
- (void)presentSignInEmailView {
[self.view setPasswordLabelText:@"Password"];
[self.view setEmailLabelText:@"Email"];
}
- (void)didLoginWithEmail:(NSString *)email password:(NSString *)password {
[self.interactor signInWithEmail:email password:password];
}
@end
#import <Foundation/Foundation.h>
#import "SignInEmailView.h"
#import "SignInInteractorIO.h"
@interface SignInPresenter : NSObject
@property (nonatomic, weak) id <SignInEmailView> view;
@property (nonatomic, strong) id <SignInInteractorInput> interactor;
- (void)presentSignInEmailView;
- (void)didLoginWithEmail:(NSString *)email password:(NSString *)password;
@end
Interactor
• Perform business logic
• Carry out events that notified by presenter
(input)
• Produce output and notify back the presenter
Interactor Cont’d
InteractorPresenter
signInWithEmail:password:
didSignInWithResponse:
@implementation SignInPresenter
#pragma mark -
#pragma mark Wireframe Update UI
- (void)presentSignInEmailView {
[self.view setPasswordLabelText:@"Password"];
[self.view setEmailLabelText:@"Email"];
}
- (void)didLoginWithEmail:(NSString *)email password:(NSString *)password {
[self.interactor signInWithEmail:email password:password];
}
#pragma mark -
#pragma mark Interactor
- (void)didSignInWithResponse:(NSDictionary *)response {
NSError *error = response[@"error"];
if (error) {
[self.view setErrorMessage:error.domain];
} else {
[self.signInWireframe pushWelcomeView];
}
}
@interface SignInInteractor ()
@property (nonatomic, strong) SignInDataManager *dataManager;
@end
@implementation SignInInteractor
- (void)signInWithEmail:(NSString *)email password:(NSString *)password {
[self.dataManager userWithEmail:email password:password completion:^(User *user) {
NSMutableDictionary *response = [NSMutableDictionary new];
if (user) {
response[@"user"] = user;
} else {
response[@"error"] = [NSError errorWithDomain:@"User Not Found"
code:404 userInfo:nil];
}
[self.output didSignInWithResponse:response];
}];
}
@end
@interface SignInInteractor : NSObject <SignInInteractorInput>
@property (nonatomic, weak) id <SignInInteractorOutput> output;
@end
@protocol SignInInteractorInput <NSObject>
- (void)signInWithEmail:(NSString *)email password:(NSString *)password;
@end
@protocol SignInInteractorOutput <NSObject>
- (void)didSignInWithResponse:(NSDictionary *)response;
Data
Manager
userWithEmail:password:completion:
completion:^(User *user)
Data Manager
• Fetch data from database
• Restructure data to model / entities
• Store data
Data Manager Cont’d
Data
Manager
Interactor
@interface SignInInteractor ()
@property (nonatomic, strong) SignInDataManager *dataManager;
@end
@implementation SignInInteractor
- (void)signInWithEmail:(NSString *)email password:(NSString *)password {
[self.dataManager userWithEmail:email password:password completion:^(User *user) {
NSMutableDictionary *response = [NSMutableDictionary new];
if (user) {
response[@"user"] = user;
} else {
response[@"error"] = [NSError errorWithDomain:@"User Not Found"
code:404 userInfo:nil];
}
[self.output didSignInWithResponse:response];
}];
}
@end
Service
userWithEmail:password:completion:
@implementation SignInDataManager
- (void)userWithEmail:(NSString *)email password:(NSString *)password
completion:(void (^)(User *))completionBlock {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(email == %@)", email];
[self.dataStore fetchEntriesWithPredicate:predicate sortDescriptors:@[]
completionBlock:^(NSArray *results) {
if (completionBlock) {
if (results.count == 0) {
completionBlock(nil);
} else {
completionBlock(results[0]);
}
}
}];
}
@end
fetchEntriesWithPredicate:sortDescriptors:completionBlock
results arrayrun completionBlock:
Service
• Execute requests related to Entities / Models
• Network/ API, Database (local)
Entities
• Represent data
• Passed between class
Entities Cont’d
@interface User : NSManagedObject
@property (nonatomic, strong) NSString *email;
@property (nonatomic, strong) NSString *name;
@end
@implementation User
@dynamic name;
@dynamic email;
@end
Wireframe
• Initialize view controllers, Presenter, Interactor
• Handles routing / navigation within Views
Wireframe Cont’d
@class SignInPresenter;
@class WelcomeWireframe;
@interface SignInWireframe : RootWireframe
@property (nonatomic, strong) WelcomeWireframe *welcomeWireframe;
- (void)pushWelcomeView;
- (void)presentSignInViewControllerOnWindow:(UIWindow *)window;
@end
static NSString *ViewControllerIdentifier = @"ViewController";
@interface SignInWireframe ()
@property (nonatomic, strong) SignInPresenter *presenter;
@property (nonatomic, strong) SignInInteractor *interactor;
@end
@implementation SignInWireframe
- (void)initializeClasses {
self.presenter = [[SignInPresenter alloc] init];
self.interactor = [[SignInInteractor alloc] init];
self.presenter.interactor = self.interactor;
self.interactor.output = self.presenter;
}
- (void)presentSignInViewControllerOnWindow:(UIWindow *)window {
[self initializeClasses];
ViewController *signInVC = [self signInViewController];
signInVC.presenter = self.presenter;
self.presenter.view = signInVC;
[self createNavigationControllerWithRootView:signInVC];
window.rootViewController = self.navigationController;
}
- (void)pushWelcomeView {
[self.welcomeWireframe pushWelcomeViewControllerOnNavigation:self.navigationController];
}
- (ViewController *)signInViewController {
UIStoryboard *storyboard = [self mainStoryboard];
ViewController *signInVC = [storyboard instantiateViewControllerWithIdentifier:ViewControllerIdentifier];
return signInVC;
}
Benefits of Viper
• Easy to iterate on
• Collaboration-friendly
• Separated concerns
• Easy to test
Conclusion
• Helps developer to be more explicit about
separation of code
• Single responsibility each class, easier to
maintain
• Neat Code!!
References
• http://mutualmobile.github.io/blog/2013/12/04/viper-
introduction/
• http://www.objc.io/issue-13/viper.html
• https://medium.com/brigade-engineering/brigades-
experience-using-an-mvc-alternative-36ef1601a41f
• http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-
architecture.html
• iOS viper presentation - http://www.slideshare.net/
RajatDatta1/i-os-viper-presentation
DEMOS
Q&A

More Related Content

PDF
Infinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
PDF
iOS viper presentation
PDF
PDF
Infinum iOS Talks #4 - Making our VIPER more reactive
PDF
Break the monolith with (B)VIPER Modules
PPTX
Sexy Architecting. VIPER: MVP on steroids
PDF
Rambler.iOS #5: Разбираем Massive View Controller
PDF
Web sockets in Angular
Infinum iOS Talks #2 - VIPER for everybody by Damjan Vujaklija
iOS viper presentation
Infinum iOS Talks #4 - Making our VIPER more reactive
Break the monolith with (B)VIPER Modules
Sexy Architecting. VIPER: MVP on steroids
Rambler.iOS #5: Разбираем Massive View Controller
Web sockets in Angular

What's hot (20)

PDF
Reactive Thinking in Java with RxJava2
PDF
Angular2 Development for Java developers
PPTX
Angular 4
PDF
Angular 4 for Java Developers
PPTX
Introduction to Angular JS
PDF
PPTX
Moving From AngularJS to Angular 2
PPTX
Sitecore MVC (London User Group, April 29th 2014)
PPTX
Introduction to angular with a simple but complete project
PPT
Angular js
PPTX
Flux architecture
PDF
Azure Container Apps
PPTX
PDF
Overview of the AngularJS framework
PPTX
Asp.Net MVC 5 in Arabic
PPTX
Introduction to ASP.Net MVC
PDF
RESTful services and OAUTH protocol in IoT
PDF
Introduction to Angular 2
PDF
Backbone.js
PPTX
AngularJS2 / TypeScript / CLI
Reactive Thinking in Java with RxJava2
Angular2 Development for Java developers
Angular 4
Angular 4 for Java Developers
Introduction to Angular JS
Moving From AngularJS to Angular 2
Sitecore MVC (London User Group, April 29th 2014)
Introduction to angular with a simple but complete project
Angular js
Flux architecture
Azure Container Apps
Overview of the AngularJS framework
Asp.Net MVC 5 in Arabic
Introduction to ASP.Net MVC
RESTful services and OAUTH protocol in IoT
Introduction to Angular 2
Backbone.js
AngularJS2 / TypeScript / CLI
Ad

Viewers also liked (20)

PDF
From mvc to viper
PPTX
VIPER - Design Pattern
PPTX
[SIP 2015] iOS Proposal: VIPER
PDF
Clean architecture workshop
PDF
Rambler.iOS #5: VIPER и Swift
PDF
Rambler.iOS #5: VIPER a la Rambler
PDF
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
PPTX
Software architectural design patterns(MVC, MVP, MVVM, VIPER) for iOS
PDF
Rambler.iOS #4: Как мы стали писать бизнес-логику
PDF
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
PDF
Rambler.iOS #3: Test-Driven Development в iOS
PDF
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
PPTX
ReactiveCocoa: делаем отзывчивое приложение (П. Руденко)
PDF
An (highly elementary) introduction to VIPER
PPTX
VIPER Architecture
PDF
Rambler.iOS #5: Генерамба и прочие аспекты кодогенерации в VIPER
PDF
iOS advanced architecture workshop 3h edition
PDF
Clean Architecture
PPTX
Viper - чистая архитектура iOS-приложения (И. Чирков)
PDF
Dependence day insurgence
From mvc to viper
VIPER - Design Pattern
[SIP 2015] iOS Proposal: VIPER
Clean architecture workshop
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER a la Rambler
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
Software architectural design patterns(MVC, MVP, MVVM, VIPER) for iOS
Rambler.iOS #4: Как мы стали писать бизнес-логику
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Rambler.iOS #3: Test-Driven Development в iOS
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
ReactiveCocoa: делаем отзывчивое приложение (П. Руденко)
An (highly elementary) introduction to VIPER
VIPER Architecture
Rambler.iOS #5: Генерамба и прочие аспекты кодогенерации в VIPER
iOS advanced architecture workshop 3h edition
Clean Architecture
Viper - чистая архитектура iOS-приложения (И. Чирков)
Dependence day insurgence
Ad

Similar to Introduction to VIPER Architecture (20)

PDF
Medium TechTalk — iOS
PDF
Intro to ReactiveCocoa
PPTX
Building Your First App with MongoDB Stitch
PDF
Building an Angular 2 App
PPTX
Angular 2 at solutions.hamburg
PDF
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
PDF
Functionnal view modelling
PDF
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
PPTX
[NDC 2019] Enterprise-Grade Serverless
PPTX
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
PDF
The use case of a scalable architecture
PPTX
Tutorial: Building Your First App with MongoDB Stitch
PDF
Implement Service Broker with Spring Boot #cf_tokyo
PPTX
Asp.NET MVC
PPTX
[MongoDB.local Bengaluru 2018] Introduction to MongoDB Stitch
PDF
Angular for Java Enterprise Developers: Oracle Code One 2018
PDF
ReactiveCocoa in Practice
PPTX
Angular js 2
PPTX
Mobile Developers Talks: Delve Mobile
PPTX
Building a TV show with Angular, Bootstrap, and Web Services
Medium TechTalk — iOS
Intro to ReactiveCocoa
Building Your First App with MongoDB Stitch
Building an Angular 2 App
Angular 2 at solutions.hamburg
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Functionnal view modelling
[Serverless Meetup Tokyo #3] Serverless in Azure (Azure Functionsのアップデート、事例、デ...
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
The use case of a scalable architecture
Tutorial: Building Your First App with MongoDB Stitch
Implement Service Broker with Spring Boot #cf_tokyo
Asp.NET MVC
[MongoDB.local Bengaluru 2018] Introduction to MongoDB Stitch
Angular for Java Enterprise Developers: Oracle Code One 2018
ReactiveCocoa in Practice
Angular js 2
Mobile Developers Talks: Delve Mobile
Building a TV show with Angular, Bootstrap, and Web Services

Recently uploaded (20)

PDF
Well-logging-methods_new................
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PPT
Mechanical Engineering MATERIALS Selection
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PPTX
OOP with Java - Java Introduction (Basics)
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PPTX
Welding lecture in detail for understanding
PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PDF
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PPTX
additive manufacturing of ss316l using mig welding
PPTX
web development for engineering and engineering
PPTX
Internet of Things (IOT) - A guide to understanding
PDF
composite construction of structures.pdf
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PDF
Structs to JSON How Go Powers REST APIs.pdf
PPTX
Strings in CPP - Strings in C++ are sequences of characters used to store and...
Well-logging-methods_new................
Operating System & Kernel Study Guide-1 - converted.pdf
Mechanical Engineering MATERIALS Selection
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
OOP with Java - Java Introduction (Basics)
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
Welding lecture in detail for understanding
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
additive manufacturing of ss316l using mig welding
web development for engineering and engineering
Internet of Things (IOT) - A guide to understanding
composite construction of structures.pdf
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
Structs to JSON How Go Powers REST APIs.pdf
Strings in CPP - Strings in C++ are sequences of characters used to store and...

Introduction to VIPER Architecture

  • 2. Why VIPER? • MVC - Massive View Controller • What goes into View Controllers? • Data sources for Views (UITableViews) • Business Logic • Application Flows • Transition between view controller
  • 3. What is VIPER? • Based on clean architecture to Uncle Bob’s clean architecture. • Basically a new architecture, introduced on 2014 • Used to resolve “Massive View Controller” • Using “Single Responsibility” as a principle
  • 5. View • The View is passive • Waits for the Presenter to give content to display • Detect user interaction • The view is an abstract interface
  • 6. View Cont’d @protocol SignInEmailView <NSObject> - (void)setEmailLabelText:(NSString *)email; - (void)setPasswordLabelText:(NSString *)password; @end #import <UIKit/UIKit.h> #import "SignInEmailView.h" @interface ViewController : UIViewController <SignInEmailView> @end only protocols, abstract interface implements SignInEmailView interface View Presenter setPasswordLabelText:
  • 7. Presenter • Tells the view what to display • Handle events
  • 8. Presenter Cont’d @implementation ViewController #pragma mark - #pragma mark View Interface - (void)setEmailLabelText:(NSString *)email { self.emailLabel.text = email; } - (void)setPasswordLabelText:(NSString *)password { self.passwordLabel.text = password; } - (void)setErrorMessage:(NSString *)error { self.errorLabel.text = error; } #pragma mark - #pragma mark IBAction - (IBAction)buttonLoginClicked:(id)sender { [self.presenter didLoginWithEmail:self.emailTextField.text password:self.passwordTextField.text]; } PresenterView buttonLoginClicked: didLoginWithEmail: password: Interactor signInWithEmail:password: @implementation SignInPresenter #pragma mark - #pragma mark Wireframe Update UI - (void)presentSignInEmailView { [self.view setPasswordLabelText:@"Password"]; [self.view setEmailLabelText:@"Email"]; } - (void)didLoginWithEmail:(NSString *)email password:(NSString *)password { [self.interactor signInWithEmail:email password:password]; } @end #import <Foundation/Foundation.h> #import "SignInEmailView.h" #import "SignInInteractorIO.h" @interface SignInPresenter : NSObject @property (nonatomic, weak) id <SignInEmailView> view; @property (nonatomic, strong) id <SignInInteractorInput> interactor; - (void)presentSignInEmailView; - (void)didLoginWithEmail:(NSString *)email password:(NSString *)password; @end
  • 9. Interactor • Perform business logic • Carry out events that notified by presenter (input) • Produce output and notify back the presenter
  • 10. Interactor Cont’d InteractorPresenter signInWithEmail:password: didSignInWithResponse: @implementation SignInPresenter #pragma mark - #pragma mark Wireframe Update UI - (void)presentSignInEmailView { [self.view setPasswordLabelText:@"Password"]; [self.view setEmailLabelText:@"Email"]; } - (void)didLoginWithEmail:(NSString *)email password:(NSString *)password { [self.interactor signInWithEmail:email password:password]; } #pragma mark - #pragma mark Interactor - (void)didSignInWithResponse:(NSDictionary *)response { NSError *error = response[@"error"]; if (error) { [self.view setErrorMessage:error.domain]; } else { [self.signInWireframe pushWelcomeView]; } } @interface SignInInteractor () @property (nonatomic, strong) SignInDataManager *dataManager; @end @implementation SignInInteractor - (void)signInWithEmail:(NSString *)email password:(NSString *)password { [self.dataManager userWithEmail:email password:password completion:^(User *user) { NSMutableDictionary *response = [NSMutableDictionary new]; if (user) { response[@"user"] = user; } else { response[@"error"] = [NSError errorWithDomain:@"User Not Found" code:404 userInfo:nil]; } [self.output didSignInWithResponse:response]; }]; } @end @interface SignInInteractor : NSObject <SignInInteractorInput> @property (nonatomic, weak) id <SignInInteractorOutput> output; @end @protocol SignInInteractorInput <NSObject> - (void)signInWithEmail:(NSString *)email password:(NSString *)password; @end @protocol SignInInteractorOutput <NSObject> - (void)didSignInWithResponse:(NSDictionary *)response; Data Manager userWithEmail:password:completion: completion:^(User *user)
  • 11. Data Manager • Fetch data from database • Restructure data to model / entities • Store data
  • 12. Data Manager Cont’d Data Manager Interactor @interface SignInInteractor () @property (nonatomic, strong) SignInDataManager *dataManager; @end @implementation SignInInteractor - (void)signInWithEmail:(NSString *)email password:(NSString *)password { [self.dataManager userWithEmail:email password:password completion:^(User *user) { NSMutableDictionary *response = [NSMutableDictionary new]; if (user) { response[@"user"] = user; } else { response[@"error"] = [NSError errorWithDomain:@"User Not Found" code:404 userInfo:nil]; } [self.output didSignInWithResponse:response]; }]; } @end Service userWithEmail:password:completion: @implementation SignInDataManager - (void)userWithEmail:(NSString *)email password:(NSString *)password completion:(void (^)(User *))completionBlock { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(email == %@)", email]; [self.dataStore fetchEntriesWithPredicate:predicate sortDescriptors:@[] completionBlock:^(NSArray *results) { if (completionBlock) { if (results.count == 0) { completionBlock(nil); } else { completionBlock(results[0]); } } }]; } @end fetchEntriesWithPredicate:sortDescriptors:completionBlock results arrayrun completionBlock:
  • 13. Service • Execute requests related to Entities / Models • Network/ API, Database (local)
  • 14. Entities • Represent data • Passed between class
  • 15. Entities Cont’d @interface User : NSManagedObject @property (nonatomic, strong) NSString *email; @property (nonatomic, strong) NSString *name; @end @implementation User @dynamic name; @dynamic email; @end
  • 16. Wireframe • Initialize view controllers, Presenter, Interactor • Handles routing / navigation within Views
  • 17. Wireframe Cont’d @class SignInPresenter; @class WelcomeWireframe; @interface SignInWireframe : RootWireframe @property (nonatomic, strong) WelcomeWireframe *welcomeWireframe; - (void)pushWelcomeView; - (void)presentSignInViewControllerOnWindow:(UIWindow *)window; @end static NSString *ViewControllerIdentifier = @"ViewController"; @interface SignInWireframe () @property (nonatomic, strong) SignInPresenter *presenter; @property (nonatomic, strong) SignInInteractor *interactor; @end @implementation SignInWireframe - (void)initializeClasses { self.presenter = [[SignInPresenter alloc] init]; self.interactor = [[SignInInteractor alloc] init]; self.presenter.interactor = self.interactor; self.interactor.output = self.presenter; } - (void)presentSignInViewControllerOnWindow:(UIWindow *)window { [self initializeClasses]; ViewController *signInVC = [self signInViewController]; signInVC.presenter = self.presenter; self.presenter.view = signInVC; [self createNavigationControllerWithRootView:signInVC]; window.rootViewController = self.navigationController; } - (void)pushWelcomeView { [self.welcomeWireframe pushWelcomeViewControllerOnNavigation:self.navigationController]; } - (ViewController *)signInViewController { UIStoryboard *storyboard = [self mainStoryboard]; ViewController *signInVC = [storyboard instantiateViewControllerWithIdentifier:ViewControllerIdentifier]; return signInVC; }
  • 18. Benefits of Viper • Easy to iterate on • Collaboration-friendly • Separated concerns • Easy to test
  • 19. Conclusion • Helps developer to be more explicit about separation of code • Single responsibility each class, easier to maintain • Neat Code!!
  • 20. References • http://mutualmobile.github.io/blog/2013/12/04/viper- introduction/ • http://www.objc.io/issue-13/viper.html • https://medium.com/brigade-engineering/brigades- experience-using-an-mvc-alternative-36ef1601a41f • http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean- architecture.html • iOS viper presentation - http://www.slideshare.net/ RajatDatta1/i-os-viper-presentation
  • 21. DEMOS
  • 22. Q&A