Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Сегодня мы посмотрим на еще один способ интеграции нативного кода в Flutter - Pigeon.
Pigeon - инструмент, создающий интерфейсы для работы с нативным кодом при помощи кодогенерации. Это помогает нам не прописывать обработку Platform Channels напрямую.
-----------------------------------------------
Давайте посмотрим, как с ним работать. Для начала создадим в корне проекта папку pigeons, в которой будут находится необходимые шаблоны.
Стоит учитывать, как данные передаются в платформу и какие типы данных поддерживаются платформой. Это можно узнать по ссылке.
Для получения сообщений от платформы необходимо использовать аннотацию
Так же можем описать классы, которые будут использоваться, Pigeon также сгененирует платформенных код для них.
Создадим файл
Здесь мы обозначаем директории, в которых будет генерироваться Pigeon-файлы.
Если их не добавить, то данные файлы не сгенерируются. Для использования плагина на уровне Flutter-приложения теперь вызываем сгенерированный класс:
-----------------------------------------------
Для настройки Pigeon на Android теперь необходимо сделать две вещи:
1️⃣ Создать файл
2️⃣ Добавить в плагины наш плагин в функции
Для iOS необходимо внести изменения в файл
И в этом же классе реализуем функционал нашего плагина:
Тем самым мы реализовали Platform Channel с помощью Pigeon в нашем приложении.
Делитесь в чате, пробовали ли вы Pigeon для своих Platform Channels?
Pigeon - инструмент, создающий интерфейсы для работы с нативным кодом при помощи кодогенерации. Это помогает нам не прописывать обработку Platform Channels напрямую.
-----------------------------------------------
Давайте посмотрим, как с ним работать. Для начала создадим в корне проекта папку pigeons, в которой будут находится необходимые шаблоны.
import 'package:pigeon/pigeon.dart';
@HostApi()
abstract class CalculateHostApi {
int calculate(int a, int b);
}
Стоит учитывать, как данные передаются в платформу и какие типы данных поддерживаются платформой. Это можно узнать по ссылке.
Для получения сообщений от платформы необходимо использовать аннотацию
@FlutterApi
.Так же можем описать классы, которые будут использоваться, Pigeon также сгененирует платформенных код для них.
Создадим файл
generateCalculate.sh
для того, чтобы запускать Shell-скрипт.
flutter pub run pigeon \
--input "pigeons/calculate.dart" \
--dart_out "lib/calculate.g.dart" \
--kotlin_out "android/app/src/main/kotlin/com/example/pigeon_example/Calculate.g.kt" \
--swift_out "ios/Runner/Calculate.g.swift"
Здесь мы обозначаем директории, в которых будет генерироваться Pigeon-файлы.
Если их не добавить, то данные файлы не сгенерируются. Для использования плагина на уровне Flutter-приложения теперь вызываем сгенерированный класс:
await CalculateHostApi().calculate(3, 7);
-----------------------------------------------
Для настройки Pigeon на Android теперь необходимо сделать две вещи:
Calculate.kt
и реализовать код нашего плагина:
class Calculate : FlutterPlugin, CalculateHostApi{
// Функция которую мы реализуем
override fun calculate(a: Long, b: Long): Long {
return a + b
}
// Подключение плагина к движку
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
CalculateHostApi.setUp(binding.binaryMessenger,this)
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
CalculateHostApi.setUp(binding.binaryMessenger,null)
}
}
configureFlutterEngine
в MainActivity
:flutterEngine.plugins.add(Calculate())
Для iOS необходимо внести изменения в файл
AppDelegate.swift
, проставить CalculateHostAp
i в наследники и вызвать CalculateHostApiSetup
в функции application
:let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
CalculateHostApiSetup.setUp(
binaryMessenger: controller.binaryMessenger,
api: self
)
И в этом же классе реализуем функционал нашего плагина:
func calculate(a: Int64, b: Int64) -> Int64{
return a + b}
Тем самым мы реализовали Platform Channel с помощью Pigeon в нашем приложении.
Делитесь в чате, пробовали ли вы Pigeon для своих Platform Channels?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥4❤1
Hola, Amigos! Снова вещаем о Flutter на классных мероприятиях и зовем вас присоединиться! В этот раз выступим на конференции CrossConf по кроссплатформенной разработке и трендам IT, которая пройдет в Москве 8 ноября🔥
Конференция состоит из нескольких потоков:
- Crossplatform / Ecosystem
- Flutter
- Kotlin
- Product & Design
- Management
Павел Гершевич, Flutter Team Lead в Amiga, выступит с докладом «UI логгера на Flutter: Как сделать работу с логами удобнее и быстрее?».
В своем выступлении он расскажет о Dev Screen, зачем он нужен и как его внедрять, а также о том, как эффективно с ним работать при релизе приложения. Доклад будет особенно полезен Flutter-разработчикам.
Программа лежит по ссылке, а мы ждем вас 8 ноября в 12:45 во втором зале!
Конференция состоит из нескольких потоков:
- Crossplatform / Ecosystem
- Flutter
- Kotlin
- Product & Design
- Management
Павел Гершевич, Flutter Team Lead в Amiga, выступит с докладом «UI логгера на Flutter: Как сделать работу с логами удобнее и быстрее?».
В своем выступлении он расскажет о Dev Screen, зачем он нужен и как его внедрять, а также о том, как эффективно с ним работать при релизе приложения. Доклад будет особенно полезен Flutter-разработчикам.
Программа лежит по ссылке, а мы ждем вас 8 ноября в 12:45 во втором зале!
🔥11❤2👍2
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. В прошлом году мы уже знакомили вас с нашей командой и рассказывали об их пути во Flutter, но время идет и команда меняется, поэтому возвращаем рубрику о наших классных разработчиках! Начнем, конечно же, с меня🔥
Я познакомился с Flutter в далеком 2018, когда он был еще в Alpha-версии. До него и параллельно с ним я работал с нативным Android на Java и Kotlin, попутно переместившись из мобильной разработки на Web, где занимался React.js. Тогда не было особо источников для расширения знаний о фреймворке, поэтому учился по официальной документации и YouTube-каналу Flutter. Уже позже я познакомился с тем, что начало появляться в сети, и сейчас продолжаю следить за YouTube, Medium, VC и Habr. Еще слушаю доклады на конференциях и общаюсь со спикерами на совместных ивентах — это всегда прокачивает хард-скиллы.
В свободное время я не только выступаю на крупных конференциях — DUMP, CodeFest, Mobius и других — но и веду занятия по мобильной разработке у студентов крупнейшего ВУЗа Сибири - Сибирского Федерального Университета.
Для тех, кто только начинает свой путь с Dart и Flutter, могу посоветовать:
Курс LazyLoad Dart & Flutter;
Книгу «Основы Dart»;
Конечно же, дождаться выхода книги «Основы Flutter».
Желаю вам успешного профессионального роста! Не забывайте приходить в чат, если возникают вопросы или трудности, я всегда буду рад поделиться опытом и помочь!
Я познакомился с Flutter в далеком 2018, когда он был еще в Alpha-версии. До него и параллельно с ним я работал с нативным Android на Java и Kotlin, попутно переместившись из мобильной разработки на Web, где занимался React.js. Тогда не было особо источников для расширения знаний о фреймворке, поэтому учился по официальной документации и YouTube-каналу Flutter. Уже позже я познакомился с тем, что начало появляться в сети, и сейчас продолжаю следить за YouTube, Medium, VC и Habr. Еще слушаю доклады на конференциях и общаюсь со спикерами на совместных ивентах — это всегда прокачивает хард-скиллы.
В свободное время я не только выступаю на крупных конференциях — DUMP, CodeFest, Mobius и других — но и веду занятия по мобильной разработке у студентов крупнейшего ВУЗа Сибири - Сибирского Федерального Университета.
Для тех, кто только начинает свой путь с Dart и Flutter, могу посоветовать:
Курс LazyLoad Dart & Flutter;
Книгу «Основы Dart»;
Конечно же, дождаться выхода книги «Основы Flutter».
Желаю вам успешного профессионального роста! Не забывайте приходить в чат, если возникают вопросы или трудности, я всегда буду рад поделиться опытом и помочь!
🔥13👏4❤3
Дайджест октября
Hola, Amigos! Собрали в одну подборку все полезные посты и статьи октября, которые вы могли пропустить. Выбирайте, что вам интересно, и переходите по ссылкам.
⚪️ Базовые концепции пакета rxdart. Часть 1
⚪️ Базовые концепции пакета rxdart. Часть 2
⚪️ Инструмент Dart FFI
🔴 Запись доклада «Логирование на Flutter или какие метрики помогут в оптимизации»
⚪️ Platform Channels
⚪️ Pigeon для Platform Channels
⚪️ Команда Flutter. Павел Гершевич
Всем хорошего кода!🙂
Hola, Amigos! Собрали в одну подборку все полезные посты и статьи октября, которые вы могли пропустить. Выбирайте, что вам интересно, и переходите по ссылкам.
Всем хорошего кода!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3🔥3⚡2
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. Сегодня поговорим про то, как мы работаем с сетевыми запросами, а именно об одной из библиотек, которая нам это облегчает - Chopper.
Chopper уже достаточно давно существует и был создан как аналог библиотеки Retrofit, которая активно используется на Android. Он использует генерацию кода для упрощения работы с HTTP-клиентом.
Для использования Chopper, необходимо создать сервисы для работы с Rest API:
Также необходимо создать класс самого клиента:
Также для общей логики всех запросов можно использовать
Для прерывания запроса, например, с отсутствующим интернетом, можно просто выбросить исключение. При этом его нужно будет поймать и обработать в коде.
Chopper уже достаточно давно существует и был создан как аналог библиотеки Retrofit, которая активно используется на Android. Он использует генерацию кода для упрощения работы с HTTP-клиентом.
Для использования Chopper, необходимо создать сервисы для работы с Rest API:
part "my_service.chopper.dart";
@ChopperApi(baseUrl: "/todos")
abstract class MyService extends ChopperService {
static MyService create([ChopperClient? client]) =>
_$MyServiceService(client);
@Get()
Future<List<Todo>> getTodos();
@Post()
Future<void> addTodo({
@Body Map<String,dynamic> body,
});
}
Также необходимо создать класс самого клиента:
final chopper = ChopperClient(
baseUrl: "https://example.com/api",
services: [
MyService .service,
],
interceptor: [
MyInterceptor(),
],
);
Также для общей логики всех запросов можно использовать
Interceptor
, аналог middleware на Backend. В Chopper существует Request
и Response
Interceptor
’ы. class HeaderInterceptor extends RequestInterceptor{
@override
FutureOr<Request> onRequest(Request request)async {
return request.copyWith(
headers: {
…request.headers,
‘my_header’: ‘abc’
},
);
}
}
Для прерывания запроса, например, с отсутствующим интернетом, можно просто выбросить исключение. При этом его нужно будет поймать и обработать в коде.
🔥7🥰4❤2👍1
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga. В прошлый раз мы рассмотрели Chopper, аналог Retrofit для нативного Android, теперь же посмотрим на пакет Retrofit, работающий на схожих принципах.
Retrofit под капотом использует Dio - пакет для взаимодействия с сетью. Для начала работы нам нужно создать абстрактный класс, из которого будет сгенерирован код для запросов к API:
Для создания общей логики обработки запросов используется класс
Чтобы отменить запрос, например, если у пользователя пропало интернет-соединение, нужно сделать это в методе
И для использования нашего сервиса необходимо передать в него Dio:
Делитесь в чате, что вы используете - Chopper или Retrofit?
Retrofit под капотом использует Dio - пакет для взаимодействия с сетью. Для начала работы нам нужно создать абстрактный класс, из которого будет сгенерирован код для запросов к API:
part "my_service.g.dart";
@RestApi()
abstract class MyService {
factory MyService (Dio dio) = _MyService;
@GET('/todos')
Future<List<Todo>> getTodos();
@Post(‘/todos’)
Future<void> addTodo({
@Body required CreateTodoBody body,
});
}
Для создания общей логики обработки запросов используется класс
Interceptor
с методами onRequest
, onResponse
и onError
, который обрабатывает запросы, ответы и ошибки. Лучше использовать разные интерсепторы для различной логики вместо создания одного для обработки всего и сразу.Чтобы отменить запрос, например, если у пользователя пропало интернет-соединение, нужно сделать это в методе
onRequest
:return handler.reject(MyException(),requestOptions: options);
И для использования нашего сервиса необходимо передать в него Dio:
Dio dio = Dio();
dio.options.baseUrl = ‘https://example.com/api’;
final client = MyService(dio);
await client.getTodos();
Делитесь в чате, что вы используете - Chopper или Retrofit?
🔥5⚡3❤🔥3
Hola, Amigos! На связи Михаил Чернецов, Flutter dev в Amiga, и Павел Гершевич, Mobile Team Lead в Amiga. Недавно мы рассматривали два пакета Chopper и Retrofit, сегодня разберемся с их преимуществами и недостатками.
Chopper
🦋 В преимущества использования Chopper можно записать более простую, по сравнению с Retrofit, обработку ошибок, так как он под капотом использует пакет
🦋 Из коробки есть готовые интерсепторы для логирования запросов к API.
🦋 Chopper используется достаточно популярной библиотекой
🦋 В минусы ему можно записать то, что нельзя обозначить тип возвращаемых данных в самом сервисе заранее, а нужно писать собственный конвертер
Retrofit
🦋 У Retrofit уже встроена поддержка парсинга
🦋 Retrofit использует
🦋 Но работа с
🦋 Также мы не можем добавить свой собственный
Делитесь в чате, что используете на своих проектах. Chopper или Retrofit?
Chopper
http
, а не dio
.swagger_dart_code_generator
, которая помогает нам практически не писать код для работы с сетью, а использовать для генерации Swagger
.JSON
, из-за чего могут попадаться ошибки при парсинге.Retrofit
JSON
из коробки, которую можно также вынести в отдельные изоляты.Dio
, для которого существует большое количество дополнительных пакетов - от логирования (pretty_dio_logger
) и провайдера для изображений (dio_image_provider
) до кеширования (dio_cache_interceptor
), работы с cookies (dio_cookie_manager
) и обеспечения безопасности через SSL Pinning (http_certificate_pinning
).Dio
делает немного сложнее добавление своих интерсепторов, так как dio имеет более комплексную логику обработки.JSON
конвертер к Retrofit, и приходится дополнять код необходимыми работами по созданию моделей, которые не будут использоваться в логике приложения. Этот подход все равно будет надежнее, так как мы избежим ошибок при парсинге.Делитесь в чате, что используете на своих проектах. Chopper или Retrofit?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤4🔥3💩2
Hola, Amigos! На связи Flutter-команда агентства продуктовой разработки Amiga.
Раскрываем карты! Несколько месяцев мы держали в секрете одну разработку — это наша собственная библиотека для помощи в разработке и тестировании - amiga_dev_screen. Она предоставляет возможности для логирования ошибок, кастомных событий и запросов к API, а также с ее помощью можно менять окружение и добавлять прокси для использования с снифферами🔥
Сегодня мы подробно рассказали о ней на конференции CrossConf. Чтобы узнать подробнее о других решениях, ожидайте запись с выступления, она будет скоро.
Сейчас библиотека проходит финальные этапы доработки — релиз будет в декабре этого года.
Делитесь в чате, ждете ли вы выход библиотеки?
Раскрываем карты! Несколько месяцев мы держали в секрете одну разработку — это наша собственная библиотека для помощи в разработке и тестировании - amiga_dev_screen. Она предоставляет возможности для логирования ошибок, кастомных событий и запросов к API, а также с ее помощью можно менять окружение и добавлять прокси для использования с снифферами🔥
Сегодня мы подробно рассказали о ней на конференции CrossConf. Чтобы узнать подробнее о других решениях, ожидайте запись с выступления, она будет скоро.
Сейчас библиотека проходит финальные этапы доработки — релиз будет в декабре этого года.
Делитесь в чате, ждете ли вы выход библиотеки?
❤10👍4🔥4🤔1
CrossConf 2024
Hola, Amigos! С радостью делимся результатами крупнейшей ежегодной конференции по кроссплатформенной разработке и последним трендам в IT!
Мы заняли 3 место в номинации «Лучший материал» со статьей Александра Чаплыгина «Камера и Flutter». Если еще не читали, то можете исправить это по ссылке
И 2 место в номинации «Лучшая компания-просветитель в сфере кроссплатформенных технологий», в том числе благодаря нашему каналу Flutter.Много.
Спасибо, что читаете и поддерживаете нас! ❤️ Без вас этой победы бы не было. Будем и дальше делиться с вами полезными материалами и новыми событиями. Оставайтесь с нами!
Hola, Amigos! С радостью делимся результатами крупнейшей ежегодной конференции по кроссплатформенной разработке и последним трендам в IT!
Мы заняли 3 место в номинации «Лучший материал» со статьей Александра Чаплыгина «Камера и Flutter». Если еще не читали, то можете исправить это по ссылке
И 2 место в номинации «Лучшая компания-просветитель в сфере кроссплатформенных технологий», в том числе благодаря нашему каналу Flutter.Много.
Спасибо, что читаете и поддерживаете нас! ❤️ Без вас этой победы бы не было. Будем и дальше делиться с вами полезными материалами и новыми событиями. Оставайтесь с нами!
❤14🔥8👏6👍2
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Сегодня мы рассмотрим 3 способа хранения ключей и различных переменных, которые зависят от окружения.
1. Использовать библиотеку flutter_dotenv. Для этого требуется создать файл
И добавить его в
Этот способ рабочий, но не очень безопасный, так как добавляет файл в сборку. Плюс нам нужно будет делать дополнительные изменения в проекте.
2. Использовать функционал Dart define:
И потом получать в нужном месте через
Но данный способ не подойдет, если у вас много переменных.
3. Использовать Dart define from file. Для этого требуется создать файл с расширением
И потом запустить приложение с командой:
Делитесь в чате, как вы храните такие переменные?
1. Использовать библиотеку flutter_dotenv. Для этого требуется создать файл
.env
в корне проекта:
MY_VAR=”MY VALUE”
И добавить его в
assets
в pubspec.yaml
assets:
.env
Этот способ рабочий, но не очень безопасный, так как добавляет файл в сборку. Плюс нам нужно будет делать дополнительные изменения в проекте.
2. Использовать функционал Dart define:
flutter run --dart-define=MY_VAR=’MY VALUE’
И потом получать в нужном месте через
String.fromEnvironment(‘MY_VAR’);
bool.fromEnvironment(‘MY_SEC_VAR’);
Но данный способ не подойдет, если у вас много переменных.
3. Использовать Dart define from file. Для этого требуется создать файл с расширением
.json
в корне проекта:
{
“MY_VAR”: “MY VALUE”
}
И потом запустить приложение с командой:
flutter run --dart-define-from-file=my_env.json
Делитесь в чате, как вы храните такие переменные?
👍11❤3🥰2💩1
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Мы уже говорили про многомодульность и переменные окружения, а сегодня посмотрим на случай, когда нужно сделать изменения по нативной части или заменить что-то в приложении полностью. Например, название и иконки.
В этом нам помогут Flavors - механизм создания нескольких разных сборок из одной кодовой базы. Изначально они появились в нативных приложениях.
Зачем нам нужны Flavors?
🟡 Для разделения приложения по разным окружениям. Например, можно сделать версии для разработки, тестирования и релиза.
🟡 Для White Label приложений, где сборки различаются темами, иконками, ресурсами и переменными окружения.
🟡 Если у вашего приложения есть 2 версии - бесплатная и платная.
Что можно поменять через Flavors?
Bundle ID приложения. Например, добавить к нему суффикс, чтобы вместо
Иконку и название приложения. Это полезно, чтобы разграничить версии для разных окружений.
Переменные окружения для нативных частей. Для замены некоторых частей приложения, где это необходимо.
Тему приложения и ресурсы (assets). Для изменения внешнего вида приложения.
Давайте посмотрим, как это делается во Flutter-части наших приложений. Для начала создадим дополнительную точку входа для нашего приложения -
Далее изменим
И теперь мы можем запустить наш код:
В следующих постах мы рассмотрим как нам сделать Flavors для Android и iOS.
В этом нам помогут Flavors - механизм создания нескольких разных сборок из одной кодовой базы. Изначально они появились в нативных приложениях.
Зачем нам нужны Flavors?
Что можно поменять через Flavors?
Bundle ID приложения. Например, добавить к нему суффикс, чтобы вместо
com.sample.example
стало com.sample.example.dev
, или полностью его изменить, сделать com.myapp.example
.Иконку и название приложения. Это полезно, чтобы разграничить версии для разных окружений.
Переменные окружения для нативных частей. Для замены некоторых частей приложения, где это необходимо.
Тему приложения и ресурсы (assets). Для изменения внешнего вида приложения.
Давайте посмотрим, как это делается во Flutter-части наших приложений. Для начала создадим дополнительную точку входа для нашего приложения -
main_dev.dart
. Это полная копия нашего main.dart
, но тут мы уже можем изменять тему и любые части, которые нужно.Далее изменим
pubspec.yaml
, чтобы он добавил ресурсы, которые различаются для различных Flavors:flutter:
assets:
- assets/common/ # Для общих ресурсов
- path: assets/main
flavors:
- main
- path: assets/dev
flavors:
- dev
И теперь мы можем запустить наш код:
flutter run --flavor dev --target lib/main_dev.dart
В следующих постах мы рассмотрим как нам сделать Flavors для Android и iOS.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥5❤2🥰1
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Продолжаем разбираться с Flavors. Сегодня посмотрим, как это делается для Android.
Большую часть изменений мы будем делать в файле
Далее для замены иконки создадим папку
Получается, что одно и то же приложение при запуске через Flavor будет иметь разные иконку, название и
Делитесь в чате, использовали Flavors на Android?
Большую часть изменений мы будем делать в файле
android/app/build.gradle
, в блоке android. Давайте добавим Flavor:android {
…
flavorDimensions “default”
productFlavors {
dev {
dimension “default”
applicationIdSuffix “.dev”
resValue “string”, “app_name”, “My App Dev”
}
}
}
Далее для замены иконки создадим папку
app/src/dev
и скопируем туда папки res
из app/src/main
, которые содержат иконку, и заменим их.Получается, что одно и то же приложение при запуске через Flavor будет иметь разные иконку, название и
applicationId
.Делитесь в чате, использовали Flavors на Android?
❤12👍2🔥2
Hola, Amigos! С вами Михаил Чернецов, Flutter Dev в Amiga. Мы продолжаем рубрику о нашей команде и ее пути в мире разработки. Сегодня я расскажу немного о себе и своем опыте🔥
С Flutter я познакомился в 2021 году, когда начал писать свой дипломный проект. Сразу зацепило, насколько доступна и понятна была официальная документация. Она позволяла быстро войти в работу и буквально на практике изучать фреймворк, а большое количество обучающих материалов помогало углубиться в детали и разобраться с архитектурой приложений.
Со временем я понял, что одного Flutter иногда недостаточно. Это подтолкнуло меня изучать взаимодействие с нативными платформами, а также разбираться в backend-разработке — сейчас я постепенно осваиваю эти направления.
Из полезной литературы могу порекомендовать:
📚 «Грокаем алгоритмы» — чтобы прокачать алгоритмическое мышление.
📚 «Чистый код» — чтобы научиться писать понятный и поддерживаемый код.
Желаю всем вдохновения и успехов! 🚀
С Flutter я познакомился в 2021 году, когда начал писать свой дипломный проект. Сразу зацепило, насколько доступна и понятна была официальная документация. Она позволяла быстро войти в работу и буквально на практике изучать фреймворк, а большое количество обучающих материалов помогало углубиться в детали и разобраться с архитектурой приложений.
Со временем я понял, что одного Flutter иногда недостаточно. Это подтолкнуло меня изучать взаимодействие с нативными платформами, а также разбираться в backend-разработке — сейчас я постепенно осваиваю эти направления.
Из полезной литературы могу порекомендовать:
📚 «Грокаем алгоритмы» — чтобы прокачать алгоритмическое мышление.
📚 «Чистый код» — чтобы научиться писать понятный и поддерживаемый код.
Желаю всем вдохновения и успехов! 🚀
🔥10❤4👏3
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Продолжаем разбираться с Flavors. Сегодня посмотрим, как это делать в iOS.
Нам нужно сделать несколько шагов:
1) Создать копию Target у приложения.
2) Переименовать все схемы запуска через Runner -> Manage Schemes.
3) Дублировать конфигурации в проекте и переименовать их.
После этого мы сможем менять Bundle ID, логотип, название приложения и многое другое.
Смотрите в карточках, как это делается, и делитесь в чате, пробовали так на своих проектах?
Нам нужно сделать несколько шагов:
1) Создать копию Target у приложения.
2) Переименовать все схемы запуска через Runner -> Manage Schemes.
3) Дублировать конфигурации в проекте и переименовать их.
После этого мы сможем менять Bundle ID, логотип, название приложения и многое другое.
Смотрите в карточках, как это делается, и делитесь в чате, пробовали так на своих проектах?
👍13🔥3👏2
Hola, Amigos! На связи Михаил Чернецов, Flutter Dev в Amiga. Сегодня мы расскажем о возможности импортов во Flutter.
Классы для экспорта
Часто случается, когда при импорте нескольких файлов из одной папки увеличивается количество строк:
Вместо этого мы можем создать в этой же папке специальный файл для экспорта. Например,
Теперь подключение будет занимать всего одну строку:
Еще одна возможность, которая появляется — использовать любой класс из тех, что мы экспортировали, без необходимости импортировать их еще раз.
Ключевые слова
Наверное, вы уже видели такую запись:
Это префикс
Допустим, у нас в 2 пакетах есть класс
Также этот способ подходит, если в пакете присутствуют методы, и вы хотите знать, что они оттуда. Например, это используется при работе с пакетами
Есть еще 2 ключевых слова, которые позволяют изолировать видимость классов, методов, переменных, расширений и миксинов из импортов:
1.
2.
Пишите в чате, как вы организовываете импорты на своих проектах?
Классы для экспорта
Часто случается, когда при импорте нескольких файлов из одной папки увеличивается количество строк:
import “class_a.dart”;
import “class_b.dart”;
import “class_c.dart”;
import “class_d.dart”;
Вместо этого мы можем создать в этой же папке специальный файл для экспорта. Например,
my_imports.dart
. После чего внесем наши файлы с ключевым словом export
в начале:export “class_a.dart”;
export “class_b.dart”;
export “class_c.dart”;
export “class_d.dart”;
Теперь подключение будет занимать всего одну строку:
import “my_imports.dart”;
Еще одна возможность, которая появляется — использовать любой класс из тех, что мы экспортировали, без необходимости импортировать их еще раз.
Ключевые слова
as
, hide
и show
Наверное, вы уже видели такую запись:
import “dart:math” as math;
Это префикс
as
, который нужен, чтобы мы могли использовать зависимость вместе с другими, у которых имеются такие же классы.Допустим, у нас в 2 пакетах есть класс
MyClass
, и нам нужно использовать оба. В таком случае мы можем добавить ключевое слово as
к импортам и использовать их вместе:import 'my_package.dart' as package1;
import 'other_package.dart' as package2;
…
package1.MyClass();
package2.MyClass();
Также этот способ подходит, если в пакете присутствуют методы, и вы хотите знать, что они оттуда. Например, это используется при работе с пакетами
math
, http
и dio
.Есть еще 2 ключевых слова, которые позволяют изолировать видимость классов, методов, переменных, расширений и миксинов из импортов:
1.
hide
. Скрывает, что нам не понадобится. Например, если нам не нужен какой-то определенный класс или его имя дублируется.2.
show
. Отображает только то, что нам необходимо. Это позволяет нам использовать что-то определенное, без доступа к остальному.import “my_model.dart” hide ModelA;
import “my_sevice.dart” show MyService;
Пишите в чате, как вы организовываете импорты на своих проектах?
❤7👏6🔥4👍2
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead в Amiga. Мы уже поговорили про импорты, но вы подсказали, что есть еще пару лайфхаков, связанных с ними.
Механизм Part Of
Все наши файлы на Dart это небольшие библиотеки, но иногда они становятся настолько большими, что их хочется поделить. В этом случае можно применить ключевые слова
Этот механизм часто используется библиотеками для генерации кода. Думаю, вы видели файлы
Давайте рассмотрим как работать с данным механизмом на примере BLoC. У нас есть файл
В
И уже в файлах-частях вместо импортов будет строчка:
Таким образом эти 3 файла будут распознаваться как один и тем самым импорты мы можем писать только в
Выбор импорта в зависимости от условий
Допустим, вы делаете приложение и на мобильные платформы, и на веб, но некоторые импорты нужно менять в зависимости от платформы. Это бывает при использовании
Для этого нужно будет подготовить 3 файла — один под МП, второй под веб, третий если ни один из них не подходит. И создать третий файл для экспорта:
Импортируя уже этот файл, мы точно получим нужный нам инстанс, который будет работать.
Делитесь в чате, пробовали ли вы использовать эти 2 механики на своих проектах? И пишите, что еще хотели бы узнать, а мы соберем информацию об этом❤️
Механизм Part Of
Все наши файлы на Dart это небольшие библиотеки, но иногда они становятся настолько большими, что их хочется поделить. В этом случае можно применить ключевые слова
part
и part of
.Этот механизм часто используется библиотеками для генерации кода. Думаю, вы видели файлы
my_class.g.dart
, если такими пользуетесь.Давайте рассмотрим как работать с данным механизмом на примере BLoC. У нас есть файл
my_bloc.dart
, который будет основным, и файлы my_event.dart
и my_state.dart
, которые будут его частями.В
my_bloc.dart
мы пропишем:part ‘my_event.dart’;
part ‘my_state.dart;
И уже в файлах-частях вместо импортов будет строчка:
part of ‘my_bloc.dart’;
Таким образом эти 3 файла будут распознаваться как один и тем самым импорты мы можем писать только в
my_bloc.dart
, и он же будет импортироваться в другие файлы.Part of
имеет смысл применять, только если это неотделимые друг от друга классы. Например, события и состояния для BLoC или обработка JSON для моделей, в остальных случаях лучше использовать export.Выбор импорта в зависимости от условий
Допустим, вы делаете приложение и на мобильные платформы, и на веб, но некоторые импорты нужно менять в зависимости от платформы. Это бывает при использовании
dart:io
и dart:web
Тут к нам на выход приходит использование if
.Для этого нужно будет подготовить 3 файла — один под МП, второй под веб, третий если ни один из них не подходит. И создать третий файл для экспорта:
export ‘my_none.dart’
if (dart.library.io) ‘my_mobile.dart’
if (dart.library.js_interop) ‘my_web.dart’;
Импортируя уже этот файл, мы точно получим нужный нам инстанс, который будет работать.
Делитесь в чате, пробовали ли вы использовать эти 2 механики на своих проектах? И пишите, что еще хотели бы узнать, а мы соберем информацию об этом❤️
👍11🔥4❤2