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

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

Embed Size (px)

Citation preview

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

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

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

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

Кратко о Viber iOS• 6 лет разработки

• ~1M SLOC

• Команда iOS: 20 человек в 4 странах и 5 городах

• 6 языков программирования

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

Археология программирования

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

6 языков

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

6 языков• ASM

• C

• C++

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

6 языков• ASM

• C

• C++

• ObjC

• ObjC++

• Swift

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

Используем фреймворки и инструменты на пределе

возможностей• CoreData

• Xcode

• clang

• Git

• Hardware

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

🎤

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

🎤 Encode

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

🎤 Encode Packetize

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

🎤 Encode Packetize Send

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

🎤 Encode Packetize Send

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

🎤 Encode Packetize Send

NAT�Traversal

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

🎤 Encode Packetize Send

Receive

NAT�Traversal

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

🎤 Encode Packetize Send

ReceiveDepacketize

NAT�Traversal

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

🎤 Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

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

🔊

🎤 Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

sync

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

sync

Capability�Negotiation

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

sync

Capability�NegotiationAEC

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

sync

Capability�NegotiationAEC

BitrateControl

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

🔊

📺

🎥🎤 Encode Packetize Send

ReceiveDepacketizeDecode

Encode Packetize Send

ReceiveDepacketizeDecode

NAT�Traversal

sync sync

sync

Capability�NegotiationAEC

BitrateControl

FEC

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

Git

• ~120 комиков в неделю

• 32k всего

• 10k мержей

• неизвестное количество веток

• 15 прилинкованных внешних origins

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

Управление внешними зависимостями

• CocoaPods, Carthage • git submodules • git subtrees

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

Управление внешними зависимостями

• CocoaPods, Carthage • git submodules • git subtrees

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

Git submodulesgit pull … && git submodule update --recursive

git status, --git-dir, --work-tree, git archive игнорируют сабмодули

git worktree игнорируют сабмодули

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

Кроссплатформенный подход

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

LibViber

Core

Media�Engine

Codec Codec

Viber�iOS

DSP

RAC Mantle

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

Сборка

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

Сборка

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

Сборка

• cmake, scons, GYP, qmake

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

Сборка

• cmake, scons, GYP, qmake

• Xcode, xcodebuild

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

Сборка

• cmake, scons, GYP, qmake

• Xcode, xcodebuild

• Workspace, project, target

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

Сборка

• cmake, scons, GYP, qmake

• Xcode, xcodebuild

• Workspace, project, target

• External build, Run Script

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

1 Project 1 Target

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

1 Project N Targets

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

1 Project N Subprojects

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

1 Workspace N Projects

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

+ external build

+ external build

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

Проблемы Xcode

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

• Сборка специфических файлов под разные архитектуры (armv7/arm64)

• Скорость сборки

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

Swift

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

Swift• Мы используем Swift!

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

Swift• Мы используем Swift!

• 15-строчный скрипт для генерации иконки с версией сборки

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

CoreData

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

CoreDataПоучительная история

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

CoreDataПоучительная история

Many-To-Many

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

CoreDataПоучительная история

Many-To-Many

+Core data migration

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

ReactiveCocoa✓Замена KVO

✓Элементы функционального программирования в ObjC

✓Меньше изменяемого состояния -> меньше багов

- Крутая кривая обучения

- Слишком много блоков в коде

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

–Alex A, iOS team lead

“Зачем мы засунули RAC и не можем высунуть?”

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

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

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

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

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

Page 68: "Подходы, используемые в разработке iOS-клиента Viber" Кирилл Лашкевич (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 69: "Подходы, используемые в разработке iOS-клиента Viber" Кирилл Лашкевич (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 70: "Подходы, используемые в разработке iOS-клиента Viber" Кирилл Лашкевич (Viber)

Проблемы с self в ObjC

• self захватывается по сильной ссылке

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

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

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

@weakself

https://habrahabr.ru/company/viber/blog/232185/

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

@weakself• Безопасное использование self в блоках: слабая ссылка пока блок не вызван и сильная во время вызова

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

• Проверка в рантайме на доступ к _ivar в блоках через неявный self

https://habrahabr.ru/company/viber/blog/232185/

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

[RACObserve(self, pttState) doNext: @weakselfnotnil(^(NSNumber *state)) { self.isRecording = !!state.intValue; } @weakselfend];

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

[RACObserve(self, pttState) doNext: @weakselfnotnil(^(NSNumber *state)) { self.isRecording = !!state.intValue; } @weakselfend];

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

[RACObserve(self, pttState) doNext: @weakselfnotnil(^(NSNumber *state)) { self.isRecording = !!state.intValue; } @weakselfend];

1628 блоков в проекте используют weakself

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

CrashlyticsПросто используйте её, она клевая

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

@notorca