SlideShare une entreprise Scribd logo
1  sur  76
Télécharger pour lire hors ligne
VIPER
то, о чем все говорят, но никто
не рассказывает
Автор
Егор Толстой
Ведущий iOS разработчик
Rambler&Co
Twitter: @igrekde
www.github.com/igrekde
CompositionViewController
@interface
@interface
[self updateContactsView];
CompositionViewController
@interface
[self updateContactsView];
CompositionViewController
- (void)saveMessageToDraft {
// Crash
}
CompositionViewController
- (void)sendMessage {
// Crash
}
CompositionViewController
@end
- (void)updateAddressBook {
// Crash
// Crash
// Crash
}
CompositionViewController
- (void)updateAddressBook {
if (invalidContacts) {
return;
}
}
@end
CompositionViewController
@end
CompositionViewController
@interface
CompositionViewController
Хотим 100% crash-free!
Хотим быстро и качественно!
Хотим чистый код!
Хотим модульность!
• Структура VIPER модуля
• Связь модулей
• Возможности использования VIPER
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER
E
E
TABLEVIEW
CELLFACTORY
View Presenter Interactor Router
- (void)viewDidLoad {
[super viewDidLoad];
}
[self setupBarWithTitle:@"#mbltdev"];
- (void)setupBarWithTitle:(NSString *)title {
self.navigationItem.title = title;
}
View Presenter Interactor Router
- (void)viewDidLoad {
[super viewDidLoad];
}
[self setupBarWithTitle:@"#mbltdev"];
- (void)setupBarWithTitle:(NSString *)title {
self.navigationItem.title = title;
}
View Presenter Interactor Router
Lifecycle
[self setupBarWithTitle:@"#mbltdev"];
View Presenter Interactor Router
Lifecycle
- (void)setupBarWithTitle:(NSString *)title {
self.navigationItem.title = title;
}
Navbar Setup
View Presenter Interactor Router
Lifecycle
Navbar Setup
[self setupBarWithTitle:@"#mbltdev"];
Handles events
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events
BOOL valid = [self.inputValidator
validatePhoneNumber:phoneNumber];
if (valid) {
} else {
}
[self processToNextScreen];
[self showErrorAlertView];
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events
if (valid) {
} else {
}
[self processToNextScreen];
[self showErrorAlertView];
BOOL valid = [self.inputValidator
validatePhoneNumber:phoneNumber];
Data validation
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events
if (valid) {
} else {
}
[self showErrorAlertView];
Data validation
[self processToNextScreen];
Module Routing
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events
if (valid) {
} else {
}
Data validation Module Routing
[self showErrorAlertView];Shows data
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if (valid) {
} else {
}
if-else
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else
[rootSavingContext performBlock:^{
Message *message =
[Message MR_findFirst];
}];
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else
[rootSavingContext performBlock:^{
Message *message =
[Message MR_findFirst];
}];
Data storage
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request];
[dataTask resume];
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request];
[dataTask resume];
Networking
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender {
segue.destinationViewController.inputData =
@"inputData";
}
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender {
segue.destinationViewController.inputData =
@"inputData";
}
Segues
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCell];
[cell setupWithObject:cellObject];
}
Segues
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCell];
[cell setupWithObject:cellObject];
}
Segues
Table DataSource
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (void)panGestureRecognizerDidChangeState:(id)sender {
CGPoint panPoint = [sender translationInView:self.view];
self.view.frame = CGRectMake(panPoint.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height);
}
Segues
Table DataSource
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
- (void)panGestureRecognizerDidChangeState:(id)sender {
CGPoint panPoint = [sender translationInView:self.view];
self.view.frame = CGRectMake(panPoint.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height);
}
Simple gestures
Segues
Table DataSource
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
Simple gestures
if (panPoint.x > 100.0f) {
}
[self showSideMenu];
Segues
Table DataSource
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
Simple gestures
if (panPoint.x > 100.0f) {
}
[self showSideMenu];Side Menu
Segues
Table DataSource
View Presenter Interactor Router
Lifecycle
Navbar Setup
Handles events Data validation Module Routing
Shows data
if-else Data storage
Networking
Segues
Table DataSource
Simple gestures
Side Menu
if (panPoint.x > 100.0f) {
}
Complex gestures
VIEW PRESENTER INTERACTOR
ROUTER
E
E
VIEW PRESENTER INTERACTOR
ROUTER ESERVICE
SERVICE
SERVICE
E
Роутер
должен
роутить
VIEW PRESENTER INTERACTOR
ROUTER ESERVICE
SERVICE
SERVICE
E
ASSEMBLY
Экран
=
Модуль
Экран
=
Модуль
UIViewController
UIView
UITabBarController
Daemon
VIEW PRESENTER INTERACTOR
ROUTER ESERVICE
SERVICE
SERVICE
E
ASSEMBLY
VIEW PRESENTER INTERACTOR
ROUTER ESERVICE
SERVICE
SERVICE
E
ASSEMBLY
PRESENTER
INTERACTOR
VIEW
ROUTER
VIEW
PRESENTER
INTERACTOR
ROUTER
Модуль 1 Модуль 2
PRESENTER
INTERACTOR
VIEW
ROUTER
VIEW
PRESENTER
INTERACTOR
ROUTER
@"Module2Segue"
<TransitionHandler> <ModuleInput>
Модуль 1 Модуль 2
@implementation Router
[[self.transitionHandler openModuleUsingSegue:SegueIdentifier]
        thenChainUsingBlock:^void(id<SomeModuleInput> moduleInput) {
                [moduleInput moduleConfigurationMethod];
        }];
@end
PRESENTER
INTERACTOR
VIEW
ROUTER
VIEW
PRESENTER
INTERACTOR
ROUTER
Список контактов Карточка контакта
contactId
contact
MODULEVIEW
MODULEPRESENTER
MODULEINTERACTOR
MODULEROUTER <SUBMODULE2INPUT>
<SUBMODULE1INPUT>
<SUBMODULE3INPUT>
~ 99% Code Coverage
VIEW
TEST
pod 'MyApp/Core', '1.2.2'
pod 'MyApp/Modules/CalendarModule', '1.5'
pod 'MyApp/Modules/SettingsModule', '1.0.1'
pod 'SharedModules/Authorization', '2.3.4'
• VIPER увеличивает тестируемость приложения,
• VIPER увеличивает модульность приложения,
• VIPER делает нашу жизнь немного прекраснее.
One more thing...
❤
VIPER
Open Source
• Рамблер.Конференции - приложение
• Generamba - генератор
• VIPER McFlurry - библиотека
• The Book of VIPER - сборник статей
https://github.com/rambler-ios
Дизайн: студия «Рамблер Инфографика»

Contenu connexe

Tendances

Tendances (20)

Workshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte II
 
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуй
 
Vue, vue router, vuex
Vue, vue router, vuexVue, vue router, vuex
Vue, vue router, vuex
 
Vue next
Vue nextVue next
Vue next
 
React, Redux, ES2015 by Max Petruck
React, Redux, ES2015   by Max PetruckReact, Redux, ES2015   by Max Petruck
React, Redux, ES2015 by Max Petruck
 
Workshop 3: JavaScript build tools
Workshop 3: JavaScript build toolsWorkshop 3: JavaScript build tools
Workshop 3: JavaScript build tools
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
Switch to React.js from AngularJS developer
Switch to React.js from AngularJS developerSwitch to React.js from AngularJS developer
Switch to React.js from AngularJS developer
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
React JS and Redux
React JS and ReduxReact JS and Redux
React JS and Redux
 
Mobile Day - React Native
Mobile Day - React NativeMobile Day - React Native
Mobile Day - React Native
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte III
 
React with Redux
React with ReduxReact with Redux
React with Redux
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
React state managmenet with Redux
React state managmenet with ReduxReact state managmenet with Redux
React state managmenet with Redux
 
Spring 4 advanced final_xtr_presentation
Spring 4 advanced final_xtr_presentationSpring 4 advanced final_xtr_presentation
Spring 4 advanced final_xtr_presentation
 
JavaFX GUI architecture with Clojure core.async
JavaFX GUI architecture with Clojure core.asyncJavaFX GUI architecture with Clojure core.async
JavaFX GUI architecture with Clojure core.async
 

En vedette

En vedette (14)

MBLTDev15: Hector Zarate, Spotify
MBLTDev15: Hector Zarate, SpotifyMBLTDev15: Hector Zarate, Spotify
MBLTDev15: Hector Zarate, Spotify
 
MBLT16: Andrey Bakalenko, Sberbank Online
MBLT16: Andrey Bakalenko, Sberbank OnlineMBLT16: Andrey Bakalenko, Sberbank Online
MBLT16: Andrey Bakalenko, Sberbank Online
 
MBLTDev15: Artemiy Sobolev, Parallels
MBLTDev15: Artemiy Sobolev, ParallelsMBLTDev15: Artemiy Sobolev, Parallels
MBLTDev15: Artemiy Sobolev, Parallels
 
MBLT16: Marvin Liao, 500Startups
MBLT16: Marvin Liao, 500StartupsMBLT16: Marvin Liao, 500Startups
MBLT16: Marvin Liao, 500Startups
 
MBLTDev: Evgeny Lisovsky, Litres
MBLTDev: Evgeny Lisovsky, LitresMBLTDev: Evgeny Lisovsky, Litres
MBLTDev: Evgeny Lisovsky, Litres
 
MBLT16: Vincent Wu, Alibaba Mobile
MBLT16: Vincent Wu, Alibaba MobileMBLT16: Vincent Wu, Alibaba Mobile
MBLT16: Vincent Wu, Alibaba Mobile
 
MBLT16: Dmitriy Geranin, Afisha Restorany
MBLT16: Dmitriy Geranin, Afisha RestoranyMBLT16: Dmitriy Geranin, Afisha Restorany
MBLT16: Dmitriy Geranin, Afisha Restorany
 
MBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetricaMBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetrica
 
MBLTDev15: Brigit Lyons, Soundcloud
MBLTDev15: Brigit Lyons, SoundcloudMBLTDev15: Brigit Lyons, Soundcloud
MBLTDev15: Brigit Lyons, Soundcloud
 
MBLTDev15: Alexander Orlov, Postforpost
MBLTDev15: Alexander Orlov, PostforpostMBLTDev15: Alexander Orlov, Postforpost
MBLTDev15: Alexander Orlov, Postforpost
 
MBLT16: Andrey Maslak, Aviasales
MBLT16: Andrey Maslak, AviasalesMBLT16: Andrey Maslak, Aviasales
MBLT16: Andrey Maslak, Aviasales
 
Rx java
Rx javaRx java
Rx java
 
Rx Java architecture
Rx Java architectureRx Java architecture
Rx Java architecture
 
MBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, PureMBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, Pure
 

Similaire à MBLTDev15: Egor Tolstoy, Rambler&Co

Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
Guy Nir
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
Ganesh Gembali
 

Similaire à MBLTDev15: Egor Tolstoy, Rambler&Co (20)

Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lecture
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
Rambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View ControllerRambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View Controller
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play Framework
 
Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
 
Do iOS Presentation - Mobile app architectures
Do iOS Presentation - Mobile app architecturesDo iOS Presentation - Mobile app architectures
Do iOS Presentation - Mobile app architectures
 
ITT 2014 - Peter Steinberger - Architecting Modular Codebases
ITT 2014 - Peter Steinberger - Architecting Modular CodebasesITT 2014 - Peter Steinberger - Architecting Modular Codebases
ITT 2014 - Peter Steinberger - Architecting Modular Codebases
 
iOS
iOSiOS
iOS
 
Spring boot
Spring boot Spring boot
Spring boot
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
Play! Framework for JavaEE Developers
Play! Framework for JavaEE DevelopersPlay! Framework for JavaEE Developers
Play! Framework for JavaEE Developers
 
Sexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroidsSexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroids
 
Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and Threads
 
JDBC Tutorial
JDBC TutorialJDBC Tutorial
JDBC Tutorial
 
React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applications
 
Dmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleanerDmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleaner
 
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"
 
React native by example by Vadim Ruban
React native by example by Vadim RubanReact native by example by Vadim Ruban
React native by example by Vadim Ruban
 
Conductor vs Fragments
Conductor vs FragmentsConductor vs Fragments
Conductor vs Fragments
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 

Plus de e-Legion

Plus de e-Legion (15)

MBLTDev15: Alexander Dimchenko, DIT
MBLTDev15: Alexander Dimchenko, DITMBLTDev15: Alexander Dimchenko, DIT
MBLTDev15: Alexander Dimchenko, DIT
 
MBLTDev: Alexander Dimchenko, Bright Box
MBLTDev: Alexander Dimchenko, Bright Box MBLTDev: Alexander Dimchenko, Bright Box
MBLTDev: Alexander Dimchenko, Bright Box
 
MBLTDev15: Konstantin Goldshtein, Microsoft
MBLTDev15: Konstantin Goldshtein, MicrosoftMBLTDev15: Konstantin Goldshtein, Microsoft
MBLTDev15: Konstantin Goldshtein, Microsoft
 
MBLTDev15: Anna Mikhina, Maxim Evdokimov, Tinkoff Bank
MBLTDev15: Anna Mikhina, Maxim Evdokimov, Tinkoff Bank MBLTDev15: Anna Mikhina, Maxim Evdokimov, Tinkoff Bank
MBLTDev15: Anna Mikhina, Maxim Evdokimov, Tinkoff Bank
 
MBLTDev15: Ivan Kozlov, Aviasales
MBLTDev15: Ivan Kozlov, AviasalesMBLTDev15: Ivan Kozlov, Aviasales
MBLTDev15: Ivan Kozlov, Aviasales
 
MBLTDev15: Ilya Krasilshchik, Meduza.io
MBLTDev15: Ilya Krasilshchik, Meduza.ioMBLTDev15: Ilya Krasilshchik, Meduza.io
MBLTDev15: Ilya Krasilshchik, Meduza.io
 
MBLTDev15: Svetlana Sonina, STS Media
MBLTDev15: Svetlana Sonina, STS MediaMBLTDev15: Svetlana Sonina, STS Media
MBLTDev15: Svetlana Sonina, STS Media
 
MBLTDev15: Marius Racwitz, Realm
MBLTDev15: Marius Racwitz, RealmMBLTDev15: Marius Racwitz, Realm
MBLTDev15: Marius Racwitz, Realm
 
MBLTDev15: Denis Legezo, Kaspersky Lab
MBLTDev15: Denis Legezo, Kaspersky LabMBLTDev15: Denis Legezo, Kaspersky Lab
MBLTDev15: Denis Legezo, Kaspersky Lab
 
MBLTDev15: Kyle Fuller, Apairy
MBLTDev15: Kyle Fuller, ApairyMBLTDev15: Kyle Fuller, Apairy
MBLTDev15: Kyle Fuller, Apairy
 
MBLTDev15: Sergey Semenov, Trucker Path
MBLTDev15: Sergey Semenov, Trucker Path MBLTDev15: Sergey Semenov, Trucker Path
MBLTDev15: Sergey Semenov, Trucker Path
 
MBLTDev: Phillip Connaughton, RunKepper
MBLTDev: Phillip Connaughton, RunKepper MBLTDev: Phillip Connaughton, RunKepper
MBLTDev: Phillip Connaughton, RunKepper
 
MBLT15: Alexey Chikov, Kaspersky Lab
MBLT15: Alexey Chikov, Kaspersky LabMBLT15: Alexey Chikov, Kaspersky Lab
MBLT15: Alexey Chikov, Kaspersky Lab
 
MBLT15: Yakov Zubarev, Parallels
MBLT15: Yakov Zubarev, ParallelsMBLT15: Yakov Zubarev, Parallels
MBLT15: Yakov Zubarev, Parallels
 
MBLT15: Dmitriy Navosha, Sports.ru
MBLT15: Dmitriy Navosha, Sports.ru MBLT15: Dmitriy Navosha, Sports.ru
MBLT15: Dmitriy Navosha, Sports.ru
 

Dernier

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Cara Menggugurkan Kandungan 087776558899
 

Dernier (8)

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Thane 💋 Call Girls 7738631006 💋 Call Girls in Thane Escort service book now. ...
Thane 💋 Call Girls 7738631006 💋 Call Girls in Thane Escort service book now. ...Thane 💋 Call Girls 7738631006 💋 Call Girls in Thane Escort service book now. ...
Thane 💋 Call Girls 7738631006 💋 Call Girls in Thane Escort service book now. ...
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdf
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 

MBLTDev15: Egor Tolstoy, Rambler&Co