Hola, Amigos! Рассказываем и показываем в карточках, как прошел BOOST для нас в 2024 году.
А еще раскрываем интригу, кто такая Лидочка! Знакомьтесь с нашим виртуальным менеджером по вашим нецелевым лидам. Переходите в чат, там все подробности⚙️
Проводили лето со всем IT-комьюнити и встретили осень легендарным треком «третье сентября» на афтепати.
А еще раскрываем интригу, кто такая Лидочка! Знакомьтесь с нашим виртуальным менеджером по вашим нецелевым лидам. Переходите в чат, там все подробности
Проводили лето со всем IT-комьюнити и встретили осень легендарным треком «третье сентября» на афтепати.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥3🍾1
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня разберем пакет bloc_concurrency, который позволяет манипулировать обработкой событий в BLoC и содержит в себе набор трансформеров 🙂
Трансформеры позволяют изменять поток событий внутри BLoC, чтобы они обрабатывались в нужном порядке или не попадали в обработку в определенных случаях.
Трансформеры передаются через поле transformer в методе on. Для каждого отдельного события (event) можно задать свой трансформер. Если нужно применить один трансформер ко всем событиям, создайте абстрактный класс событий и назначьте его трансформеру.
🔴
🔴
🔴
🔴
Ставьте 🔥, если было полезно и делитесь в чате, пользуетесь ли данным пакетом?
Трансформеры позволяют изменять поток событий внутри BLoC, чтобы они обрабатывались в нужном порядке или не попадали в обработку в определенных случаях.
MyBloc() : super(MyState()) {
on<MyEvent>(
_myEvent,
transformer: concurrent(),
);
}
Трансформеры передаются через поле transformer в методе on. Для каждого отдельного события (event) можно задать свой трансформер. Если нужно применить один трансформер ко всем событиям, создайте абстрактный класс событий и назначьте его трансформеру.
abstract class MyAbstractEvent {}
class OtherEvent extends MyAbstractEvent {}
MyBloc() : super(MyState()) {
on<MyAbstractEvent>(
…,
transformer: concurrent(),
);
}
bloc_concurrency
включает четыре типа трансформеров:concurrent
— обрабатывает все события одновременно; используется в bloc по умолчанию.sequential
— обрабатывает события последовательно, применяя asyncMap. Подходит для случаев, когда требуется поочередная обработка, например, при добавлении товара в корзину по одному.restartable
— прерывает обработку текущего события, если поступает новое. Полезен, когда каждое новое событие может полностью изменить результат, как при обновлении строки поиска: в этом случае нас не интересует результат обработки предыдущего ввода.droppable
— блокирует добавление новых событий до завершения обработки текущего. Эффективен для предотвращения дублирующих действий, например, при нажатии кнопки входа на странице авторизации, чтобы избежать лишних запросов к серверу.Ставьте 🔥, если было полезно и делитесь в чате, пользуетесь ли данным пакетом?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍6🥰4❤2🤗1
Hola Amigos! На связи Михаил Чернецов, Flutter Dev, и Павел Гершевич, Mobile Team Lead в Amiga. Сегодня расскажем, как собираем приложения под Android.
Существует два вида собираемых файла под Android: APK (Android Package Kit) и Android App Bundle (AAB). Рассмотрим их особенности.
APK — это исполняемый файл, а App Bundle — формат публикаций.
Сборка APK
Запускаем команду:
Однако такой APK подписан debug-ключом и не подходит для публикации. Чтобы создать релизный ключ, используем инструмент keytool из JDK.
Для Windows:
Для macOS и Linux:
Не забудьте указать правильный путь и имя файла ключа. Затем создаем файл
Теперь APK готов к публикации, но он универсальный и достаточно объемный. Чтобы уменьшить размер, лучше собрать отдельные APK для каждой архитектуры процессора:
На выходе получим несколько APK, которые можно зарелизить. Однако они будут крупнее по сравнению с теми, что пользователи смогут скачать из магазинов приложений с использованием AAB.
Сборка AAB
AAB собирается под определенную конфигурацию девайса пользователя. На устройство устанавливается облегченное APK, оптимизированное под архитектуру процессора, разрешение экрана и выбранные языки. Сборка APK в таком случае происходит на стороне магазина приложений.
Для сборки AAB:
1) Подготовьте файл для подписи приложения.
2) Запустите команду:
Этот файл можно загрузить в магазины приложений, и пользователи смогут скачивать облегченное приложение. При обновлении будет загружаться только измененная часть приложения.
Когда использовать APK?
Сборка APK также важна, например, для тестирования — чтобы не выкладывать каждую сборку в магазины приложений. Или если приложение распространяется вне Google Play, App Gallery или RuStore.
Если вам нужен экспертный взгляд или помощь в сборке и публикации приложения, пишите нам. Будем рады помочь!
Существует два вида собираемых файла под Android: APK (Android Package Kit) и Android App Bundle (AAB). Рассмотрим их особенности.
APK — это исполняемый файл, а App Bundle — формат публикаций.
Сборка APK
Запускаем команду:
flutter build apk
Однако такой APK подписан debug-ключом и не подходит для публикации. Чтобы создать релизный ключ, используем инструмент keytool из JDK.
Для Windows:
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
-storetype JKS -keyalg RSA -keysize 2048 -validity 10000 `
-alias upload
Для macOS и Linux:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \
-keysize 2048 -validity 10000 -alias upload
Не забудьте указать правильный путь и имя файла ключа. Затем создаем файл
/android/key.properties
для подписи:storePassword=<пароль от KeyStore>
keyPassword=<пароль от самого ключа>
keyAlias=upload
storeFile=<местоположение файла с ключом>
Теперь APK готов к публикации, но он универсальный и достаточно объемный. Чтобы уменьшить размер, лучше собрать отдельные APK для каждой архитектуры процессора:
flutter build apk --split-per-abi
На выходе получим несколько APK, которые можно зарелизить. Однако они будут крупнее по сравнению с теми, что пользователи смогут скачать из магазинов приложений с использованием AAB.
Сборка AAB
AAB собирается под определенную конфигурацию девайса пользователя. На устройство устанавливается облегченное APK, оптимизированное под архитектуру процессора, разрешение экрана и выбранные языки. Сборка APK в таком случае происходит на стороне магазина приложений.
Для сборки AAB:
1) Подготовьте файл для подписи приложения.
2) Запустите команду:
flutter build appbundle
Этот файл можно загрузить в магазины приложений, и пользователи смогут скачивать облегченное приложение. При обновлении будет загружаться только измененная часть приложения.
Когда использовать APK?
Сборка APK также важна, например, для тестирования — чтобы не выкладывать каждую сборку в магазины приложений. Или если приложение распространяется вне Google Play, App Gallery или RuStore.
Если вам нужен экспертный взгляд или помощь в сборке и публикации приложения, пишите нам. Будем рады помочь!
❤9🔥7👍4🥰1👏1😱1👨💻1
«Попали в сердечко»🥹
Hola, Amigos! Ради такой обратной связи мы готовы тратить 30 часов на подготовку докладов и 8 часов еще много-много раз.
Множество вопросов от аудитории после лекции — плюс еще одно доказательство, что нам удалось угадать с интересными и актуальными темами. Ес!💪🏼
Напомним, что Паша Гершевич, Flutter Team Lead выступал с докладом «Логирование на Flutter или какие метрики помогут в оптимизации».
А Артем Салеев, CTO Amiga — с темой «Перестройка процессов разработки при масштабировании агентства».
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
Hola, Amigos! Ради такой обратной связи мы готовы тратить 30 часов на подготовку докладов и 8 часов еще много-много раз.
Множество вопросов от аудитории после лекции — плюс еще одно доказательство, что нам удалось угадать с интересными и актуальными темами. Ес!💪🏼
Напомним, что Паша Гершевич, Flutter Team Lead выступал с докладом «Логирование на Flutter или какие метрики помогут в оптимизации».
А Артем Салеев, CTO Amiga — с темой «Перестройка процессов разработки при масштабировании агентства».
Смотрите фотки и ставьте 🔥, если ждете записи докладов!
🔥18👏2🤩1
Hola Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня снова затронем тему автоматического тестирования, а точнее получение процента покрытия нашего кода тестами ⚙️
Первый шаг — запустить тесты с параметром coverage:
Эта команда сгенерирует файл с информацией о покрытии, но для его расшифровки понадобится инструмент lcov, доступный только для Unix-систем.
Установка lcov
Для Linux (на примере Ubuntu):
Для macOS:
Генерация отчета в HTML
Далее, конвертируем полученный файл в удобный для чтения HTML-формат:
Теперь в папке coverage/html можно просматривать отчет по покрытию. Однако тут возникает проблема: отчет может не учитывать все файлы вашего проекта, так как покрываются только те файлы, которые явно были импортированы в тесты.
Решение проблемы с неполным покрытием
Чтобы охватить все файлы, нужно импортировать их в тесты через специальный файл, например,
Тут мы создаем файл
⚙️ Важное правило: не импортировать файлы, которые были сгенерированы, можно дополнять такой скрипт файлами от freezed и других библиотек. В конце добавляем метод main, чтобы импорты попали в покрытие.
Автоматизация на CI/CD
Скрипт сохраняем в файл с расширением .sh и запускаем перед тестами.
Все эти шаги можно интегрировать в ваш CI/CD процесс для автоматической проверки покрытия кода тестами.
А как вы подходите к тестированию? Какие используете методики?🙂
Первый шаг — запустить тесты с параметром coverage:
flutter test --coverage
Эта команда сгенерирует файл с информацией о покрытии, но для его расшифровки понадобится инструмент lcov, доступный только для Unix-систем.
Установка lcov
Для Linux (на примере Ubuntu):
sudo apt-get update -qq -y
sudo apt-get install lcov -y
Для macOS:
brew install lcov
Генерация отчета в HTML
Далее, конвертируем полученный файл в удобный для чтения HTML-формат:
genhtml coverage/lcov.info -o coverage/html
Теперь в папке coverage/html можно просматривать отчет по покрытию. Однако тут возникает проблема: отчет может не учитывать все файлы вашего проекта, так как покрываются только те файлы, которые явно были импортированы в тесты.
Решение проблемы с неполным покрытием
Чтобы охватить все файлы, нужно импортировать их в тесты через специальный файл, например,
coverage_helper_test.dart
. Этот процесс можно автоматизировать с помощью скрипта:
file=test/coverage_helper_test.dart
echo "// Helper file to make coverage work for all files\n" > $file
echo "// ignore_for_file: unused_import" > $file
find lib -name "*.dart" "!" -name "*.g.dart" | cut -c4- | awk -v package="my_package" '{printf "import '\''package:%s%s'\'';\n", package, $1}' >> $file
echo "void main(){}" >> $file
Тут мы создаем файл
coverage_helper_test.dart
, ставим игнорирование определенного правила статического анализа на один файл и импортируем наши файлы. Автоматизация на CI/CD
Скрипт сохраняем в файл с расширением .sh и запускаем перед тестами.
./coverage_helper.sh
Все эти шаги можно интегрировать в ваш CI/CD процесс для автоматической проверки покрытия кода тестами.
А как вы подходите к тестированию? Какие используете методики?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍5🥰4
Никогда еще не был космос так близко
Hola, Amigos! Полетели в Санкт-Петербург на XII международную IT-конференцию «Стачка». 27 и 28 сентября в гостинице Cosmos вы сможете зарядиться атмосферой новых знаний, революционными идеями и вдохновением по направлениям:
⚪️ разработка
⚪️ дизайн и контент
⚪️ digital-маркетинг
⚪️ управление
⚪️ стартапы и технологии
Павел Гершевич, Team Lead Flutter от команды Amiga выступит с докладом «Это больше, чем биометрия. Или как сделать локальную аутентификацию в мобильном приложении».
Рассмотрим два основных алгоритма работы с локальной аутентификацией, а также инструменты, которые помогут сделать это как в нативных приложениях, так и в кросс-платформенных.
Обязательно приходите 28 сентября в 17:25 в зал Разработка-2.
Специально для вас действует промокод«спикер_10» . Покупайте билеты со скидкой! А с программой можно ознакомиться тут.
Взлетаеееем!⚙️
Hola, Amigos! Полетели в Санкт-Петербург на XII международную IT-конференцию «Стачка». 27 и 28 сентября в гостинице Cosmos вы сможете зарядиться атмосферой новых знаний, революционными идеями и вдохновением по направлениям:
Павел Гершевич, Team Lead Flutter от команды Amiga выступит с докладом «Это больше, чем биометрия. Или как сделать локальную аутентификацию в мобильном приложении».
Рассмотрим два основных алгоритма работы с локальной аутентификацией, а также инструменты, которые помогут сделать это как в нативных приложениях, так и в кросс-платформенных.
Обязательно приходите 28 сентября в 17:25 в зал Разработка-2.
Специально для вас действует промокод
Взлетаеееем!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👏4⚡2
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