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

What's hot (20)

PDF
Reactive Thinking in Java with RxJava2
Yakov Fain
 
PDF
Angular2 Development for Java developers
Yakov Fain
 
PPTX
Angular 4
Saurabh Juneja
 
PDF
Angular 4 for Java Developers
Yakov Fain
 
PPTX
Introduction to Angular JS
Santhosh Kumar Srinivasan
 
PDF
jQuery
Ivano Malavolta
 
PPTX
Moving From AngularJS to Angular 2
Exilesoft
 
PPTX
Sitecore MVC (London User Group, April 29th 2014)
Ruud van Falier
 
PPTX
Introduction to angular with a simple but complete project
Jadson Santos
 
PPT
Angular js
yogi_solanki
 
PPTX
Flux architecture
Boyan Mihaylov
 
PDF
Azure Container Apps
ninefyi
 
PPTX
Angular 5
Bartłomiej Narożnik
 
PDF
Overview of the AngularJS framework
Yakov Fain
 
PPTX
Asp.Net MVC 5 in Arabic
Haitham Shaddad
 
PPTX
Introduction to ASP.Net MVC
Sagar Kamate
 
PDF
RESTful services and OAUTH protocol in IoT
Yakov Fain
 
PDF
Introduction to Angular 2
Dawid Myslak
 
PDF
Backbone.js
Ivano Malavolta
 
PPTX
AngularJS2 / TypeScript / CLI
Domenico Rutigliano
 
Reactive Thinking in Java with RxJava2
Yakov Fain
 
Angular2 Development for Java developers
Yakov Fain
 
Angular 4
Saurabh Juneja
 
Angular 4 for Java Developers
Yakov Fain
 
Introduction to Angular JS
Santhosh Kumar Srinivasan
 
Moving From AngularJS to Angular 2
Exilesoft
 
Sitecore MVC (London User Group, April 29th 2014)
Ruud van Falier
 
Introduction to angular with a simple but complete project
Jadson Santos
 
Angular js
yogi_solanki
 
Flux architecture
Boyan Mihaylov
 
Azure Container Apps
ninefyi
 
Overview of the AngularJS framework
Yakov Fain
 
Asp.Net MVC 5 in Arabic
Haitham Shaddad
 
Introduction to ASP.Net MVC
Sagar Kamate
 
RESTful services and OAUTH protocol in IoT
Yakov Fain
 
Introduction to Angular 2
Dawid Myslak
 
Backbone.js
Ivano Malavolta
 
AngularJS2 / TypeScript / CLI
Domenico Rutigliano
 

Viewers also liked (20)

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

Similar to Introduction to VIPER Architecture (20)

PDF
Clean VIP (Clean Swift) architecture
Jianbin LIN
 
PDF
MBLTDev15: Egor Tolstoy, Rambler&Co
e-Legion
 
PDF
Elements for an iOS Backend
Laurent Cerveau
 
PDF
iPhonical and model-driven software development for the iPhone
Heiko Behrens
 
PPT
iOS Multithreading
Richa Jain
 
ODP
MobileCity:Core Data
Allan Davis
 
PDF
Implementing Inclusive Interfaces
Sally Shepard
 
PDF
MFF UK - Advanced iOS Topics
Petr Dvorak
 
PDF
iOS Contact List Application Tutorial
Ishara Amarasekera
 
PPTX
04 objective-c session 4
Amr Elghadban (AmrAngry)
 
PDF
Developing iOS REST Applications
lmrei
 
PPTX
iOS Development (Part 2)
Asim Rais Siddiqui
 
PPTX
Code camp 2011 Getting Started with IOS, Una Daly
Una Daly
 
KEY
iOSDevCamp 2011 Core Data
Chris Mar
 
PDF
Paparazzi2
Mahmoud
 
PDF
Adventures in Multithreaded Core Data
Inferis
 
PPTX
iOS Beginners Lesson 2
Calvin Cheng
 
PDF
Introduction of Xcode
Dhaval Kaneria
 
PDF
Taming Core Data by Arek Holko, Macoscope
Macoscope
 
PDF
CoreData Best Practices (2021)
deeje cooley
 
Clean VIP (Clean Swift) architecture
Jianbin LIN
 
MBLTDev15: Egor Tolstoy, Rambler&Co
e-Legion
 
Elements for an iOS Backend
Laurent Cerveau
 
iPhonical and model-driven software development for the iPhone
Heiko Behrens
 
iOS Multithreading
Richa Jain
 
MobileCity:Core Data
Allan Davis
 
Implementing Inclusive Interfaces
Sally Shepard
 
MFF UK - Advanced iOS Topics
Petr Dvorak
 
iOS Contact List Application Tutorial
Ishara Amarasekera
 
04 objective-c session 4
Amr Elghadban (AmrAngry)
 
Developing iOS REST Applications
lmrei
 
iOS Development (Part 2)
Asim Rais Siddiqui
 
Code camp 2011 Getting Started with IOS, Una Daly
Una Daly
 
iOSDevCamp 2011 Core Data
Chris Mar
 
Paparazzi2
Mahmoud
 
Adventures in Multithreaded Core Data
Inferis
 
iOS Beginners Lesson 2
Calvin Cheng
 
Introduction of Xcode
Dhaval Kaneria
 
Taming Core Data by Arek Holko, Macoscope
Macoscope
 
CoreData Best Practices (2021)
deeje cooley
 
Ad

Recently uploaded (20)

PPTX
Introduction to Design of Machine Elements
PradeepKumarS27
 
PDF
International Journal of Information Technology Convergence and services (IJI...
ijitcsjournal4
 
PPTX
Pharmaceuticals and fine chemicals.pptxx
jaypa242004
 
PDF
6th International Conference on Machine Learning Techniques and Data Science ...
ijistjournal
 
PPTX
Destructive Tests corrosion engineer (1).pptx
zeidali3
 
DOCX
8th International Conference on Electrical Engineering (ELEN 2025)
elelijjournal653
 
PPTX
REINFORCEMENT AS CONSTRUCTION MATERIALS.pptx
mohaiminulhaquesami
 
PDF
POWER PLANT ENGINEERING (R17A0326).pdf..
haneefachosa123
 
PDF
Statistical Data Analysis Using SPSS Software
shrikrishna kesharwani
 
PPTX
Thermal runway and thermal stability.pptx
godow93766
 
PPTX
Green Building & Energy Conservation ppt
Sagar Sarangi
 
PDF
IoT - Unit 2 (Internet of Things-Concepts) - PPT.pdf
dipakraut82
 
PDF
Book.pdf01_Intro.ppt algorithm for preperation stu used
archu26
 
PDF
Water Design_Manual_2005. KENYA FOR WASTER SUPPLY AND SEWERAGE
DancanNgutuku
 
PPTX
MPMC_Module-2 xxxxxxxxxxxxxxxxxxxxx.pptx
ShivanshVaidya5
 
PDF
Unified_Cloud_Comm_Presentation anil singh ppt
anilsingh298751
 
PDF
GTU Civil Engineering All Semester Syllabus.pdf
Vimal Bhojani
 
PPTX
The Role of Information Technology in Environmental Protectio....pptx
nallamillisriram
 
PDF
MAD Unit - 1 Introduction of Android IT Department
JappanMavani
 
PDF
PORTFOLIO Golam Kibria Khan — architect with a passion for thoughtful design...
MasumKhan59
 
Introduction to Design of Machine Elements
PradeepKumarS27
 
International Journal of Information Technology Convergence and services (IJI...
ijitcsjournal4
 
Pharmaceuticals and fine chemicals.pptxx
jaypa242004
 
6th International Conference on Machine Learning Techniques and Data Science ...
ijistjournal
 
Destructive Tests corrosion engineer (1).pptx
zeidali3
 
8th International Conference on Electrical Engineering (ELEN 2025)
elelijjournal653
 
REINFORCEMENT AS CONSTRUCTION MATERIALS.pptx
mohaiminulhaquesami
 
POWER PLANT ENGINEERING (R17A0326).pdf..
haneefachosa123
 
Statistical Data Analysis Using SPSS Software
shrikrishna kesharwani
 
Thermal runway and thermal stability.pptx
godow93766
 
Green Building & Energy Conservation ppt
Sagar Sarangi
 
IoT - Unit 2 (Internet of Things-Concepts) - PPT.pdf
dipakraut82
 
Book.pdf01_Intro.ppt algorithm for preperation stu used
archu26
 
Water Design_Manual_2005. KENYA FOR WASTER SUPPLY AND SEWERAGE
DancanNgutuku
 
MPMC_Module-2 xxxxxxxxxxxxxxxxxxxxx.pptx
ShivanshVaidya5
 
Unified_Cloud_Comm_Presentation anil singh ppt
anilsingh298751
 
GTU Civil Engineering All Semester Syllabus.pdf
Vimal Bhojani
 
The Role of Information Technology in Environmental Protectio....pptx
nallamillisriram
 
MAD Unit - 1 Introduction of Android IT Department
JappanMavani
 
PORTFOLIO Golam Kibria Khan — architect with a passion for thoughtful design...
MasumKhan59
 

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