Hola, Amigos! С вами Павел Гершевич, Mobile Team Lead в Amiga. В прошлый раз мы рассмотрели, как получить покрытие кода тестами в обычных проектах. Сегодня разберемся с многомодульными проектами ⚙️
Применив предыдущие команды, можно получить покрытие для каждого отдельного пакета. Однако, чтобы увидеть общую картину, нужно объединить результаты. Для этого мы используем Melos и специальные скрипты.
Начнем с обновления скрипта для генерации покрытия. Он должен работать с каждым пакетом отдельно. Добавим проверку на наличие папки test, и, если ее нет, создадим:
Далее заменим в скрипте статическое название пакета на переменную:
Теперь скрипт сможет корректно обрабатывать все модули.
Чтобы объединить результаты покрытия, создадим скрипт, который соберет все данные в один файл:
Этот скрипт ищет папки с покрытиями, объединяет файлы lcov.info в один общий и сохраняет его в папке coverage_report в корне проекта. После этого можно создать HTML-отчет о покрытии кода тестами⚙️
А как вы обычно отслеживаете покрытие кода в своих проектах? Рассказывайте в чате.
Применив предыдущие команды, можно получить покрытие для каждого отдельного пакета. Однако, чтобы увидеть общую картину, нужно объединить результаты. Для этого мы используем Melos и специальные скрипты.
Начнем с обновления скрипта для генерации покрытия. Он должен работать с каждым пакетом отдельно. Добавим проверку на наличие папки test, и, если ее нет, создадим:
package=$1
if [ ! -d “test” ]; then
mkdir test
fi
Далее заменим в скрипте статическое название пакета на переменную:
package=$package
Теперь скрипт сможет корректно обрабатывать все модули.
Чтобы объединить результаты покрытия, создадим скрипт, который соберет все данные в один файл:
escapedPath=”$(echo pwd | sed ‘s/\//\\\//g’)”
if grep flutter pubspec.yaml > /dev/null; then
if [ -d “coverage” ]; then
if [ ! -d “$MELOS_ROOT_PATH/coverage_report” ]; then
mkdir “$MELOS_ROOT_PATH/coverage_report”!
fi
sed “s/^SF:lib:$escapedPath\/lib/g” coverage/lcov.info >> “$MELOS_ROOT_PATH/coverage_report/lcov.info”
rm -rf “coverage”
fi
fi
Этот скрипт ищет папки с покрытиями, объединяет файлы lcov.info в один общий и сохраняет его в папке coverage_report в корне проекта. После этого можно создать HTML-отчет о покрытии кода тестами
А как вы обычно отслеживаете покрытие кода в своих проектах? Рассказывайте в чате.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👏5👍2
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня расскажем, как заменять разные сервисы (Google Play Services, Huawei Mobile Services, RuStore и др.) в одном приложении на примере Push-уведомлений, используя многомодульность.
Создадим несколько пакетов:
–
–
–
Теперь определим основные функции. В нашем случае это Push-уведомления: инициализация, получение токена и обработка открытия уведомлений. Для этого создадим в пакете
Можно добавить свои функции или создать такие же классы для сервисов аналитики, Remote Config или др. Настроим зависимости для каждого пакета в pubspec.yaml.
🔵 Для Google Play Services:
🔵 Для Huawei Mobile Services:
Теперь напишем классы, расширяющие интерфейс. Помимо этого, можно вынести настройки сервисов в соответствующие пакеты.
Для сборок используем flavors, т.к. делать нам это нужно только для Android.
Перед публикацией заменяем пакет в pubspec.yaml и корректируем строку создания объекта в Dependency Injection. Затем выбираем необходимый flavor и собираем приложение с его конфигурацией.
А как вы решаете задачи с поддержкой разных платформ и сервисов в одном приложении? Расскажите о своем опытом в чате⚙️
Создадим несколько пакетов:
–
mobile_services_interface
–
gps
–
hms
Теперь определим основные функции. В нашем случае это Push-уведомления: инициализация, получение токена и обработка открытия уведомлений. Для этого создадим в пакете
mobile_services_interface
абстрактный класс.
abstract interface class IPushService {
Future<void> init();
Future<String> getToken();
Future<void> onOpenPush();
}
Можно добавить свои функции или создать такие же классы для сервисов аналитики, Remote Config или др. Настроим зависимости для каждого пакета в pubspec.yaml.
mobile_services_interface:
path: ../mobile_services_interface
firebase_messaging: ^latest_version
mobile_services_interface:
path: ../mobile_services_interface
huawei_push: ^latest_version
Теперь напишем классы, расширяющие интерфейс. Помимо этого, можно вынести настройки сервисов в соответствующие пакеты.
Для сборок используем flavors, т.к. делать нам это нужно только для Android.
Перед публикацией заменяем пакет в pubspec.yaml и корректируем строку создания объекта в Dependency Injection. Затем выбираем необходимый flavor и собираем приложение с его конфигурацией.
А как вы решаете задачи с поддержкой разных платформ и сервисов в одном приложении? Расскажите о своем опытом в чате
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🥰3👍2
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня расскажем, как избавиться от написания шаблонного кода на проекте⚙️
Mason — набор для командной строки, позволяющий унифицировать процесс создания файлов с шаблонным кодом без надобности написания своих плагинов для IDE. Это ускоряет разработку и позволяет больше фокусироваться на написании фич.
Для установки выполним команду:
Далее инициализируем Mason в нашем проекте:
Для создания первого шаблона, который в Mason называется brick, необходимо прописать команду:
Это создаст папку __bricks__/my_brick в корне проекта. Внутри можно настроить структуру, а для генерации классов — использовать переменные.
Шаблоны в Mason не ограничены один файлом. Можно создать шаблоны на генерацию кода для разных библиотек, репозитории, State Management и страницы для одной фичи.
Переменные используются для подстановки значений в шаблоне, например, для именования файлов и классов. Чтобы сгенерировать шаблон, запустите:
Создадим сам шаблон. В папку brick помещаем необходимые файлы {{name.snakeCase()}}.dart. И в нем же создаем шаблон для этого файла:
При вызове mason make с флагом –name my-class будет создан файл my_class.dart, содержащий код:
Готовые шаблоны можно найти на сайте.
Делитесь в чате используете ли вы Mason в своих проектах?🙂
Mason — набор для командной строки, позволяющий унифицировать процесс создания файлов с шаблонным кодом без надобности написания своих плагинов для IDE. Это ускоряет разработку и позволяет больше фокусироваться на написании фич.
Для установки выполним команду:
dart pub global activate mason_cli
Далее инициализируем Mason в нашем проекте:
mason init
Для создания первого шаблона, который в Mason называется brick, необходимо прописать команду:
mason add (имя шаблона)
Это создаст папку __bricks__/my_brick в корне проекта. Внутри можно настроить структуру, а для генерации классов — использовать переменные.
Шаблоны в Mason не ограничены один файлом. Можно создать шаблоны на генерацию кода для разных библиотек, репозитории, State Management и страницы для одной фичи.
vars:
name:
type: string
description: Name of your class
Переменные используются для подстановки значений в шаблоне, например, для именования файлов и классов. Чтобы сгенерировать шаблон, запустите:
mason make (имя шаблона)
Создадим сам шаблон. В папку brick помещаем необходимые файлы {{name.snakeCase()}}.dart. И в нем же создаем шаблон для этого файла:
class {{name.snakeCase()}} {
final String {{name.camelCase()}}
{{name.snakeCase()}}(
this.{{name.camelCase()}},
);
}
При вызове mason make с флагом –name my-class будет создан файл my_class.dart, содержащий код:
class MyClass{
final String myClass;
MyClass(
this.myClass,
);
}
Готовые шаблоны можно найти на сайте.
Делитесь в чате используете ли вы Mason в своих проектах?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4🔥3
Дайджест сентября
Hola, Amigos! Собрали в одну подборку все полезные посты и статьи сентября, которые вы могли пропустить. Выбирайте, что вам интересно, и переходите по ссылкам.
⚪️ Обзор виджета Draggable
⚪️ Как сделать динамические иконки для приложения
⚪️ Обзор пакета local_auth
⚪️ Обзор пакета bloc_concurrency
⚪️ Сборка приложения для Android
⚪️ Определение покрытия тестами для обычных проектов и для многомодульных
⚪️ Интеграция нескольких мобильных сервисов в Flutter приложение под Android
⚪️ Обзор инструмента Mason
Всем хорошего кода!🙂
Hola, Amigos! Собрали в одну подборку все полезные посты и статьи сентября, которые вы могли пропустить. Выбирайте, что вам интересно, и переходите по ссылкам.
Всем хорошего кода!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
Выиграй участие в конференции CrossConf!
Hola, amigos!
Вместе с организаторами конференции CrossConf дарим 2 билета на крупнейшее мероприятие по кросс-платформам с мощнейшим Flutter-потоком.
Встречаемся 08 ноября в Москве в Start Hub на Красном Октябре в режиме офлайн и онлайн.
В программе очень крутые доклады по 🦋Flutter от эффективного BDUI и работы с логами до Divkit и Flame.
Участвовать в розыгрыше просто:
1️⃣ Подпишись на нас @flutter_amiga и на @crossconf
2️⃣ Нажми “Участвую” под этим постом
3️⃣ Жди публикации результатов розыгрыша 10 октября
И скажем по секрету, Павел Гершевич, Mobile Team Lead в Amiga, тоже там выступит!
До встречи! 🙂
Hola, amigos!
Вместе с организаторами конференции CrossConf дарим 2 билета на крупнейшее мероприятие по кросс-платформам с мощнейшим Flutter-потоком.
Встречаемся 08 ноября в Москве в Start Hub на Красном Октябре в режиме офлайн и онлайн.
В программе очень крутые доклады по 🦋Flutter от эффективного BDUI и работы с логами до Divkit и Flame.
Участвовать в розыгрыше просто:
1️⃣ Подпишись на нас @flutter_amiga и на @crossconf
2️⃣ Нажми “Участвую” под этим постом
3️⃣ Жди публикации результатов розыгрыша 10 октября
И скажем по секрету, Павел Гершевич, Mobile Team Lead в Amiga, тоже там выступит!
До встречи! 🙂
👍14❤5🔥3🤩1
Hola, Amigos! Рассказываем, как для нас прошла XIII Международная IT-конференция «Стачка» в Санкт-Петербурге.
Наш Mobile Team Lead Павел Гершевич выступал с докладом “Это больше, чем биометрия. Или как сделать локальную аутентификацию в мобильном приложении”. Было мощно: реальные примеры, полезные советы и много вопросов от участников! Но еще больше получили благодарностей от слушателей. А вот и «спасибо» от самого Паши:
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
Наш Mobile Team Lead Павел Гершевич выступал с докладом “Это больше, чем биометрия. Или как сделать локальную аутентификацию в мобильном приложении”. Было мощно: реальные примеры, полезные советы и много вопросов от участников! Но еще больше получили благодарностей от слушателей. А вот и «спасибо» от самого Паши:
Спасибо всем, кто был в зале, за поддержку и вопросы! Вы супер-аудитория!
Второй раз выступаю на Стачке, это очень крутая конференция, которая собирает людей из всех IT-областей и из различных уголков нашей страны вместе. Очень радует, что организовывается отдельная часть из докладов именно про Flutter! Поэтому советую всем приехать на Стачку в следующем году!
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
🔥19❤1
Hola, Amigos!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня рассмотрим некоторые базовые концепции пакета rxdart. Он позволяет нам работать с потоками данных еще эффективнее, так как добавляет много всего полезного.
RxDart - пакет от компании ReactiveX, которые до него уже сделали много популярных библиотек для других языков программирования. Например, RxJava или RxSwift. Но так как в Dart уже есть стримы, их не добавляли, но дополнительно улучшили, добавив методы расширений и новые типы потоков данных.
Давайте посмотрим для начала на то, как мы можем добавить буферизацию к нашему
Также иногда нам нужно отбрасывать данные и брать только последнее, что приходит. Для этого пригодятся методы
А что делать, если нужно объединить несколько потоков данных? Для этого у RxDart заготовлены несколько конструкторов. Например,
Делитесь в чате, используете ли вы RxDart на своих проектах и как он вам помогает? А мы поделимся еще несколькими полезными концептами во второй части!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Сегодня рассмотрим некоторые базовые концепции пакета rxdart. Он позволяет нам работать с потоками данных еще эффективнее, так как добавляет много всего полезного.
RxDart - пакет от компании ReactiveX, которые до него уже сделали много популярных библиотек для других языков программирования. Например, RxJava или RxSwift. Но так как в Dart уже есть стримы, их не добавляли, но дополнительно улучшили, добавив методы расширений и новые типы потоков данных.
Давайте посмотрим для начала на то, как мы можем добавить буферизацию к нашему
Stream
. Допустим, что у нас есть поток данных, который выдает информацию достаточно часто, а нам нужно получать ее не по одному, а сразу несколько штук. Для этого мы можем воспользоваться добавлением еще одного потока данных, который будет отмерять время, просто передать количество, функцию для определения конца отрезка или необходимый отрезок времени, а функции buffer
, bufferCount
, bufferTest
и bufferTime
вернут нам список данных, который накопился.Также иногда нам нужно отбрасывать данные и брать только последнее, что приходит. Для этого пригодятся методы
debounce
и debounceTime
. В первый мы можем передать какой-нибудь другой Stream
и при получении в него событий, получать данные и в изначальном. Во второй мы просто передадим время для промежутков с выдачей информации.А что делать, если нужно объединить несколько потоков данных? Для этого у RxDart заготовлены несколько конструкторов. Например,
MergeStream
, который просто добавляет события из всех стримов в себя, или CombineLatestStream
, который позволяет производить какие-либо вычисления, когда в один из стримов приходит событие, в этом случае, для других берутся последние значения.Делитесь в чате, используете ли вы RxDart на своих проектах и как он вам помогает? А мы поделимся еще несколькими полезными концептами во второй части!
👍11🔥5❤3❤🔥1
Hola, Amigos!
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Мы продолжаем изучать концепции и полезные функции в rxdart.
В прошлый раз мы забыли про троттлинг. Он похож на debounce, но возвращает не последнее, а первое значение, что полезно при обработке различных случаев, например, отправки форм. Для него можно использовать методы throttle и throttleTime.
Еще давайте затронем фильтрацию данных внутри стримов, так как это часто необходимо. Да, в Dart есть метод where, но его может не хватать или он будет слишком большим в коде. Поэтому в rxdart есть расширение whereType, которое позволяет фильтровать по типу без применения cast, и его дополнение - whereNotNull, которое убирает все нулевые значения из потока данных.
Еще одно полезное расширение - distinctUnique. Оно позволяет нам сохранять в стриме только уникальные значения. Очень похоже на применение toSet().toList() для списков.
И самое главное, что добавляет rxdart - это новые StreamController, которые здесь называются Subjects. Их 2 - BehaviorSubject и ReplaySubject. Давайте посмотрим на каждый из них.
BehaviorSubject - контроллер, который при добавлении слушателя сразу же передает ему последнее значение, которое попало в стрим. Также ему можно задать изначальное значение при помощи конструктора BehaviorSubject.seeded.
ReplaySubject - контроллер, который при добавлении слушателя сразу же передаст все значения, которые в него попадали. Но если нам нужно возвращать последние N значений, то мы можем применить в его конструкторе параметр maxSize.
Делитесь в чате, как часто вы используете стримы на своих проектах?
На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Мы продолжаем изучать концепции и полезные функции в rxdart.
В прошлый раз мы забыли про троттлинг. Он похож на debounce, но возвращает не последнее, а первое значение, что полезно при обработке различных случаев, например, отправки форм. Для него можно использовать методы throttle и throttleTime.
Еще давайте затронем фильтрацию данных внутри стримов, так как это часто необходимо. Да, в Dart есть метод where, но его может не хватать или он будет слишком большим в коде. Поэтому в rxdart есть расширение whereType, которое позволяет фильтровать по типу без применения cast, и его дополнение - whereNotNull, которое убирает все нулевые значения из потока данных.
Еще одно полезное расширение - distinctUnique. Оно позволяет нам сохранять в стриме только уникальные значения. Очень похоже на применение toSet().toList() для списков.
И самое главное, что добавляет rxdart - это новые StreamController, которые здесь называются Subjects. Их 2 - BehaviorSubject и ReplaySubject. Давайте посмотрим на каждый из них.
BehaviorSubject - контроллер, который при добавлении слушателя сразу же передает ему последнее значение, которое попало в стрим. Также ему можно задать изначальное значение при помощи конструктора BehaviorSubject.seeded.
ReplaySubject - контроллер, который при добавлении слушателя сразу же передаст все значения, которые в него попадали. Но если нам нужно возвращать последние N значений, то мы можем применить в его конструкторе параметр maxSize.
Делитесь в чате, как часто вы используете стримы на своих проектах?
❤9👍5❤🔥3🔥2🥰1