Найти тему
ИНОСТУДИО

Flutter. Учимся работать с платформозависимыми сервисами.

Оглавление

Подписывайтесь на наш канал, будьте в курсе последних новостей из мира кросс-платформенной разработки.

В прошлой статье мы разобрали по косточкам архитектуру BLoC и, надеемся, научились сносно ее готовить. Сегодня предлагаем поговорить о внедрении в проект функционала, требующего взаимодействия с платформозависимыми сервисами.

Перед тем как заняться кроссплатформенной разработкой, мы часто мучились вопросами: каким образом в таких проектах осуществляется работа с системными сервисами и компонентами? Возможна ли она вообще? Очень сложно найти приложение, которое не обращается к адресной книге, геолокации или хотя бы камере устройства. К счастью, у Flutter-сообщества есть ответы почти на все наши запросы.

Взаимодействие Dart с нативным кодом

Для начала немного теории. Flutter помогает организовать взаимодействие между Dart и нативным кодом приложения при помощи механизма PlatformChannel.

В самом простом случае на стороне Flutter создается экземпляр MethodChannel с уникальным идентификатором, после чего в этот канал отправляются сообщения с уникальными (в рамках канала) именами и при необходимости параметрами. В нативном коде регистрируются канал с аналогичным идентификатором (FlutterMethodChannel на iOS и MethodChannel на Android) и его обработчик. В обработчике нужно только прогнать имя сообщения через обычный switch и вызвать соответствующий метод, написанный на Swift/Kotlin. Результат работы метода (или nil для void функций) возвращается обратно в Dart с callback’ом. Код реализации тут.

Есть возможность и обратного взаимодействия. Для этого в нативном коде вызываем, например так.

а в Dart файле прописываем так.

Сообщения и callback’и отправляются асинхронно и не блокируют UI, однако, вызывать методы обработчика рекомендуется все же в главном потоке. Подробнее о взаимодействии Flutter и нативного кода можно почитать тут.

Как видите, имея такой удобный инструмент под рукой, не сложно реализовать обращение к системным сервисам самостоятельно. Ну, а для тех, кто не любит изобретать велосипеды, мы приготовили подборку удобных библиотек, которые помогут сэкономить потраченное на разработку время.

Запрашиваем разрешение у пользователя

Итак, первым делом нам понадобится запросить у пользователя разрешение на использование того или иного ресурса системы. Одной из наиболее удобных библиотек для этого является permission_handler.

Нужно только не забыть указать user-friendly текст запроса в Info.plist файле iOS-приложения и прописать необходимое разрешение в файле AndroidManifest. После этого останется вызвать метод requestPermissions и обработать результат. Приятным бонусом станет возможность отправить пользователя в Настройки устройства, чтобы открыть приложению доступ к тому или иному системному сервису.

Правда, и здесь iOS-разработчик может попасть впросак. Шутка заключается в том, что при первом запуске на iPhone библиотека выдаст статус unknown, а на Android-устройстве — сразу denied. И Android-разработчиков это не остановит. Они продолжат выпрашивать у пользователя разрешение, пока тот не пометит галочкой опцию «Не спрашивать больше» (проверить это можно при помощи метода библиотеки shouldShowRequestPermissionRationale). Поэтому, определяя, запрашивается ли разрешение впервые, придется полагаться на флаг, вручную добавленный в SharedPreferenses (Flutter-аналог «яблочного» UserDefaults). Код реализации тут.

Итак, разрешение получено, пора за дело.

Надежные помощники. Адресная книга

Однажды нам понадобилось получить список контактов из адресной книги устройства. Здесь хорошим подспорьем стала библиотека contacts_service. Она позволяет получать контакты из адресной книги, добавлять, редактировать и удалять записи, отдельно вытаскивать аватарки и фильтровать контакты.

Для каждого профиля доступны идентификатор, имя, данные о компании и должности, адрес, телефоны, email адреса, аватар.

Надежные помощники. Календарь

А если нужно поработать с системными календарями, на помощь придет device_calendar. Эта удобная библиотека умеет и разрешение у пользователя спросить, и со списком доступных календарей управиться, определив при этом, в какие из них допускается запись, а в каких — только чтение, и событие ваше сохранить, отредактировать или удалить. Для каждого события необходимо указать идентификатор календаря, название, дату начала и окончания. В нагрузку можно добавить описание, адрес проведения, организатора и участников, правило повторения и напоминание. При создании события библиотека отдает его идентификатор, используя который можно редактировать и удалять события.

Надежные помощники. Камера и галерея

Для работы с камерой и галереей устройства рекомендуем библиотеку image_picker. Несмотря на то, что работа над ней еще в самом разгаре, текущая версия порадует пользователей привычным системным интерфейсом, а программистов — минимумом необходимых для интеграции усилий. По сути, после добавления в Info.plist необходимых разрешений понадобится только вызвать.

Или, соответственно так.

Стоит обратить внимание, что при выборе изображения мы получаем путь к файлу, использовать который в виджете можно следующим образом.

6. Надежные помощники. Видео плеер

Чтобы проиграть видео-файл, советуем обратиться к video_player. Библиотека «под капотом» опирается AVPlayer для iOS и ExoPlayer для Android, но формат видео лучше выбрать популярный, чтобы обе платформы сумели его потянуть. Важно учесть, что плеер не разворачивается автоматически на весь экран, его придется руками добавлять в иерархию виджетов. А если понадобится повернуть видео в landscape, просто заверните плейер в виджет RotatedBox.

7. Добавляем плагин запуска URL

Если появится желание открыть браузер или почтовый клиент, сделать звонок или отправить смс, обратите внимание на url_launcher. Эта простая библиотечка поможет проверить, возможна ли необходимая операция (сложно будет позвонить кому-то с планшета или отправить письмо с iOS-устройства, если системный почтовый клиент не настроен), а также выполнит ее.

А еще можно открыть веб-сайт.

Что дальше?

Итак, оказывается, работа с системными сервисами во Flutter пугает только на первый взгляд. В следующей статье мы посмотрим, как отправить ваши тестовые сборки с помощью сервиса Firebase, и какие подводные камни могут поджидать вас в этом, казалось бы, несложном деле.

Автор статьи Евгения Слепцова, iOS/Flutter-разработчик компании INOSTUDIO.

Подписывайтесь на наш канал, будьте в курсе последних новостей из мира кросс-платформенной разработки.

Это адаптация статьи, изначально опубликованной в блоге INOSTUDIO.