Я работал над Hermio последние 4 с лишним месяца и на этой неделе закончил его. Это приложение для путешественников, предназначенное для самостоятельно путешествующих с рюкзаком туристов, в котором я собрал все инструменты, необходимые мне во время моих поездок.
Это автономное приложение. Пользователям не нужно создавать аккаунт. Вы запускаете его и пользуетесь им.
1. Был ли Flutter хорошим выбором?
У меня уже есть опыт работы с Flutter и Dart. Я создавал простые и сложные приложения, с бэкендом и без, для мобильных и настольных компьютеров. Я также публиковал пакеты для Flutter.
Короче говоря, я более-менее знаю, как использовать Flutter.
Я считаю, что Flutter был отличным выбором. Вы — сообщество Flutter, думаю, мне не нужно вас убеждать. Создать пользовательский интерфейс очень просто. Все компоненты, которые мне были нужны, уже были предоставлены фреймворком Flutter. Если у него нет какого-то компонента, сообщество уже опубликовало пакет для него. Для меня главный минус в том, что многие пакеты содержат некачественный код или больше не поддерживаются.
Мне не нужен ни смартфон, ни эмулятор для создания приложения. Все мои разработки ведутся на десктопе. Это намного быстрее. В режиме разработки приложение запускается за 10 секунд. Я могу закрыть его, очистить кэш, и оно снова будет запущено в одно мгновение. Эмуляторы занимают много памяти и могут быть медленными, а моему смартфону потребовалась минута, чтобы запустить приложение в первый раз, и горячая перезагрузка занимает 1.5 с каждый раз.
Если мне нужно использовать какой-либо датчик, например, камеру или местоположение, я мокирую его. Если платформа Android/iOS, используйте пакет “location”, в противном случае используйте заглушку.
Я также смог опубликовать свое приложение в App Store, хотя у меня нет ни Mac, ни iPhone. Вот это сила!
2. Моя архитектура
Прежде всего, я создал это приложение для работы в автономном режиме. Я не хочу писать бэкэнд.
Я использовал feature-first архитектуру. До этого я использовал layer-first архитектуру, и должен сказать, что первая для меня лучше. Было проще добавлять функции и следить за папками.
При использовании layer-first архитектуры я терял информацию о прогрессе и страницах через несколько недель. Также проще скопировать/вставить функцию в новый проект. Сейчас у меня есть функция «paywall», которую я могу использовать в своих новых проектах. Мне просто нужно скопировать папку.
Для управления состоянием я использую Bloc. Никаких особых причин для этого нет. Он первый, что я освоил, и я никогда не пытался использовать что-то другое. Я не большой поклонник пакетов, использующих build_runner. Он работает, и этого достаточно. Я мог бы добавить, что использовать пакет не очень сложно, но я устал от шаблонов, которые нужно писать для каждого нового Cubit/Bloc.
Все, что пользователь может скачать, хранится в Cloudflare. Это был первый раз, когда я использовал Cloudflare, и это был хороший опыт. Бесплатный тариф огромен. Я размещаю свой сайт бесплатно, и он копируется по всему миру. Мне просто нужно было связать мой репозиторий на GitHub с Cloudflare, и при каждом новом коммите Cloudflare будет редеплоить мой сайт.
Самая интересная услуга, которую они предоставляют, — это R2, сервис, похожий на S3. Я бесплатно получил около 10 ГБ в своей корзине, где могу хранить свои изображения. На ее настройку у меня ушло 20 минут.
Для обработки подписок я использую RevenueCat. Его легко настроить, а бесплатного уровня мне вполне достаточно.
Как я уже говорил в предыдущем пункте, я разрабатываю на настольном компьютере, а специальные функции (GPS-локация, покупка в приложении) тестирую на телефоне.
3. Как я решаю некоторые проблемы
Данные о валюте
Я хотел, чтобы в моем приложении был конвертер валют. Мне нужно было найти способ получения данных.
Использовать ли мне API? Нет. Я не хочу писать бэкенд, а также разворачивать его в VPS/облаке/…
Поэтому я использовал небольшой хак. В Google Sheet есть специальная функция под названием «GOOGLEFINANCE()». Она использует Google Finance API для получения финансовых данных. Я нашел все возможные валюты мира, поместил их в новый лист Google Sheet и с помощью этой функции конвертировал их в доллары США.
Затем я настроил скрипт на своем ноутбуке, который будет считывать данные из этого листа и загружать CSV в мое хранилище Cloudflare каждый раз, когда я включаю свой ноутбук.
Карта с отметками
Я хотел предоставить пользователям карту, на которой они могли бы отмечать свое местоположение, чтобы у них была статистика: посещенные страны, общее расстояние…
Мне нужна карта, верно? Поскольку это все еще оффлайн-карта, я не могу использовать какой-либо крупный провайдер карт, например Google Maps или MapBox. Платить за API я тоже не хочу…
Моим решением было просто воссоздать пакет карт. Это был не очень сложный пакет. У нас есть SVG страны, мы парсим его и рисуем с помощью CustomPainter. Чтобы добавить взаимодействия, я проверяю, что `Offset` содержится в `Path`, так что я знаю, какая страна/регион была выбрана. Самое сложное — преобразовать координаты Lat/Long в картезианские координаты.
Вот моя статья, если вы хотите узнать больше.
Скриншоты для магазинов
У меня нет ни Mac, ни iPhone. Если вы уже публиковали приложение в App Store, вы знаете, что у них особые требования к скриншотам. Вы должны предоставить 4/5 комплектов скриншотов с разными размерами. Я не дизайнер, у меня нет навыков создания привлекательных скриншотов, я не хочу изучать Gimp и мне лень.
Я решил написать скрипт на Python для создания своих скриншотов. Сначала я вручную делаю скриншот своего приложения на десктопе. Затем скрипт генерирует новое изображение для каждого нужного размера. Он заливает фон красивым цветом, пишет заголовок и подзаголовок в верхней части, вставляет скриншот в изображение с белой рамкой и готово!
Генерация занимает 2 секунды, что для меня очень хорошо.
Для предыдущего приложения я написал похожий скрипт, который генерировал скриншоты для каждой локализации и загружал их прямо в магазины. Я должен переписать его.
Публикация в App Store
Делаю с помощью CodeMagic. Он создает конвейер для создания вашего кода на Mac и загрузки его в App Store. Чтобы включить функцию покупки в приложении, мне нужно было использовать Xcode, поэтому я запустил виртуальную машину MacOS, загрузил Xcode и включил функцию покупки в приложении.
4. Пакеты Flutter
Иногда быстрее создать новый пакет. Думаю, я был прав, написав свой пакет interactive_country_map. Он подходит для моих целей, и у меня есть идеи новых приложений, где этот пакет будет очень полезен.
Некоторые пакеты, которые я использовал, больше не поддерживаются или поддерживаются очень медленно. Я открыл несколько PR, но думаю, что лучше сделать новый пакет.
Мне также хотелось бы иметь другой способ работы с ассетами. Мой пакет interactive_country_map поставляется с 5 МБ SVG. Я полагаю, что некоторые люди не будут использовать ВСЕ карты стран. Например, 3.7 МБ — это только карта США…
Я также использую пакет flag. Он используется для отображения флагов. Они предоставляют 2 формата флагов «4×3» и «1×1». Мне не нужны флаги «4×3». Я не хочу, чтобы они поставлялись с моим приложением.
Пожалуйста, поправьте меня, если я ошибаюсь, но Flutter не делает treeshake активов.
Вот и все! Это было интересное путешествие, и я горжусь тем, что создал приложение, которое смогу использовать в своих будущих поездках. У меня есть еще много функций, которые я хотел бы добавить в свое приложение, так что, думаю, скучать мне не придется. Спасибо, если вы прочитали все это. Надеюсь, я написал что-то интересное.
Ссылки: