34
Подходы и технологии, используемые в разработке iOS-клиента Viber Кирилл Лашкевич Yandex Mobile Camp

Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

  • Upload
    yandex

  • View
    631

  • Download
    0

Embed Size (px)

DESCRIPTION

Рассказ об основных принципах, которых придерживается Viber в длительной разработке приложения с большой кодовой базой — если разработкой занимается распределённая команда. Мы обсудим используемые технологии, библиотеки, работу с кодом и многое другое.

Citation preview

Page 1: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Подходы и технологии, используемые в разработке

iOS-клиента ViberКирилл Лашкевич

Yandex Mobile Camp

Page 2: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Viber• >20M зарегистрированных пользоватей в России

• >400M по миру

• 100M online

• 220 сотрудников в 9 странах

• 4.5 года проекту

Page 3: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Статистика iOS проекта• 206K SLOC под iOS

• +50K SLOC сторонних библиотек под iOS

• +140K SLOC общего кода Viber

• +300K SLOC медиа-движка WebRTC

• +120K SLOC аудио/видео кодеков

• ≈800K строк кода

Page 4: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Agenda

1. Управление исходным кодом

2. Сборка проекта

3. Несколько примеров кода

Page 5: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Работа с репозиториями

• 1 репозиторий для всего проекта

• Много репозиториев

• 12 git origins, >100 с форками

Page 6: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

1 репозиторий

• Просто для начального этапа

• Поддерживается всеми инструментами

• Разграничения доступа

• Ветки

• Совместная работа

• Размер

• Скорость работы

+ -

Page 7: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

CocoaPods

• База готовых pods для сторонних библиотек

• Возможность управления приватными репозиториями

• Только для проектов под iOS,для остальных платформ проблема остается

• Практически не используем сторонние библиотеки

+ -

Page 8: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Сторонние библиотеки• Только в исходных кодах

• 7 раз подумать стоит ли брать сторонний код либо написать самим

• Быть готовым исправлять баги, адаптировать под новые версии ОС и компилятора быстрее авторов

• Приватный форк в github (git-svn для svn)

Page 9: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Git submodules• Ссылка на конкретную ревизию внешнего репозитория в каталоге основного

• Что бы получить весь код для сборки: git clone … && git submodule update --init —update

• Подходит как для внутренних библиотек так и для стороннего кода

• Работает одинаково на всех платформах

Page 10: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Git subtree• Способ добавить внешний репозиторий, либо его часть в основной, с сохранением возможности обновления в обе стороны

• Подходит для случаев, когда внешний репозиторий активно не взаимодействует с upstream

• Проще в использовании, код из внешнего репозитория выглядит как часть основного

Page 11: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

LibViber

Core

Media����������� ������������������  Engine

Codec Codec

Viber����������� ������������������  iOS

DSP

RAC Mantle

Page 12: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Сборка проекта

• make, cmake, qmake, scons

• Xcode, xcodebuild:

• Workspace

• Project

• Target

Page 13: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

1 Проект 1 Target

Page 14: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

1 Проект N Targets

Page 15: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

1 Проект N подпроектов

Page 16: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

1 Workspace N проектов

Page 17: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

+ external build

+ external build

Page 18: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич
Page 19: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Недостатки Xcode• Переодически что-нибудь ломают (а иногда и чинят)

• Headermap который сложно отключить

• Сборка отдельных файлов под разные платформы

• Не все документировано

• Скорость сборки не максимальная

Page 20: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Немного кода

• Swift

• Main thread profiler

• ReactiveCocoa

• Mantle

Page 21: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Swift• Да, мы используем Swift!

• 15 строчке скрипта для генерации иконки с номером версии

• Для кода приложения не раньше Xcode 6.1

Page 22: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Main thread profiler• UI обрабатывается в главном потоке, он не должен блокироваться

• Каждые 0.1с запускать на выполнение блок в главном потоке

• Если выполнение блока задерживается — уведомление в UI и backtrace в лог

Page 23: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

while (!NSThread.currentThread.isCancelled) { static bool pingTaskIsRunning; pingTaskIsRunning = YES; dispatch_async(dispatch_get_main_queue(), ^{ pingTaskIsRunning = NO; dispatch_semaphore_signal(semaphore); }); [NSThread sleepForTimeInterval:0.4]; if (pingTaskIsRunning) { // Уведомление о блокировке } dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); [NSThread sleepForTimeInterval:0.1]; }

Page 24: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

ReactiveCocoa• Удобная замена KVO

• Функциональное программирование в ObjC

• Меньше состояния, меньше багов

• Возрастает порог входа

• Много блоков в коде

Page 25: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

RAC(self, label.text) = RACObserve(self, name);

http://www.raywenderlich.com/62796/reactivecocoa-tutorial-pt1

Page 26: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

[[[[[[[self requestAccessToTwitterSignal] then:^RACSignal *{ @strongify(self) return self.searchText.rac_textSignal; }] filter:^BOOL(NSString *text) { @strongify(self) return [self isValidSearchText:text]; }] throttle:0.5] flattenMap:^RACStream *(NSString *text) { @strongify(self) return [self signalForSearchWithText:text]; }] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDictionary *jsonSearchResult) { NSArray *tweets = [jsonSearchResult[@"statuses"] .rac_sequence map:^(id tweet) { return [RWTweet tweetWithStatus:tweet]; }].array; [self.resultsViewController displayTweets:tweets]; } error:^(NSError *error) { NSLog(@"An error occurred: %@", error); }];

Page 27: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

self и циклические ссылки• self захватывается как сильная ссылка в блоке

• Доступ к ivar происходит через неявный self:^ { NSLog(@"%@", _ivar); }; ^ { NSLog(@"%@", self->_ivar); };

• Циклическая ссылка получается при сохранении блока в атрибуте объекта

Page 28: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

@weakself• До вызова блока объект, на который указывает self, хранится по слабой ссылке, а во время вызова блока — по сильной

• self называется self

• Проверяется доступ к ivar внутри блоков [RACObserve(self, pttState) subscribeNext:@weakselfnotnil(^(NSNumber *state)) { self.isRecordingPTT = !!state.intValue;} @weakselfend];

https://gist.github.com/notorca/9192459

Page 29: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

Mantle• Слой модели данных для приложения

• Замена NSDictionary

• Замена классов состоящих только из набора @property

• Автоматом добавляет основные методы: initWithDictionary:, description, debugDescription, initWithCoder:, encodeWithCoder:, copyWithZone:, isEqual:, hash:

Page 30: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

NSDictinary *httpRequestSetup = @{ @"URL" : [NSURL URLWithString:@"http...."], @"HTTPMethod" : @"GET", @"HTTPHeaders" : @{}, @"HTTPBody" : [NSData dataWithString:@""], @"resumable" : @(YES), @"streamBoundary" : @"---123---" @"streamBody" : [NSData dataWithString:@""] };

• Нет проверки типов

• Только тонны тестов спасут когда проект разрастется

Page 31: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

@interface VTMHTTPRequestSetup "@property (nonatomic) NSURL *URL; @property (nonatomic) NSString *HTTPMethod; @property (nonatomic) NSDictionary *HTTPHeaders; @property (nonatomic) NSData *HTTPBody; @property (nonatomic) BOOL resumable; @property (nonatomic) NSString *streamBoundary; @property (nonatomic) NSData *streamBody; "// initWithDictionary:, copyWithZone:, // description, debugDescription, // initWithCoder:, encodeWithCoder:, // isEqual:, hash: "@end

Page 32: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

@interface VTMHTTPRequestSetup : MTLModel "@property (nonatomic) NSURL *URL; @property (nonatomic) NSString *HTTPMethod; @property (nonatomic) NSDictionary *HTTPHeaders; @property (nonatomic) NSData *HTTPBody; @property (nonatomic) BOOL resumable; @property (nonatomic) NSString *streamBoundary; @property (nonatomic) NSData *streamBody; "@end

• Конвертация из/в JSON

• Конвертация из/в NSManagedObject

Page 33: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

• Вся работа с CoreData в фоновом потоке

• NSManagedObjects -> MTLModel

• FetchResultController для отслеживания изменений +логика получения конкретных обновившихся полей во время merge NSManagedContext

• ReactiveCocoa для связи всего, пересылки из потока в поток и throtlling

Page 34: Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лашкевич

@notorca