SlideShare a Scribd company logo
1 of 64
Download to read offline
Создание модульных приложений
на примере
“Рамблер.Кассы”
О чем?
• Введение в историю “Рамблер.Касса”
• Что используем
• Пример
О чем?
• Введение в историю “Рамблер.Касса”
• Что используем
• Пример
О чем?
• Введение в историю “Рамблер.Касса”
• Что используем
• Пример
Модуль — функционально законченный фрагмент программы,
оформленный в виде отдельного файла с исходным кодом.
Глоссарий
Модульность — это свойство системы, связанное с возможностью
ее декомпозиции на ряд внутренне связанных между собой
модулей
Глоссарий
Немного истории
• Приложение, отображающее информацию по событию:
- кино
- спектакли
- спорт
• Возможность купить билеты на эти события без наценки
• iPhone и iPad версии
Что же такое “Рамблер.Касса”?
Немного истории
• Приложение, отображающее информацию по событию:
- кино
- спектакли
- спорт
• Возможность купить билеты на эти события без наценки
• iPhone и iPad версии
Что же такое “Рамблер.Касса”?
Немного истории
• Приложение, отображающее информацию по событию:
- кино
- спектакли
- спорт
• Возможность купить билеты на эти события без наценки
• iPhone и iPad версии
Что же такое “Рамблер.Касса”?
Немного истории
• Приложение, отображающее информацию по событию:
- кино
- спектакли
- спорт
• Возможность купить билеты на эти события без наценки
• iPhone и iPad версии
Что же такое “Рамблер.Касса”?
Немного истории
Что же такое “Рамблер.Касса”?
Немного истории
Что же такое “Рамблер.Касса”?
Немного истории
• Проект развивается
• Появляется первая “брендированная версия”
Немного истории
Что же такое “брендированная” версия?
• Отдельное приложение, существующее обособленно от основной
версии
• Имеет свои особенности:
- своя цветовая схема, логотипы и т.д.
- отличный от основной кассы функционал
Немного истории
Что же такое “брендированная” версия?
Немного истории
Что же такое “брендированная” версия?
Немного истории
• Общий функционал
• Отличный функционал
• Количество версий только растет
Проблема
Проблема
Проблема
Расписание
Поддержка Билеты
Карта
Спорт
Кино Кино
Кино
Проблема
Расписание
Билеты
Карта
Расписание
Поддержка
Билеты
Как это было?
• Один проект для всех версий
• Множество таргетов
• Ветвления через “if” по define макросам
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#ifdef BOLSHOI
switch (section) {
case 2:
return 2;
case 3:
return 2;
default:
return 0;
}
#else
switch (section) {
case 0:
return 2;
case 1:
return 1;
default:
return 0;
}
#endif
}
Как это было?
- (instancetype)init
{
self = [super init];
NSString *bundleIdentifier = [[NSBundle mainBundle] infoDictionary][@"CFBundleIdentifier"];
if ([bundleIdentifier rangeOfString:@"cinemapark"].location != NSNotFound) {
// CINEMA PARK
_tintColor = [UIColor colorWithRed:31.f / 255.f green:110.f / 255.f blue:180.f / 255.f alpha:1.f];
_navigationBarTintColor = [UIColor colorWithRed:4.f/255.f green:110.f/255.f blue:180.f/255.f alpha:1.f];
_navigationBarTitleColor = [UIColor whiteColor];
_shouldShowTheaters = NO;
_onlyOneCinema = NO;
#if !defined(AF_APP_EXTENSIONS)
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
#endif
if ([bundleIdentifier hasSuffix:@".dev"]) {
_widgetKey = @"foo";
} else {
_widgetKey = @"foo";
}
} else if ([bundleIdentifier rangeOfString:@"Bolshoi"].location != NSNotFound) {
// Bolshoi Rostov
_tintColor = [UIColor kassaBolshoiMainColor];
_navigationBarTintColor = [UIColor kassaBolshoiMainColor];
_navigationBarTitleColor = [UIColor kassaBolshoiActiveTabsColor];
_selectedBarItemColor = [UIColor kassaBolshoiActiveTabsColor];
_unselectedBarItemColor = [UIColor kassaBolshoiSecondaryColor];
_barTextColor = [UIColor kassaBolshoiActiveTabsColor];
_shouldShowTheaters = NO;
_onlyOneCinema = YES;
if ([bundleIdentifier hasSuffix:@".dev"]) {
_widgetKey = @"foo";
} else {
_widgetKey = @"foo";
}
}else {
// KASSA APP
_tintColor = [UIColor colorWithRed:255.f / 255.f green:133.f / 255.f blue:47.f / 255.f alpha:1.f];
_navigationBarTintColor = nil;
_navigationBarTitleColor = nil;
_selectedBarItemColor = _tintColor;
_unselectedBarItemColor = nil;
_barTextColor = nil;
_shouldShowTheaters = YES;
_onlyOneCinema = NO;
if ([bundleIdentifier hasSuffix:@".dev"]) {
_widgetKey = @"foo";
} else {
_widgetKey = @"foo";
}
}
return self;
}
if ([bundleIdentifier rangeOfString:@"cinemapark"].location !=
NSNotFound) {
// CINEMA PARK
_tintColor = [UIColor colorWithRed:31.f / 255.f green:110.f /
255.f blue:180.f / 255.f alpha:1.f];
Как это было?
Как это было?
Решение
• Модуль - экран приложения, выполняющий свою
функцию
• Саб-модуль - отдельная функциональность
конкретного модуля, отвечающая за единственную
обязанность
Решение
• Разбить приложение на модули
• Разбить каждые модули на саб-модули
• Подключать нужные модули, а с ними и
нужные саб-модули для конкретных таргетов
Решение
Решение
Модуль “кинотеатры”
• Получает через API список
кинотеатров
• Отображает этот список
• Осуществляет навигацию на другие
модули
Решение
Модуль “кинотеатры”
view presenter
router
interactor
entity
entity
entity
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
Nimbus
Решение
Nimbus
Cell Object
Решение
Nimbus
Cell Object
Сконфигурированная
ячейка
Решение
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
TYPHOON
Решение
Решение
@interface RKCinemasDefaultConfiguratorAssembly : TyphoonAssembly
@property (nonatomic, strong) RKSharedAssembly *sharedAssembly;
- (id<RKCinemasViewProtocol, RKBaseListViewOutConfiguratorProtocol,
RKCinemasDataProviderDelegate>)cinemasViewController;
- (id<RKCinemasPresenterViewOutputProtocol,
RKCinemasPresenterInteractorOutputProtocol>)cinemaPresenter;
- (id<RKCinemasInteractorProtocol>)cinemasInteractor;
- (id<RKCinemasRouterProtocol>)cinemasRouter;
- (id<RKCinemasServiceProtocol>)cinemasService;
- (id<RKBaseListViewConfiguratorProtocol>)cinemaConfigurator;
- (id<RKCinemasDataSourceProviderProtocol>)cinemasDataSourceProvider;
- (id<RKCinemasDataSourceConverterProtocol>)cinemasDataConverter;
@end
Решение
Активация фабрики
Решение
Решение
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
RKCinemasDataConverter
Решение
Модуль “кинотеатры”
view presenter
router
interactor entityservice
data source
provider
data source
converter
ui
configurator
RKCinemasDataConverter
RKCinemasGiantDataConverter
Решение
Модуль “кинотеатры”
Решение
@implementation RKCinemasDataConverter
- (NSArray *)convertArrayOfListCinemasToPlaceCellObjects:(NSArray *)list
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (RKList *listObject in list) {
[array addObject:listObject.title];
NSArray *objects = [self convertListOfCinemasToCellObjects:listObject.objects];
[array addObjectsFromArray:objects];
}
return [array copy];
}
- (NSArray *)convertListOfCinemasToCellObjects:(NSArray *)list
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (RKPlace *place in list) {
[array addObject:[RKListPlaceCellObject objectWithPlace:place]];
}
return [array copy];
}
@end
Решение
@implementation RKCinemasGiantDataConverter
- (NSArray *)convertListOfCinemasToCellObjects:(NSArray *)list
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (RKPlace *place in list) {
id<RKCinemaDataProtocol>cinemaInfo = [self.dataProvider cinemaInfoById:place.identifier];
NSString *backgroundImageName = [cinemaInfo backgroundImageName];
NSString *logoImageName = [cinemaInfo logoImageName];
[array addObject:[RKPhotoCinemaCellObject objectWithPlace:place
backgroundImageName:backgroundImageName
logoImageName:logoImageName]];
}
return [array copy];
}
- (NSArray *)convertArrayOfListCinemasToPlaceCellObjects:(NSArray *)list
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (RKList *listObject in list) {
[array addObject:listObject.title];
NSArray *objects = [self convertListOfCinemasToCellObjects:listObject.objects];
[array addObjectsFromArray:objects];
}
return [array copy];
}
@end
Решение
#import "RKCinemasDefaultConfiguratorAssembly.h"
@protocol RKCinemasDataProviderProtocol;
@interface RKCinemasGiantConfiguratorAssembly : RKCinemasDefaultConfiguratorAssembly
- (id<RKCinemasDataSourceConverterProtocol>)cinemasDataConverter;
- (id<RKCinemasDataProviderProtocol>)giantCinemasDataProvider;
@end
Решение
- (id<RKCinemasDataSourceConverterProtocol>)cinemasDataConverter
{
return [TyphoonDefinition withClass:[RKCinemasGiantDataConverter class]
configuration:^(TyphoonDefinition *definition)
{
[definition injectProperty:@selector(dataProvider)
with:[self giantCinemasDataProvider]];
}];
}
- (id<RKCinemasDataSourceConverterProtocol>)cinemasDataConverter
{
return [TyphoonDefinition withClass:[RKCinemasDataConverter class]];
}
Definition для основной версии
Definition для “брединрованной” версии
Решение
rambler-kassa.plist
giant.plist
Решение
Заключение
• Код чище
• Уникальный функционал затрагивает только
нужные таргеты
• Общий код для всех таргетов
• Тестирование саб-модулей
Заключение
• Код чище
• Уникальный функционал затрагивает только
нужные таргеты
• Общий код для всех таргетов
• Тестирование саб-модулей
Заключение
• Код чище
• Уникальный функционал затрагивает только
нужные таргеты
• Общий код для всех таргетов
• Тестирование саб-модулей
Заключение
• Код чище
• Уникальный функционал затрагивает только
нужные таргеты
• Общий код для всех таргетов
• Тестирование саб-модулей
Заключение
• VIPER
• NIMBUS
• TYPHOON
Заключение
• COCOAPOD (?)
Ссылки
http://typhoonframework.org/
Статья с общими принципами
https://www.objc.io/issues/13-architecture/viper/
Официальный сайт проекта “Тyphoon”
http://habrahabr.ru/company/rambler-co/blog/264683/
https://www.youtube.com/watch?v=LO59z3fjc9k
TYPHOON
Цикл статей от Егора Толстова
Выступление на rambler.ios #3
VIPER
https://medium.com/brigade-engineering/brigades-experience-using-an-mvc-
alternative-36ef1601a41f
Вводная статья
NIMBUS
https://github.com/jverkoey/nimbus Исходники и ссылка на wiki проекта
http://www.slideshare.net/Rambler-iOS/nimbus-models Презентация с rambler.ios #1 от Стаса Цыганова

More Related Content

What's hot

«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​FDConf
 
Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...Ontico
 
Angular 2: Всех переиграл
Angular 2: Всех переигралAngular 2: Всех переиграл
Angular 2: Всех переигралEugene Zharkov
 
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)7bits
 
Angular 2 vs Angular 1
Angular 2 vs Angular 1Angular 2 vs Angular 1
Angular 2 vs Angular 1GDG Odessa
 
«Изоморфные js приложения с использованием catberry.js», Денис Речкунов
«Изоморфные js приложения с использованием catberry.js», Денис Речкунов«Изоморфные js приложения с использованием catberry.js», Денис Речкунов
«Изоморфные js приложения с использованием catberry.js», Денис РечкуновDevDay
 
#MBLTdev: Опыт использования MVVM в реальных проектах
#MBLTdev: Опыт использования MVVM в реальных проектах#MBLTdev: Опыт использования MVVM в реальных проектах
#MBLTdev: Опыт использования MVVM в реальных проектахe-Legion
 
Ember.js - Назад в Будущее - Odessa JS 2014
Ember.js - Назад в Будущее - Odessa JS 2014Ember.js - Назад в Будущее - Odessa JS 2014
Ember.js - Назад в Будущее - Odessa JS 2014Andrey Listochkin
 
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"Fwdays
 
#13 "Управление состоянием в Redux" Роман Сальников
#13 "Управление состоянием в Redux" Роман Сальников#13 "Управление состоянием в Redux" Роман Сальников
#13 "Управление состоянием в Redux" Роман СальниковJSib
 
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBenchHappyDev
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныCodeFest
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»FDConf
 
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSКурсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSГлеб Тарасов
 
антон веснин Rails Application Servers
антон веснин Rails Application Serversантон веснин Rails Application Servers
антон веснин Rails Application Serversrit2010
 
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Yulia Tsisyk
 
Java осень 2012 лекция 5
Java осень 2012 лекция 5Java осень 2012 лекция 5
Java осень 2012 лекция 5Technopark
 
Web весна 2012 лекция 7
Web весна 2012 лекция 7Web весна 2012 лекция 7
Web весна 2012 лекция 7Technopark
 
Владимир Кузнецов — Прототип сайта: разработка и развёртывание
Владимир Кузнецов — Прототип сайта: разработка и развёртываниеВладимир Кузнецов — Прототип сайта: разработка и развёртывание
Владимир Кузнецов — Прототип сайта: разработка и развёртываниеYandex
 

What's hot (20)

«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​«Как перестать отлаживать асинхронные вызовы и начать жить»​
«Как перестать отлаживать асинхронные вызовы и начать жить»​
 
Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...Пользователь точно оценит! Повышение производительности мобильных приложений ...
Пользователь точно оценит! Повышение производительности мобильных приложений ...
 
Angular 2: Всех переиграл
Angular 2: Всех переигралAngular 2: Всех переиграл
Angular 2: Всех переиграл
 
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
 
Angular 2 vs Angular 1
Angular 2 vs Angular 1Angular 2 vs Angular 1
Angular 2 vs Angular 1
 
«Изоморфные js приложения с использованием catberry.js», Денис Речкунов
«Изоморфные js приложения с использованием catberry.js», Денис Речкунов«Изоморфные js приложения с использованием catberry.js», Денис Речкунов
«Изоморфные js приложения с использованием catberry.js», Денис Речкунов
 
#MBLTdev: Опыт использования MVVM в реальных проектах
#MBLTdev: Опыт использования MVVM в реальных проектах#MBLTdev: Опыт использования MVVM в реальных проектах
#MBLTdev: Опыт использования MVVM в реальных проектах
 
Ember.js - Назад в Будущее - Odessa JS 2014
Ember.js - Назад в Будущее - Odessa JS 2014Ember.js - Назад в Будущее - Odessa JS 2014
Ember.js - Назад в Будущее - Odessa JS 2014
 
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"
Анджей Гужовский "Riot.JS, или как приготовить современные Web Components"
 
#13 "Управление состоянием в Redux" Роман Сальников
#13 "Управление состоянием в Redux" Роман Сальников#13 "Управление состоянием в Redux" Роман Сальников
#13 "Управление состоянием в Redux" Роман Сальников
 
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
2015-12-05 Вадим Литвинов - Нагрузочное тестирование с MZBench
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
 
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSКурсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
 
антон веснин Rails Application Servers
антон веснин Rails Application Serversантон веснин Rails Application Servers
антон веснин Rails Application Servers
 
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
 
Java осень 2012 лекция 5
Java осень 2012 лекция 5Java осень 2012 лекция 5
Java осень 2012 лекция 5
 
Web весна 2012 лекция 7
Web весна 2012 лекция 7Web весна 2012 лекция 7
Web весна 2012 лекция 7
 
RequireJS і Magento 2
RequireJS і Magento 2RequireJS і Magento 2
RequireJS і Magento 2
 
Владимир Кузнецов — Прототип сайта: разработка и развёртывание
Владимир Кузнецов — Прототип сайта: разработка и развёртываниеВладимир Кузнецов — Прототип сайта: разработка и развёртывание
Владимир Кузнецов — Прототип сайта: разработка и развёртывание
 

Viewers also liked

Магия AsyncDisplayKit
Магия AsyncDisplayKitМагия AsyncDisplayKit
Магия AsyncDisplayKitAnjLab
 
Rambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRAMBLER&Co
 
Роман Ермолов - Отладка приложений под iOS
Роман Ермолов - Отладка приложений под iOSРоман Ермолов - Отладка приложений под iOS
Роман Ермолов - Отладка приложений под iOSAlexander Zimin
 
iOS View Coordinators
iOS View CoordinatorsiOS View Coordinators
iOS View Coordinatorssgleadow
 
Александр Зимин (Alexander Zimin) - Protocol-Oriented Programming
Александр Зимин (Alexander Zimin) - Protocol-Oriented ProgrammingАлександр Зимин (Alexander Zimin) - Protocol-Oriented Programming
Александр Зимин (Alexander Zimin) - Protocol-Oriented ProgrammingAlexander Zimin
 
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRAMBLER&Co
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRAMBLER&Co
 
RDSDataSource: OCLint
RDSDataSource: OCLintRDSDataSource: OCLint
RDSDataSource: OCLintRAMBLER&Co
 
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101RAMBLER&Co
 
Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRAMBLER&Co
 
RDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRAMBLER&Co
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: PromisesRAMBLER&Co
 
Rambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View ControllerRambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View ControllerRAMBLER&Co
 
Rambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRAMBLER&Co
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRAMBLER&Co
 
RDSDataSource: App Thinning
RDSDataSource: App ThinningRDSDataSource: App Thinning
RDSDataSource: App ThinningRAMBLER&Co
 
Rambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRAMBLER&Co
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRAMBLER&Co
 
RDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRAMBLER&Co
 
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...Alexander Zimin
 

Viewers also liked (20)

Магия AsyncDisplayKit
Магия AsyncDisplayKitМагия AsyncDisplayKit
Магия AsyncDisplayKit
 
Rambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPER
 
Роман Ермолов - Отладка приложений под iOS
Роман Ермолов - Отладка приложений под iOSРоман Ермолов - Отладка приложений под iOS
Роман Ермолов - Отладка приложений под iOS
 
iOS View Coordinators
iOS View CoordinatorsiOS View Coordinators
iOS View Coordinators
 
Александр Зимин (Alexander Zimin) - Protocol-Oriented Programming
Александр Зимин (Alexander Zimin) - Protocol-Oriented ProgrammingАлександр Зимин (Alexander Zimin) - Protocol-Oriented Programming
Александр Зимин (Alexander Zimin) - Protocol-Oriented Programming
 
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по Dip
 
RDSDataSource: OCLint
RDSDataSource: OCLintRDSDataSource: OCLint
RDSDataSource: OCLint
 
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101
 
Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеров
 
RDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDK
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
 
Rambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View ControllerRambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #5: Разбираем Massive View Controller
 
Rambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxproj
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabase
 
RDSDataSource: App Thinning
RDSDataSource: App ThinningRDSDataSource: App Thinning
RDSDataSource: App Thinning
 
Rambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейса
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на Swift
 
RDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperienced
 
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...
Дмитрий Обухов (Dmitry Obukhov) - Growth Hacking для настольных и мобильных п...
 

Similar to Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы

Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorDevGAMM Conference
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?buranLcme
 
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)AvitoTech
 
Frontendlab: Фреймворк Duranda js - Виктор Сотов
Frontendlab: Фреймворк Duranda js  - Виктор СотовFrontendlab: Фреймворк Duranda js  - Виктор Сотов
Frontendlab: Фреймворк Duranda js - Виктор СотовGeeksLab Odessa
 
Конструктор / Денис Паясь (Яндекс)
Конструктор / Денис Паясь (Яндекс)Конструктор / Денис Паясь (Яндекс)
Конструктор / Денис Паясь (Яндекс)Ontico
 
Cовременный станок верстальщика
Cовременный станок верстальщикаCовременный станок верстальщика
Cовременный станок верстальщикаmcslayer
 
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Yandex
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Ontico
 
Доставка данных в реальном времени.
Доставка данных в реальном времени. Доставка данных в реальном времени.
Доставка данных в реальном времени. beshkenadze
 
И снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоИ снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоStanfy
 
Денис Паясь
Денис ПаясьДенис Паясь
Денис ПаясьCodeFest
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософияPaul Klimov
 
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow Vadim Nesterov
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETDev2Dev
 

Similar to Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы (20)

Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
 
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
 
Abf
AbfAbf
Abf
 
Frontendlab: Фреймворк Duranda js - Виктор Сотов
Frontendlab: Фреймворк Duranda js  - Виктор СотовFrontendlab: Фреймворк Duranda js  - Виктор Сотов
Frontendlab: Фреймворк Duranda js - Виктор Сотов
 
Конструктор / Денис Паясь (Яндекс)
Конструктор / Денис Паясь (Яндекс)Конструктор / Денис Паясь (Яндекс)
Конструктор / Денис Паясь (Яндекс)
 
Cовременный станок верстальщика
Cовременный станок верстальщикаCовременный станок верстальщика
Cовременный станок верстальщика
 
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
 
Доставка данных в реальном времени.
Доставка данных в реальном времени. Доставка данных в реальном времени.
Доставка данных в реальном времени.
 
И снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоИ снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел Тайкало
 
Крыша 2.0
Крыша 2.0Крыша 2.0
Крыша 2.0
 
Денис Паясь
Денис ПаясьДенис Паясь
Денис Паясь
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософия
 
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
 

More from RAMBLER&Co

RDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRAMBLER&Co
 
Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!RAMBLER&Co
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?RAMBLER&Co
 
Rambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRAMBLER&Co
 
RDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRAMBLER&Co
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRAMBLER&Co
 
Rambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRAMBLER&Co
 
Rambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRAMBLER&Co
 
RDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRAMBLER&Co
 
RDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRAMBLER&Co
 
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRAMBLER&Co
 
Rambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRAMBLER&Co
 
Rambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRAMBLER&Co
 

More from RAMBLER&Co (13)

RDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRDSDataSource: Основы LLVM
RDSDataSource: Основы LLVM
 
Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
 
Rambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memory
 
RDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграмм
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тесты
 
Rambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектура
 
Rambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCore
 
RDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOS
 
RDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwift
 
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуй
 
Rambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination Demystified
 
Rambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPER
 

Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы