Similar presentations:
Flutter в действии
1.
Flutter в действииГлаза боятся, а попробовать хочется
Сатуров Евгений
Android Teamlead, Surf
saturov
1
2.
Flutter в действииГлаза боятся, а попробовать хочется
Сатуров Евгений
Android Flutter Teamlead, Surf
saturov
2
3.
-Android/Flutter Teamlead
FlutterDevPodcast
PC Mobius
GDG Voronezh Lead
3
4.
Этот доклад для вас, если вы:• Уже прочитали все статьи на Хабре про то, «как я запустил Hello World, и что из
этого вышло»;
• В курсе, что Flutter позволяет быстро создавать красивые приложения, и хотите
узнать, правда ли это;
• Чувствуете дискомфорт при фразе «Всё – это виджеты»;
• Хотите посмотреть на чудаков, которые уже запилили Flutter в продакшн;
• Пришли в этот зал, потому что в соседнем непонятный айосный доклад.
4
5.
Часть 0.То, что вы уже знаете про Flutter.
5
6.
Очень скучный слайд• Flutter – мультиплатформенный open-source фреймворк;
• Приложения пишутся на Dart;
• Под капотом свой графический движок (Skia) и рантайм (Dart VM);
• Официально поддерживаются две платформы: iOS и Android;
• Неофициально ещё ряд других (веб, десктоп, носимые и встраиваемые ОС).
6
7.
*все картинки кликабельны7
8.
Архитектура фреймворкаUI (контролы, анимации, стилизация, user input);
Виджеты и стейт-менеджмент.
Skia (графический движок);
Dart (Runtime, GC);
Text (LibTxt).
Отрисовка на канве;
Нативные плагины.
8
9.
Архитектура фреймворкаUI (контролы, анимации, стилизация, user input);
Виджеты и стейт-менеджмент.
Skia (графический движок);
Dart (Runtime, GC);
Text (LibTxt).
Отрисовка на канве;
Нативные плагины.
https://github.com/flutter/flutter
9
10.
Всё своё ношу с собойUI (контролы, анимации, стилизация, user input);
Виджеты и стейт-менеджмент.
Skia (графический движок);
Dart (Runtime, GC);
Text (LibTxt).
Отрисовка на канве;
Нативные плагины.
10
11.
Типы сборок и компиляцияDebug
Release
JIT
AOT
• Low FPS;
• High FPS;
• «Тяжёлое» приложение
(> 40 Мб);
• «Лёгкое» приложение
(>7 Мб).
• Работает Hot Reload.
11
12.
Типы сборок и компиляция• Android - Gradle;
• iOS – Xcode Build;
• Flutter Assemble – coming soon.
12
13.
Часть 1.Наш опыт.
13
14.
За последние полгода мы:• Собрали команду;
• Написали 3 небольших приложения и стартанули большой финтех;
• Выработали ряд лучших практик и своё видение архитектуры;
• Заложили основу линейки переиспользуемых модулей, которые планируем
шарить в open-source.
14
15.
Начинать работатьс новой технологией надо так,
чтобы о твоём позоре
никто не узнал.
15
16.
«Вселенная Парк»16
17.
«Вселенная Парк»17
18.
Карта экранов18
19.
Проект в цифрах• 2 разработчика;
• 560 чел./час;
• 62% таски, 22% отладка, 15% на поболтать;
• 6 полноценных эпиков-фич;
• 76% попадание в собственные оценки.
19
20.
Распределение времени20
21.
Первый «подопытный» был выбран правильноНе было написано ни строчки платформенного кода, всё покрыто плагинами:
• Yandex Mapkit
• Camera
• Permission Handler
• Shared Preferences
• QR Flutter
• и многими другими.
21
22.
Flutter-приложение дешевле*• *чем два нативных приложения;
• Команда разработки на 40% меньше;
• Более линейные процессы;
• Больше времени остаётся на разработку фичей.
22
23.
NDAФинтех
23
24.
Часть 2.Рекламная.
24
25.
2526.
• По-сравнению с двумя нативнымиприложениями - вероятно;
• Когда ты понимаешь, с какой стороны
подступиться к задаче;
• Когда ты способен заранее оценить
трудозатраты (не всегда);
• Когда приложение не заточено на
глубокую работу с платформенными API.
26
27.
2728.
• Нативный Look & Feel сам себя не сделает – это возможно, но вручную;• Apple-юзеры всё ещё находят отличия в UI (не понимаю, как они это делают);
• Для унифицированного UI/UX – идеально.
28
29.
Максимальная мимикрия29
30.
3031.
• Нет бутылочных горлышек нарендеринге (прощай, JavaScript Bridge);
• Простота реализации асинхронных задач
– миф (Future исполняется в UI-потоке);
• Из коробки «летать» не будет.
Берём профайлер, лучшие практики и
вперёд!
31
32.
3233.
Часть 3.Жизненная.
33
34.
FLUTTER-ЛИД ПОСЛЕ СОБЕСЕДОВАНИЯ34
35.
Ищу Flutter-разработчикаТребуемый опыт: 1-3 года.
35
36.
Немного сухой статистикиОктябрь
Сентябрь
Август
0%
10%
20%
30%
40%
Вакансии
50%
60%
70%
80%
90%
100%
Резюме
36
37.
Бэкграунд нашей Flutter-команды6
1
1
37
38.
Бэкграунд нашей Flutter-команды6
38
39.
Без «яблока» не обойтись• Собрать билд локально;
• Настроить Firebase;
• Пофиксить специфичный баг вёрстки;
• Разобраться, почему не работает… (подставь свой вариант);
• Написать полноценный платформенный плагин;
39
40.
Назад в будущее (пишем на Dart)• Не Kotlin;;;;;;;;;;;;;;;
• Однопоточный (но есть Isolate);
• Нет модификаторов доступа: _приватность;
• Нет перегрузки функций;
• Mixins – интерфейсы с реализацией;
• Enum без состояния;
• Нет data-классов, нет null-safety (Null – это тип), нет sealed-классов и многого
другого.
40
41.
Dart.equals(Java) == true?static String normalize(String inputString, {bool withPrefix = false}) {
StringBuffer buff = StringBuffer();
for (var i = 0; i < inputString.length; i++) {
String o = inputString[i];
if (int.tryParse(o) != null) {
buff.write(o);
}
}
String res = EMPTY_STRING;
if (withPrefix) {
res += PHONE_PREFIX;
}
res += buff.toString();
return res;
}
41
42.
Async/awaitFuture<Shop> _findNearestShop() async {
final userLocation = await _locInteractor.getLocationSafe().single;
final shops = await getShops(
lat: userLocation.latitude,
lon: userLocation.longitude,
).single;
shops.sort((shop1, shop2) => _compareShops(sh1, sh2, userLocation));
return shops.first;
}
42
43.
«Выучу только Flutter и Dart!»** не сказал ни один успешный Flutter-разработчик
43
44.
• Flutter + Dart;• Android + Kotlin;
• iOS + Swift;
• App Store Connect + TestFlight;
• Google Play Console + Firebase App Distribution.
44
45.
Периодически каждый из нас45
46.
https://pub.dev/flutter46
47.
https://pub.dev/flutter47
48.
Не очень хорошие популярные плагины• https://pub.dev/packages/permission_handler - в вашем iOS-приложении будут
указаны вообще все существующие пермишны, даже если они не используются;
• https://pub.dev/packages/flutter_local_notifications - конфликтует с другими пушплагинами, например firebase_messaging.
48
49.
Самое время собирать «звёздочки»Dagger
inject.dart
Retrofit
Dio
RxJava
RxDart
49
50.
Пример HTTP-запроса через Dioimport 'package:dio/dio.dart';
void getHttp() async {
try {
Response response = await Dio().get("http://www.google.com");
print(response);
} catch (e) {
print(e);
}
}
50
51.
Firebase что-то знает• firebase_core
• firebase_dynamic_links
• firebase_messaging
• firebase_remote_config
• firebase_analytics
• firebase_ml_vision
• firebase_auth
• firebase_performance
• firebase_storage
• firebase_in_app_messaging
• firebase_database
• И все остальные модули.
• firebase_crashlytics
• firebase_admob
51
52.
Проверенные нами плагины• https://pub.dev/packages/flutter_svg – поддержка векторной графики (позволяет
использовать *.svg);
• https://pub.dev/packages/camera – удобное API для работы с камерой (фото +
видео);
• https://pub.dev/packages/flutter_masked_text – маскирование полей ввода;
• https://pub.dev/packages/device_info – получение информации о девайсе.
52
53.
Если у вас есть время53
54.
Хорошая новость:• На Flutter можно написать вообще всё что угодно;
54
55.
Плохая новость:• На Flutter можно написать вообще всё что угодно;
• Для этого нужно знать очень много разных вещей;
55
56.
Плохая новость номер два:• На Flutter можно написать вообще всё что угодно;
• Для этого нужно знать очень много разных вещей;
• Не всегда после этого становится понятно, зачем вообще было всё это писать
на Flutter.
56
57.
Можно ли сделать на Flutter {$featureName} ?Да, можно.
• Dart (UI, бизнес-логика);
• Platform Channels + Native Plugins (Kotlin, Swift и т.д.);
• Platform Views;
• C/C++ direct interop using FFI.
57
58.
История про бесшовную авторизацию.(из новейшего опыта)
58
59.
У нас были…• Два нативных «легаси» приложения;
• Сложнейшая процедура инициализации сессии с необходимостью подписи
сертификата ЭЦП в веб-версии сервиса;
• Несколько десятков тысяч пользователей, которые уничтожили бы компанию в
случае массового разлогина при обновлении приложения.
59
60.
Можно ли сделать на Flutter {$featureName} ?Да, можно.
• Dart (UI, бизнес-логика);
• Platform Channels + Native Plugins (Kotlin, Swift и т.д.);
• Platform Views;
• C/C++ direct interop using FFI.
60
61.
Схема авторизацииAuth
Credentials
Authentication
61
62.
AuthCredentials
Auth
Credentials
Authentication
Authentication
62
63.
PlatformCredentials Provider
Provide
Auth
Credentials
Flutter
Credentials Provider
Authentication
63
64.
Инициализация MethodChannelconst _platform = MethodChannel(_authProviderChannelName);
64
65.
Платформенный поставщик Credentialsclass PlatformAuthDataProvider {
Future<Uint8List> getCert(String userId, String pinHash) {
return _platform.invokeMethod(
getCertificateMethodName,
[userId, pin],
);
}
65
66.
Платформенный поставщик Credentialsclass PlatformAuthDataProvider {
Future<Uint8List> getCert(String userId, String pinHash) {
return _platform.invokeMethod(
getCertificateMethodName,
[userId, pin],
);
}
66
67.
Платформенный поставщик Credentialsclass PlatformAuthDataProvider {
Future<Uint8List> getCert(String userId, String pinHash) {
return _platform.invokeMethod(
"fghvfkajsr/m1kjnbaf",
[userId, pin],
);
}
67
68.
Это вам не a.a.b.c()68
69.
Так, так, так… секьюрити• Реверс-инжиниринг практически бесполезен;
• Обфускация в Dart существует, но…
Note: that obfuscation support is not very well tested
and might not work at the moment.
• Самое уязвимое место – Method Channels со стороны платформенного кода (да
поможет нам ручная обфускация).
69
70.
MainActivity.ktMethodChannel(
flutterView,
authProviderChannelName
).setMethodCallHandler { call, result ->
launch {
val output: Any = when (call.method) {
albhsfsadg -> {
val arguments: List<String> =
call.arguments as List<String>
authDataProvider.getCert(args[0], args[1])
}
70
71.
PlatformCredentials Provider
Provide
Auth
Credentials
Authentication
Migrate
Auth
Credentials
Flutter
Credentials Provider
71
72.
Hot Reload спасает жизнь при разработке72
73.
Но на CI/CD запасайтесь поп-корном73
74.
Джентельменский деплой-набор• Fastlane;
• Firebase App Distribution.
74
75.
Часть 4.Вдохновляющая.
75
76.
Переход на Flutter – это не смена работы• Подходы;
• Синтаксис языка;
• Архитектура.
Всё это знакомо и привычно любому мобильному разработчику.
76
77.
Больше времени с друзьями и близкими• Применение изменений: ≈ 2-3 сек.
• Синхронизация проекта: ≈ 5-10 сек.
77
78.
Настало время для крутого вызова• Нет проверенных лучших практик;
• Нет надежды на то, что кто-то поможет (даже SOF);
• С каждой проблемой ты можешь столкнуться впервые;
• Нужно обдумывать каждый шаг и брать на себя ответственность;
• Никому нельзя доверять.
78
79.
7980.
Ссылки на меняhttps://twitter.com/saturovv
https://www.facebook.com/saturov
https://habr.com/ru/users/saturovv/
Telegram: @saturov
80
81.
Ссылки на полезные ресурсыhttps://flutter.dev/
https://flutter.dev/docs/codelabs
https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw
https://habr.com/ru/company/google/blog/426701/
81