Jump to content

Yaroslav Brovin

Administrators
  • Posts

    2,567
  • Joined

  • Last visited

  • Days Won

    647

Blog Entries posted by Yaroslav Brovin

  1. Yaroslav Brovin
    В эту среду совместно с компанией Embarcadero проводим вебинар посвященный разработке мобильного приложения с использованием FGX Native. На вебинаре разберем одну из возможных архитектур мобильного приложения, применим шаблон MVVM для построения экранов. И познакомимся с приемами создания мобильных интерфейсов с FGX Native. 
    Когда: 23 июня 2021 в 12:00 МСК Язык: русский Заголовок: Примеры использования библиотеки FGX Native для создания макетов реальных мобильных приложений. Ссылка на регистрацию: https://lp.embarcadero.com/fgx-native Анонс: 
  2. Yaroslav Brovin
    В этот вторник совместно с компанией Embarcadero проводим вебинар посвященный разработке мобильного приложения с использованием FGX Native. На вебинаре разберем приемы верстки экранов мобильного приложения и одну из возможных примеров системы навигации между экранами.
    В качестве примера создаем прототип мобильного приложения, позволяющего выработать полезные привычки.
    Когда: 31 мая 2022 в 12:00 МСК Язык: русский Заголовок: Создание популярного мобильного приложения с FGX Native Ссылка на регистрацию: https://lp.embarcadero.com/fgx-native  
  3. Yaroslav Brovin

    Общая
    Hello Delphi developers,
    Black Friday is very soon and we want to please you with a good discount on new FGX Native licenses, which will be valid between 11-15 November 2023.
    Discount for English version - 150$. When placing an order, use the promo code BLACKFRIDAY2023 here. Discount for Russian version - 2000₽. Thank you and have a good shopping,
    FGX Native team
  4. Yaroslav Brovin

    Общая
    Hello Delphi developers,
    In honor of the New Year and Christmas, we are pleased to offer our future customers discounts on the purchase of FGX Native licenses, which will be valid until 15 January 2023.
    Discount for English version - 100$. When placing an order, use the promo code HAPPY2023 here. Discount for Russian version - 1500₽. Also we are anounncing 6 and 12 months subscriptions for Russian version. You can read the rates here. Thank you and happy holidays
  5. Yaroslav Brovin
    и 
    Что связывает итальянскую конференцию DelphiDay по Delphi и FGX Native?
    Правильно! В ближайшие дни FGX Native будет представлена на одной из крупнейших Delphi конференций Европы в Италии, на родине Марко Канту. Это очень важный шаг в истории развития проекта, потому как библиотека постепенно выходит на международный уровень. Возможностью рассказать о себе широкому кругу иностранных разработчиков мы обязаны нашему клиенту из Италии @claudio.piffer, который сам проявил инициативу и подготовил интереснейшую презентацию о  FGX Native. В данной презентации  Клаудио расскажет о главных возможностях библиотеки и поделится своими впечатлениями об её использовании. 
    От всего сердца желаем Клаудио удачи и с нетерпением ждём его выступления.
    Ниже опубликована вся информация о конференции.
    P.S. Выступление будет на итальянском.
    Когда: 11 июня 12:30 (по московскому времени) Программа конференции: https://www.delphiday.it/ Язык: итальянский Заголовок: FGX Native: мобильная альтернатива FMX Спикер: @claudio.piffer  Анонс:
  6. Yaroslav Brovin
    Добрый день!
    Рады с вами поделиться будущим выступлением по FGX Native на крупнейшей Итальянской конференции по Delphi в 2022 году. Конференция пройдет 21-23 июня 2022 года. Позже будет детальная информация о выступлении.
    https://www.delphiday.it/
     
  7. Yaroslav Brovin
    Добрый день пользователи FGX Native.
    Сегодня мы хотим рассказать про переход Android части библиотеки FGX Native на AndroidX. О том, что это, зачем это нужно и как это влияет на разработчиков мы поговорим в этой статье.
    Что такое AndroidX?

    Среди всех проблем Android - наверное, главной для разработчика является проблема адаптации мобильного приложения под все версии Android. Очень часто, в старых версиях Android просто невозможно реализовать тот или иной функционал, потому что операционная система не предоставляет для этого API. С выпуском новых версий, постепенно Google добавляет пропущенное API. Однако, при использовании такового, вы не можете запустить такое приложение на старых версиях Android, потому что оно просто упадет из-за отсутствия нужного API. Поэтому разработчикам нужно иногда писать по две реализации одного и того же функционала на разном API.
    Для того, чтобы это решить, Google стала выпускать набор библиотек, которые содержат универсальное API, работающее на всех версиях Android. Такая библиотека раньше называлась Android Google Support Library, а затем Google объявила ее устаревшей и заменил ее на новую AndroidX.
    AndroidX - Это набор библиотек от Google, в которых они расширяют стандартные скудные возможности Android и дают широкий набор нового функционала, доступный среди всех версий Android. Она включает в себя большое число разных библиотеки, начиная от реализации базовых компонентов Android OS, продолжая облегченной работой с камерой и заканчивая продвинутыми компонентами Material Design. 
    До версии FGX Native 1.15.0.0 используется "Android Google Support Library".
    Зачем переходить на AndroidX?
    Главная необходимость заключается в том, что многие другие современные сторонние библиотеки Android уже используют AndroidX. Например, Firebase, AdMob, Google Maps и тд. А это значит, что если мы хотим добавить новый функционал в TfgMap из свежих версий GoogleMap или добавить возможность отправки push-уведомления с картинкой из Firebase, то мы не сможем это сделать, пока не перейдем на AndroidX.
    Помимо внутренних потребностей для развития FGX Native на Android платформе нужно не забывать, что разработчик с FGX Native может использовать сторонние jar библиотеки, сгенерировать для них заголовочные файлы при помощи Java2Delphi утилиты (входит в поставку FGX Native) и использовать в вашем приложении вами любимый язык Delphi. Будь-то "Яндекс.AppMetrica" или WebRTC компоненты или UI компоненты, рисующие графики, FGX Native позволяет это сделать. Однако, опять же многие новые свежие версии сторонних Android библиотек уже используют AndroidX. А это значит, что их нельзя использовать, пока нет поддержки AndroidX.
    Почему переход на AndroidX не был выполнен ранее?
    Как уже было сказано ранее FGX Native до 1.15.0.0 использует "Android Google Support Library". И эта библиотека считается официально устаревшей с Июля 2017. Так почему же, мы до сих пор используем устаревшую версию?
    Перед тем, как ответить на этот вопрос, познакомимся, что технически означает "добавление Android библиотеки в приложение". Упрощенно, FGX Native Android приложение состоит из четырех частей:
    "SO-Библиотека" с нативным кодом вашего приложения. Это именно то, что получается в результате компиляции ваших форм, модулей и тд. "classes.dex" - Это байт код, который является стартовым для любого Android приложения. Именно эта часть загружает делфи библиотеку и передает ей управление. "Набор ресурсов" - иконки приложения, заставки, графические ресурсы, ассеты, шрифты, ресурсы локализации и тд, все то, что доступно для вашего приложения. "Манифест приложения" - это по сути описание содержимого вашего приложения, что оно может делать, а что нет. Именно он является определяющим файлом на предмет выдачи прав доступа, запуска других приложений и тд. Все это упаковывается и на выходе вы получаете пакет приложения APK или более сложный формат AAB.
    Android библиотека по сути имеет практически такое же содержание, как и Android приложение. Оно так же может иметь в своем составе нативные библиотеки, наборы ресурсов, манифест или же байт-код в jar-библиотеке.
    Поэтому чтобы добавить Android-библиотеку в приложение, необходимо все, что есть в библиотеке добавить в приложение. И выполнить хитрые манипуляции по совмещению данных из разных библиотеки (сливание манифестов, компиляция ресурсов, слияние байт кода в один classes.dex.
    Ресурсы, манифесты
    Так вот причина задержки в переходе на AndroidX кроется в механизме поддержки Android библиотек на уровне RAD Studio/Delphi. Добавление сторонних jar библиотек всегда было частью системы сборки Delphi, в которой мы увы не можем менять со стороны. Поддержка Android библиотек в Delphi ограничивается только добавлением байт кода в итоговый classes.dex. А это значит, что Delphi не умела и до сих пор не умеет сливать манифесты, добавлять  и компилировать ресурсы, внедрять so-библиотеки автоматически и тд. Поэтому круг использования сторонних Android библиотек в Delphi довольно узкий - это библиотеки, которые не используют ресурсы и по части не работают с UI. Как вы понимаете, таких библиотек в мире Android довольно мало. Потому что даже обычная не UI библиотека выделяет строковые ресурсы в "набор ресурсов" для возможности локализации разработчиком.
    Поэтому, чтобы выполнить миграцию на AndroidX нужно вначале реализовать полноценную поддержку Android-библиотек в Delphi. Поскольку это часть системы сборки Delphi, у нас нет возможностей для внесения изменений в не наш код. Осложняется еще и тем, что Delphi Deployment Manager заточен только на FMX и не любит никаких отклонений от "нормы" FireMonkey приложения. Поэтому IDE всячески пытается удалить, изменить, обновить элементы "Deployment Manager" и сводит практически на нет любые кастомизации.
    AndroidX является набором огромного количества маленьких библиотек, каждая из которых содержит свой набор ресурсов (изображения, стили, локализации, файлы настроек и тд). И именно по этому на нее не возможно перейти даже обходными путями.
    К сожалению, за прошедшие 5 лет выпуска Delphi больших изменений в области деплоя и сборки для Android не было. Главным изменением можно считать добавление поддержки MultiDex в Delphi 11.
    MultiDex и Delphi 11
    Если на пальцах объяснить, что такое MultiDex, то когда байт код из разных Android библиотек сливается в classes.dex, то может возникнуть ситуация, что все не влезает в один файл (ограничение накладывается на общее количество типов, методов и т.п., которое может поместиться в одном файле. Это связано с архитектурой выполнения байт кода в Android). Когда все не помещается в один файл, то остальное помещается в следующий файл classes2.dex и так далее, пока все не будет раскинуто по файлам. В этом случае apk содержит ни один classes.dex, а не сколько. И именно поддержка этого добавлена в Delphi 11. 
    По умолчанию, и FireMonkey и FGX Native приложение помещается в один classes.dex. Другими словами, прямой необходимости в поддержки MultiDex не требуется. Однако, чем больше сторонних Android библиотек вы используете, тем быстрее растет classes.dex и тем проще выйти за пределы SingleDex и перейти в MultiDex. 
    AndroidX вводит большое число зависимых библиотек, поэтому добавление AndroidX также автоматически добавляет необходимость использовать MultiDex. И если в Delphi 11, такая поддержка есть. То пользователям старых версий Delphi делать в этом случае уже нечего. Поскольку мы считаем, что разработчики не должны быть сильно привязаны к версии IDE при использовании нашего продукта, мы не могли и не можем отказаться от поддержки старых Delphi до 11 версии.
    Delphi 11 и FireMonkey поддерживает же AndroidX, в чем секрет?
    "Delphi 11 официально же использует AndroidX" - значит ли это, что проблем никаких нет? На самом деле, поддержка заканчивается только на уровне интеграции байт-кода в приложение. О чем я упомянул в предыдущем разделе. Это значит, что Delphi просто внедряет исполняемый байт код в приложение и так же не поставляет никакие ресурсы в FMX приложение. Как это отражается на приложении. Как только выполнение вашего приложения попробует обратиться к несуществующим ресурсам, то в этот момент оно может либо упасть, либо работать некорректно. Так же FMX содержит не весь AndroidX, а только минимально-необходимый набор библиотек. По большей части FMX минимально использует Android API, поэтому вы можете не наблюдать проблем с отсутствующими ресурсами. Однако, как только вы сделаете шаг в сторону и захотите расширить возможности добавлением Android-библиотеки, то вы поймете, что все использование ограничено и приложение не будет работать.
    Почему теперь переход на AndroidX стал возможен?
    Возможно, Embarcadero в будущем добавит полноценную поддержку Android-библиотек. Но пока ее нет, нам ничего не остается, как заменить систему сборки Android приложений на другую и добавить полноценную поддержку использования Android-библиотек. Последнее время мы плотно занимались этой работой. В результате чего мы полностью перешли с системы сборки Android приложения в Delphi на другую с полноценной поддержкой Android-библиотек. Данную поддержку вы увидите в обновлении 1.15.0.0. Подробности перехода на новую систему сборки будут рассказаны в следующей статье. Однако, новая сборка помимо полноценной поддержки Android-библиотек так же значительно ускоряет запуск приложения на устройстве (даже при условии деплоя ресурсов) и дает эти возможности на любой версии Delphi. Это значит, что клиенты любых поддерживаемых версий Delphi, не зависимо от IDE получат все возможности по сборке приложений, включая MultiDex и добавление Android-библиотеки.  
    Что дает нам AndroidX?
    Android 13 и новее
    Переход на последнюю версию AndroidX дает нам полноценную поддержки последних версий Android. Начиная с версии FGX Native 1.15.0.0 все приложения будут нацелены на Android 13 (Api Level = 33). Все заголовочные файлы так же будут обновлены до Android 13. Старые заголовочные с классами "Support Library" будут удалены.
    Material Components
    Помимо этого, теперь мы можем полноценно использовать компоненты из Material Design. И в будущем теперь нас ничто не сдерживает от добавления продвинутых различных реализаций вкладок, chips и т.д.
    Firebase
    Поддержка последней версии Firebase, работающая на всех поддерживаемых версиях Андроида без проблем. Возможность передавать изображение в push-сообщениях.

    Сканер штрихкодов
    Обновленная реализация сканера штрихкодов, которая работает быстрее, стабильнее и лучше.
    Карты GoogleMap
    Поддержка свежих версий карт.
    Реклама AdMob
    Использование последних версий площадки по размещению рекламы.
    Прочее
    Обновление Yandex.AppMetrica, Google SignIn, Billing, InAppPurchase и тд.
    Что делать, если я не все понял в этой статье?
    Не расстраиваться! FGX Native команда делает все, чтобы вам не нужно было знать обо всем этом и вы могли сконцентрироваться на решении своих задач. Однако, нам приятно поделиться с вами действительно важными изменениями в FGX Native, которые позволят нашему продукту стать еще шире и добавить еще больше новых возможностей. У нас большой опыт в этой области, который позволяет нам реализовывать практически любые идеи. 
    Всем спасибо за внимание!
  8. Yaroslav Brovin
    Добрый вечер,
    Начиная с FGX Native 1.15.3.0, появится новый компонент для сборка аналитики использования вашего приложения TfgFirebaseAnalytics.

    Данный компонент позволяет собрать информацию об использовании вашего приложения пользователями. Например, вы можете определить:
    Какую форму пользователи открывают чаще всего. Какие версии вашего приложения успешно запускаются. Сколько пользователей первый раз запустили приложение. Какие покупки чаще всего делают в вашем приложении. С какими компонентами чаще всего взаимодействуют.  И многое другое. Подробности о Firebase Analytics: https://firebase.google.com/docs/analytics?authuser=0
    Настройка использования
    Чтобы использовать новый компонент, необходимо выполнить общую регистрацию FGX Native приложения в Firebase консоли (Шаги такие же, как регистрация приложения для использования Push-уведомлений): 
    Настройка Firebase для iOS. Настройка Firebase для Android. Дополнительно для Android нужно вручную добавить зависимость на библиотеку "com.google.firebase:firebase-analytics:21.2.0"
    https://forum.fgx-native.com/blogs/entry/56-интеграция-android-библиотек-просто-и-быстро-с-11520/

    Если вы не выполните корректную настройку приложения, то на iOS запуск приложения закончится ошибкой старта, а в Android ни одна метрика не будет отправлена в облако Firebase. 
    Отправка событий
    Чтобы начать отправку событий необходимо разместить новый компонент TfgFirebaseAnalytics. Рекомендуем разместить его на общем дата модуле, чтобы вы могли пользоваться одним экземпляром компонента в любом месте. Однако, вы можете использовать и несколько экземпляров данного компонента.
    Как только вы размещаете его в приложении, так сразу компонент начинает автоматический сбор базовых событий в вашем iOS/Android приложении, такие как:
    Определение первого запуска приложения Статистику использования разных версий вашего приложения. Сбор сессий использования.  И тд. Такие события доступны в консоли Firebase в разделе Analytics -> Realtime.

    Помимо автоматического сбора событий, вы можете выполнять отправку своих событий.
    Каждое событие, происходящее в вашем приложении, характеризуется:
    Name - имя. Строковый код события. Firebase предлагает готовые коды событий. С ними можно познакомиться на этой странице. Вы можете использовать, как готовые коды, так и свои собственные.
    Например: событие select_content предназначено для информирования о том, что пользователь выбрал важный для вас контент (нажал на кнопку, открыл форму и тд). Parameters - параметры в формате - название параметра - значение. Каждое событие может сопровождаться соответствующими параметрами. Firebase описывает связанные с событиями параметрами, которые вы можете отправить.
    Например, событие select_content сопровождается двумя параметрами: content_type и item_id (документация) Для отправки события в компоненте есть два метода, позволяющие это сделать:
    /// <summary> /// Отправляет на сервер Firebase событие с именем <c>AName</c>, параметрами c именами <c>AKeys</c> и значениями /// <c>AValues</c>. /// </summary> procedure LogEvent(const AName: string; const AKeys: TArray<string>; const AValues: array of const); overload; /// <summary>Отправляет на сервер Firebase событие с именем <c>AName</c>.</summary> procedure LogEvent(const AName: string); overload; Чтобы узнать, что пользователь нажал на кнопку покупки в вашем приложении, необходимо добавить в обработчик вызов метода LogEvent:
    procedure TFormMain.fgButtonBuyTap(Sender: TObject); begin fbAnalytics.LogEvent('select_content', ['content_type', 'item_id'], ['Button', 'Buy subscription']); end; Определение открытых экранов/форм
    Помимо отправки любых событий, компонент TfgFirebaseAnalytics позволяет отправлять информацию о том, какие формы/экраны открывает пользователь. Чтобы воспользоваться данной возможностью, необходимо в момент отображения формы передавать на сервер Firebase информацию о текущей форме.
    /// <summary> /// Задает текущее название экрана, которое определяет текущий визуальный контекст в вашем приложении. /// Это помогает определить области в вашем приложении, где пользователи проводят свое время и как они /// взаимодействуют с вашим приложением. /// </summary> procedure SetCurrentScreen(const AScreenName: string; const AScreenClassName: string); Для удобства отслеживания, когда форма появляется на переднем плане, в FGX Native 1.15.3.0 для формы TfgForm добавлены два новых события:
    /// <summary>Вызывается, когда форма выходит на передний план на экране.</summary> /// <remarks>Не вызывается для встроенных форм-фреймов.</remarks> property OnActivate: TNotifyEvent read FOnActivate write FOnActivate; /// <summary>Вызывается, когда форма уходит с переднего плана на экране.</summary> /// <remarks>Не вызывается для встроенных форм-фреймов.</remarks> property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate; Именно их мы рекомендуем использовать для указания текущего экрана в Firebase Analytics.
    Например, код по отображению главной формы может выглядеть так:
    procedure TFormMain.fgFormActivate(Sender: TObject); begin Shared.fbAnalytics.SetCurrentScreen('Main form', ClassName); end; Первым параметром указывание название экрана, вторым - класс. 
    Общие настройки
    Помимо главной задачи отправления статистики в Firebase Analyitcs, вы можете выполнять базовые настройки компонента:
    /// <summary> /// Удаляет все аналитические данные для этого приложения с устройства и сбрасывает идентификатор экземпляра приложения. /// </summary> procedure ResetAnalyticsData; /// <summary> /// Включен ли сбор аналитики для этого приложения на данном устройстве. Этот параметр сохраняется во всех сеансах /// приложения. По умолчанию он включен. /// </summary> property Enabled: Boolean read FEnabled write SetEnabled default DefaultEnabled; /// <summary>Уникальный идентификатор текущего пользователя.</summary> property UserId: string read FUserId write SetUserId; /// <summary>Задает продолжительность бездействия, которая завершает текущий сеанс.</summary> property SessionTimeoutDuration: Integer read FSessionTimeoutDuration write SetSessionTimeoutDuration default DefaultSessionTimeoutDuration; С остальными подробности использования вы можете ознакомиться в официальной документации Firebase:  https://firebase.google.com/docs/analytics?authuser=0
    Спасибо
  9. Yaroslav Brovin
    Добрый день, уважаемые разработчики.
    В этой статье мы рассмотрим настройку и использование сервиса Firebase Messaging (FCM)для приема push-уведомлений на платформе iOS.
    Начиная с версии FGX Native 1.15.2.0, вы можете использовать Firebase не только на Android, но теперь и на iOS. Тем самым не нужно выполнять дополнительные действия для конвертации токенов устройств из Apple Push Service (APS) в токен Firebase (FCM), сделав ваш код полностью кроссплатформенным.
    Перед тем, как приступить к работе с уведомлениями, необходимо выполнить регистрацию аккаунта Google.
    Регистрация приложения в Firebase для iOS
    1. Откройте Firebase Console и выполните вход в учетную запись Google. 
    2. Нажмите кнопку "Создать проект"

    3. Укажите название вашего проекта и нажмите кнопку "Continue". Вы можете использовать любое название. Например: "FGX Native project". 

    4. На текущей странице вы можете отключить поддержку Google Analytics. Вы можете ее отключить. Однако, рекомендуем ее оставить. Так в будущем вы сможете использовать аналитику для данного проекта. Нажмите кнопку "Continue".

    5. Выберите или создайте аккаунт Google Analytics. Я взял созданные раннее, в который будет добавлена аналитика для нового проекта. Нажмите кнопку "Create Project".

    6. Ожидаем окончания процесса создания проекта в Firebase. По окончании нажимаем "Continue". Когда проект будет создан, вы увидите главную страницу:

    7. Теперь необходимо зарегистрировать ваше FGX Native iOS приложение для этого нажимаете на кнопку с логотипом iOS.
    8. Указываете имя пакета вашего iOS приложения, такое же, как у вашего приложения (если оно есть), или такое, какое оно будет (его можно будет указать)
    Если у вас уже есть приложение, то узнать название пакета можно в настройках проекта: Project -> Options... -> Version Info >  CFBundleIdentifier ". Если у вас еще нет приложения, то придумайте название пакета. Например: "ru.fgx.pushnotificationdemo".
    9. Нажмите кнопку "Register app".
    10. Скачиваем конфигурационный файл "GoogleService-Info.plist", нажав на кнопку "Download" и сохраняем файл в папку FGX Native проекта (можно сохранить в любое другое место). Этот файл содержит настройки для инициализации FGX Native приложения на iOS.
    14. Заканчиваем добавление вашего приложения путем нажатия кнопок "Next" -> "Next" -> "Continue to console"
    15. Теперь вы увидите ваше iOS приложение на главной странице.

    Теперь необходимо выполнить настройку FGX Native приложения в IDE.
    Настройка приложения
    1. Откройте существующий проект или создайте новый.
    Если вы создаете новый проект, то в мастере создания проекта обязательно укажите (на основании шага 8 регистрации приложения в Firebase): Идентификатор организации. Например: "ru.fgx". Имя проекта. Например: "pushnotificationdemo". Если открываете существующий, то убедитесь, что название пакета в Project -> Options... -> Version Info >  CFBundleIdentifier " соответствует названию из шага 8. 2. Откройте: "Главное меню" -> "Project ->  Deployment".
    2.1. В выпадающем списке конфигурации выберите "All Configurations -> iOS-Device 64-bit platform".
    Примечание: Если вы хотите разделять настройки для разных конфигураций, выберете соответствующую конфигурацию.    
    2.2. Добавьте ранее скаченный файл настроек "GoogleService-Info.plist" (на основании шага 10 регистрации приложения в Firebase).

    Примечание: Если этого не сделать, то при старте приложение упадет.
    3. Откройте настройки проекта: "Project -> Options... -> Application > Services".
    4. Перейдите к странице "Application -> Entitlment list". И поставьте галку напротив: "Receive push notification". 
    3. Сохраните изменения.
    4. Откройте главную форму вашего приложения и подключите модуль FGX.PushNotification.FCM. 
    Примечание: FGX Native использует Firebase по умолчанию на Android. Однако, на iOS мы используем Apple Push Service по умолчанию. Поэтому Firebase библиотека не линкуется по умолчанию. По этому важно подключить данный модуль. 
    5. Добавьте на форму компонент TfgPushNotificationService и укажите "ServiceNamne = FCM".
    Минимально необходимая настройка вашего приложения для получения пуш уведомлений выполнена. Если приложение будет свернуто или выгружено из памяти, то при отправке push-уведомление отобразиться в центре уведомлений устройства. Если же приложение активно, то пуш уведомление не будет попадать в центр уведомления устройства.
    Получение токена устройства
    При первом старте приложения, оно выполняет свою регистрацию в облаке Firebase. При этом облако выдает устройству уникальный токен DeviceToken. Перед тем, как отправить тестовое уведомление, необходимо узнать токен устройства. Для получения токена устройства нужно написать обработчик события "TfgPushNotificationService.OnDeviceTokenChanged". Данное событие вызывается каждый раз, когда выдается новый токен устройства. Токен устройства может меняться.
    Получив токен, вам необходимо передать его на ваш сервер, отправляющий Push-уведомления для будущих отправок сообщений. 
    В данном примере, мы не будем его сохранять, а выведем в лог устройства.
    procedure TFormMain.PushServiceDeviceTokenChanged(Sender: TObject; const ADeviceToken: string); begin TfgLog.Info('Device token changed: deviceToken="%s"', [ADeviceToken]); end; Получение push-уведомления
    Для получения токена устройства нужно написать обработчик события "TfgPushNotificationService.OnPushNotificationReceived". Данное событие вызывается, когда устройство принимает push-уведомление.
    Примечание: В зависимости от реализации, событие может вызываться в разные моменты времени. Например, если приложение не в памяти или в фоне, то событие вызовется в момент нажатия пользователем на уведомление в Центре локальных уведомлений.
    Пример вывода в лог полученного push-уведомления:
    procedure TFormMain.PushServicePushNotificationReceived(Sender: TObject; const ANotification: TfgPushNotification); begin TfgLog.Info('Notification received: notification="%s"', [ANotification.ToString]); end; Запустите приложение и запомните токен устройства из консоли. 
    О том, как пользоваться Console для просмотра логов устройства, читайте в статье:
    Отправка тестового сообщения
    Чтобы отправить тестовое сообщение на конкретное устройство, можно воспользоваться Firebase консолью.  
    1. Откройте консоль: https://console.firebase.google.com
    2. Перейдите в меню навигации к разделу: "Engage -> Messaging"
    3. Нажмите кнопку "Create your first campaign".
    4. Выберите тип "Firebase Notification Messages".
    4. Заполните данные уведомления. Например так:

    5. Нажмите кнопку "Send test message". Консоль предложит указать на какие устройства необходимо отправить данное уведомление.
    6. Укажите в поле токен устройства (раздел "Получение токена устройства") и нажмите кнопку "+".
    7. Выполните отправку уведомления, путем нажатия на кнопку "Протестировать" и наблюдайте появление вашего уведомления в центре локального уведомления на устройстве:

    Получение данных уведомления при старте приложения
    Если пользователь нажимает на push-уведомление в центре уведомлений, то система запустит ваше приложение. В любой момент времени можно получить данные стартового уведомления напрямую из локального Firebase сервиса (Раздел "Получение Push-уведомлений").
    var Notifications: TArray<TfgPushNotification>; begin Notifications := fgPushNotificationService1.StartupNotifications; end;
  10. Yaroslav Brovin
    Как вы знаете, библиотека FGX Native - это кроссплатформенная библиотека, разрабатываемая с учетом возможностей добавления новых платформ.
    На текущий момент доступна только платформа Андроид. Однако, работа над iOS уже идет полным ходом.
    Рад поделится с вами промежуточными результатами. Перед вами простое приложение с одной кнопкой и меткой:

    Полностью работает система выравнивания, реализована часть базовых сервисов платформы и сделаны первые наброски стандартных компонентов (кнопки, метки и контейнеры).
    video_2020-04-07_02-12-49.mp4.994174c5afa23d87170f03d57d1b01e0.mp4
  11. Yaroslav Brovin
    Доброго дня, уважаемые пользователи FGX Native.
    Наши клиенты делают интересные проекты на базе нашего продукта, однако, к сожалению, об этом знаю только я в результате получения обратной связи по FGX Native. Мне кажется, что всем было бы интересно узнать о таких приложениях, о применяемых возможностях FGX Native и об использованных технических решениях. Сегодня я начну с обзора приложения, которое первоначально задумывалось, как приложения для каршеринга. Однако, в ходе разработки, области применения гораздо расширились за счет универсальности разработанного решения. Но обо всем по порядку.
       
    Далее приведен текст автора @r3h0soft.
    Перед нами стояла задача реализовать программный комплекс мониторинга за ГЛОНАСС устройствами, который бы включал возможности:
    Отслеживание местоположения устройств Мониторинг телеметрии Формирование различных отчётов за выбранный период времени И т.д. В комплекс входило так же и мобильная разработка, при которой стоило преимущественно выбрать среду разработки с лаконичными и понятным кодом имеющим в комплекте кроссплатформенной реализации. Выбор остался за Delphi. Мобильное приложение должно было отвечать всем требованиям на текущий момент что касаемо UI, отзывчивый интерфейс, анимации, поддержкой API и т.д.  Но если с реализацией бэкенд всё было прозрачно, то неотъемлемой частью разработки UI было не всё гладко с использованием FireMonkey. Выбор пал на FGX Native, который предлагает все инструменты для простой и лёгкой разработки и решению поставленных задач.
    В FGX Native реализовано собственное уникальное решение реализации UI, за основу взята система позиционирования FlexBox. С его помощью можно на лету, только через свойства компонента, реализовать UI любой сложности, которое будет одинаково выглядеть при любом разрешении устройств без единой строчки кода. Этот подход значительно ускорил процесс разработки и позволил сосредоточится на построении логики приложения, не загромождая код, вычислениями позиционирования элементов интерфейса.
    Карты
    Данный проект сложно представить без отражения мониторинга в режиме реального времени. За основу мы взяли компонент карт TfgMap с возможностью отображать маркеры, полигоны, географические зоны, строить маршруты, используя линии с большим количеством объектов. Удивила скорость работы компонента и его плавность. Одной из приятных функций для нашего проекта оказалась стилизация карт. Это позволило нам настроить внешний вид карты, чтобы он не выбивался из общего дизайна интерфейса. Одной из задач при использовании карт было построение маршрута, реализовав парсер точек по заданному диапазону времени с необходимой информацией о состоянии объекта и его положении GPS, используя фильтр настойки для разграничения маршрута использовали состояния "простоя" объекта, и иные события при которых объект не выполнял движения. Так мы получили точный список точек перемещения и реализовали отображение через поли линии. Через свойства реализации в FGX Native, мы смогли стилизовать под свои нужды, зная определенные участки состояния объекта смогли через маркеры объектов вывести определенные состояния (к примеру, участки превышения скорости). Хорошим моментом послужило что точками можно взаимодействовать присвоив им ID, так можно получить дополнительную информацию в любом участке трекера просто выбрав точку на карте. Конечно, в будущем очень хотелось бы использовать некую сущность для маркера имеющую стиль, для наполнения его своими объектами как в TfgCollectionView и отображения определенных маркеров при определенных состояниях.
    Сами маркеры добавляются легко через менеджер объектов.
      
    Списки
    Не обошлось и без списков, следовало подгружать объекты в стилизованные карточки одного списка, не нагружая при этом систему, с плавность отрисовки и высокой скоростью. Для решения данной задачи взят TfgCollectionView. Этот компонент отвечает всем требованиям и прост как и все другие решения библиотеки в освоении.  Мы использовали списки, как для формирования меню навигации, так и для отображения маршрутов, истории поездок и т.д. Чтобы не нагружать приложение разными формами, мы использовали выдвигаемые панели сбоку TfgDrawerLayout и снизу TfgBottomSheetLayout. С помощью этих компонентов решена задача быстрого доступа к данным истории телеметрии при этом не нагружая интерфейс и проект дополнительными формами.
     
    Не обошлось и без списков, следовало подгружать объекты в стилизованные карточки одного списка, не нагружая при этом систему, с плавность отрисовки и высокой скоростью. Для решения данной задачи взят TfgCollectionView. В списках мы добавили нужные нам стили объектов списка, что позволило генерировать нужный по событию изменяя только имя стиля, это удобно. Единственное чего не хватило, так это свайпа по элементам списка (лево/право). В общем и целом, этот компонент отвечает всем требованиям и прост как и все другие решения библиотеки в освоении.  Мы использовали списки, как для формирования меню навигации, так и для отображения маршрутов, истории поездок и т.д.
    Чтобы не нагружать приложение формами, мы использовали выдвигаемые панели сбоку TfgDrawerLayout и снизу TfgBottomSheetLayout. С помощью этих компонентов решена задача быстрого доступа к данным истории телеметрии при этом не нагружая интерфейс и проект дополнительными формами.
      
     
    Анимация
    Чтобы оживить интерфейс и порадовать пользователя внешним видом было принято решение встроить готовые сценарии анимации. В одном из обновлений FGX Native появилась поддержка продвинутых анимаций Lottie. Мы нашли готовые примеры анимации и просто встроили их в пару кликов. Таким образом получился такой вот симпатичный экран:
    AddingDriver.mp4
    Так же имеется и конструктор анимации для самих компонентов, мы использовали анимацию тряски для неправильного ввода пароля и анимацию появления для уведомлений.
    Сканер штрих кодов
    В ходе работы с приложением, пользователю необходимо выполнить регистрацию ГЛОНАСС устройства. Можно было бы ограничится вводом в ручную серийного номера, указанного на устройстве. Однако, мы воспользовались готовым сканером штрих кодов TfgBarcodeScanner и камерой TfgCamera и сделали эту процедуру автоматической.

    Уведомления и монетизация
    Любое приложение каршеринга - это контроль за местоположением транспортного средства. И в нашем случае это не исключение. Нам нужно было уведомлять пользователя при определенных событиях телеметрии устройства (вход/выход из геозоны, состояния устройства, ДТП, включения зажигания). Для этого мы использовали локальные уведомления. А вот для системных уведомлений, таких как "обновление приложения" или "необходимости оплаты" легко реализованы с помощью Push уведомлений на базе FGX и Firebase.
    Кстати, среди поставляемых примеров, вы найдете много готовых решений и примеров возможностей библиотеки.
    Хотите иметь возможность монетизации в приложении будь то подписка или продажа, для этого есть готовые компоненты оплаты, как для Android так и iOS.
    Реализация авторизации
    Как и любое приложение, работающее с пользователя, нам необходимо было организовать процесс авторизации. Мы использовали Firebase, реализация выполнена с помощью FB4D библиотеки, в FGX имеется возможность легко реализовать авторизацию и с помощью Google Sign, Facebook, VK, AppleID, что не может не радовать. Основная база крутится на PostgreSQL, используя штатные компоненты FireDAC. Общение построено с использованием REST API, чьим ответственным выступил DelphiMVCFramework фреймворк. Как видно, FGX Native не конфликтует с различными сторонними решениями, что позволяет расширять возможности разработки приложений любой сложности и поставленных задач.
    Bluetooth
    Не обошлось и без штатных задач управления устройством с помощью Bluetooth , мы использовали стандартные средства Delphi RTL для синхронизации и управления модулем через Bluetooth.
    Итог
    Это лишь малая часть которой хотел поделиться, возможности FGX Native для нас очень обширны, мы реализовали разные сложные проекты с его помощью, о которых я расскажу напишу в следующих статьях. Среди таких:
    Мониторинг за сотрудниками (курьерами, работниками, водителям где устройством мониторинга выступает мобильное приложение на FGX с использованием сервисов фоновой локации и состоянием устройства, мониторинга задач и управления через Bitrix), личный кабинета клиента микрофинансовой компании, личный кабинет клиентов интернет провайдера, управление модулем автопилота для лодок fishboat по Bluetooth и многое другое. FGX Native - это лучшее решение для нас!
  12. Yaroslav Brovin
    Hello dear Delphi developers,
    We are happy to share with you two new FGX Native courses in Italian, which Claudio Piffer @claudio.piffer designed and prepared for you. Claudio Piffer is strong Delphi Developer with wide knowledge of different technologies. He often speaks at various Delphi conferences and shares his knowledge with other developers. For us, he is known for two speeches at the DelphiDays conference in Italy (2020, 2022), on which he clearly showed and told the possibilities of FGX Native in the shortest possible time. Claudio has prepared two courses that can help you go into the world of mobile development with Delphi and FGX Native:
    Basic. Mobile developement with FGX Native. Advanced. Advanced concepts in FGX Native. You can find the course description, topics and lessons covered by clicking on the links above.
    Thank you,
    Yaroslav Brovin
  13. Yaroslav Brovin
    В обновлении 1.1.6.0 процесс сборки android приложения претерпел незаметное на первый взгляд, но очень важное для пользователей изменение, а именно,  добавлена автоматическая генерация файла classes.dex.
    classes.dex - обязательный для android приложения файл, содержащий все используемые в приложении Java библиотеки. Ранее конечное приложение собиралось с готовым classes.dex файлом поставляемым вместе с библиотекой FGX Native, что создавало для разработчиков некоторые проблемы при использовании сторонних jar библиотек. Процесс добавления был нетривиален и требовал глубокого погружения в документацию, процессы сборки и микширования classes.dex.
    Механизм автоматической генерации уже используется в FMX проектах, однако, по ряду причин и ограничений, накладываемых IDE, он не мог быть задействован для FGX Native.
    Мы пересмотрели пользовательский опыт и рады представить вам новый удобный диалог для управления jar библиотеками, используемыми в проекте.
    Вызвать диалог можно двумя способами:
    Через главное меню: Project -> FGX Android Libraries Через контекстное меню панели Projects. Target Platforms -> Android (32/64 bits) -> Libraries -> Setup Android Libraries.
    Всё, что необходимо для включения в ваше приложение сторонней jar библиотеки — это добавить её в разделе «Все модули» или «Пользовательские».
    Для возврата списка библиотек к первоначальноиу состоянию воспользуйтесь кнопки «По-умолчанию».
  14. Yaroslav Brovin
    Всем доброго дня,
    При разработке кросс-платформенного приложения важной базовой составляющей является определение размеров компонентов. С одной стороны нет ничего проще, чем задать желаемый размер любому компоненту библиотеки FGX Native или задать правило выравнивания компонентов при помощи FlexBox. Однако, кросс-платформенная разработка накладывает определенные трудности в этом подходе. А именно зачастую размер компонентов зависит не только от других компонентов, но и от содержимого. И если с первым отлично справляется FlexBox, то со вторым в FGX Native нужно использовать метод для расчета размеров компонентов TfgControl.MeasureSize, и будем честны, это было временное решение.
    Мы всегда стараемся сделать библиотеку FGX Native удобной для использования, чтобы разработчик мог концентрироваться в коде на бизнес логике своего приложения, а не программной "настройке" UI. Одним из грядущих улучшений будет поддержка автоматического расчета размеров компонентов. Мы внедрили на нижнем уровне поддержку Autosize. Теперь на уровне появится новое свойство TfgControl.Autosize, которое отвечает за то, что именно нужно автоматически посчитать: ширину, высоту или обе величины. Если в ходе выравнивания компонента система понимает, что компонент имеет фиксированный размер, то в этом случае компонент может автоматически его рассчитать. Так например задание Autosize = [Height] для TfgTraсkBar автоматически посчитает нужную высоту компонента, а вот указание Autosize = [Width] для этого компонента ни на что не повлияет. 

    Не смотря на то, что сам механизм внедрен на нижнем уровне, реально это свойство в ближайшем релизе будет доступно только для нескольких компонентов: TfgSwitch, TfgTrackBar, TfgNavigationBar и возможно TfgLabel. Если с TfgSwitch и TfgTrackBar в целом понятно,  то вот на счет TfgNavigationBar  стоит отдельно отметить, что теперь этот компонент умеет в автоматическом режиме расчета высоты учитывать отступы у формы SafeArea и наличие заголовка и подзаголовка. И если раньше необходимо было программно отслеживать изменения отступов области SafeArea в TfgForm.OnSafeAreaChanged и на основании значений отступов вычислять руками высоту панели навигации, то сейчас все это будет происходить автоматически.



    Данное нововведение особенно актуально в свете предстоящего появления iOS. Так как в iOS используются другие шрифты, размеры текста и размеры компонентов. И чтобы сделать действительно универсальное приложение без этой функциональности будет очень сложно.
    Всем хорошей рабочей недели!
  15. Yaroslav Brovin
    Добрый день, уважаемые разработчики. 
    FGX Native содержит большое количество разнообразных компонентов: начиная от визуальных компонентов, составляющих основу для создания UI вашего приложения, продолжая невизуальными компонентами, облегчающими отслеживание состояния вашего приложения  и заканчивая компонентами-интеграциями с различными сервисами. И если использование первых двух - не зависит от внешних сервисов, то третья - как раз часто требует настройки и более точной интеграции на стороне приложения.
    Так, например, при желании подключить Push-уведомления, вам нужно выбрать провайдера, выполнить первичную настройку на стороне сервиса и затем выполнить настройку клиента (FGX Native приложения). А при использовании Facebook аутентификации уже требуется гораздо больше действия, включая ручное подключение Android библиотек, добавление в деплой новых файлов, правку манифеста и тд.
    Отдельно стоит упомянуть про необходимость настроить приложение в целом: поменять заставку, настроить иконки и базовые цвета и так далее. Все это требует не столько кодирования, сколько внесения и размещения нужных значений параметров в манифесты и файлы настроек. К сожалению, эта часть настроек осуществляется при помощи штатного окна настройки проекта Project -> Options. И поскольку мы не имеем возможности его как-то модифицировать, то мы не можем добавлять туда новые настройки и адаптировать логику. 
    Именно по этой причине в этом релизе 1.18.0.0 нас ждет новое окно настроек проекта.

    Однако стоит обратить внимание, что просто новое окно настроек не имеет смысла без интеграции процесса сборки MSBuild. Так как введенные параметры и настройки нужно передавать и упаковывать в собираемого приложение.  В течении несколько месяцев мы разрабатывали базовый механизм для создания расширяемого окна настроек. Основная идея - это добавление любых страниц настроек и внедрение в систему сборки MSBuild для любых сторонних сервисов. В рамках разработки мы написали несколько расширений для MSBuild, чтобы в будущем проект можно было собрать полностью с командной строки. Процесс перевода в пользу сборки целиком с помощью MSBuild еще не завершен полностью, но мы движемся в этом направлении.
    В этой статье мы не будем разбирать API для сторонних разработчиков, которое они могут использовать для регистрации своих настроек, а сосредоточимся на утилитарном использовании.
    Анимированная заставка Android
    Первым главным нововведением нового окна настроек являются анимированные заставки для Android 12+. 
    https://developer.android.com/develop/ui/views/launch/splash-screen Начиная с Android 12+ структура заставок изменилась и теперь появилась возможность использовать современные анимированные заставки. Раньше была статья, которая описывала детально ручные правки, которые можно было внести 
    Сейчас достаточно включить опцию и настроить внешний вид заставки. Описание параметров смотрите в официальной документации Андроида.

    Eсли ваше приложение запускается на устройствах с Android 12+ будет использоваться анимированная заставка, на старых версиях Android, будет использоваться статическая заставка.

    Добавлен новый пример: "Android Api" -> "Анимированная заставка"
    Примечание: Настройки статической версии заставки пока находятся в старом окне настроек. По мере возможности мы будем переносить значимые для нас настройки из старого окна настроек проекта в новое.
    Google Maps
     
    Было: Раньше ключ карты указывался в стандартном окне настроек проекта в разделе VersionInfo. Помимо этого необходимо было включить поддержку карт в разделе "Entitlements List" -> "Maps Service".
    Стало: Теперь включение сервиса карт и API ключ указываются в разделе "Сервисы" -> "Google Maps".
    Что нужно сделать: Дополнительных действий не требуется. При открытии проекта в этой версии ключ будет автоматически перенесен. Однако, после этого ключ надо менять только в новом окне настроек.
    Facebook Login

    Было: Раньше при использовании "Facebook Login" необходимо было вручную вносить настройки Facebook Login в файлы "strings.xml" и "info.plist.TemplateiOS.xml". Так же требовалось вручную добавлять зависимость на Android библиотеку и править Android манифест.
    Стало: Достаточно включить сервис в новых настройках "Сервисы" -> "Аутентификация" -> "Facebook Login" и указать требуемые параметры.
    Что нужно сделать: Если вы уже используете Facebook Login, то вы либо можете оставить все, как есть. Либо же перейти на новую настройку. Для этого нужно откатить все изменения сделанные в статьях:
    Сервисы аутентификации. Аутентификация с помощью Facebook Login (Android) Сервисы аутентификации. Аутентификация с помощью Facebook Login (iOS). И выполнить включение и ввод настроек в новом окне.
    VK Login

    Было: Раньше при использовании "VK Login" необходимо было вручную вносить настройки в файл "info.plist.TemplateiOS.xml".
    Стало: Достаточно включить сервис в новых настройках "Сервисы" -> "Аутентификация" -> "VK Login" и указать требуемые параметры.
    Что нужно сделать: Если вы уже используете VK Login, то вы либо можете оставить все, как есть, либо же перейти на новую настройку. Для этого нужно откатить все изменения сделанные в статьях:
    Сервисы аутентификации. Аутентификация с помощью VK Login (iOS) И выполнить включение и ввод настроек в новом окне.
    Заключение
    В следующих релизах мы будем переносить значимые параметры - такие как настройки Push-уведомлений, реклама, аналитика и тд.
  16. Yaroslav Brovin
    В следующем релизе FGX Native 1.11.0.0 будет много новых интересных возможностей, которые безусловно найдут свое место в ваших приложениях. В этой статье поговорим о первой новинке: получение фотографии с камеры или из системной галереи изображений.
    До версии 1.11.0.0 получение фотографии с камеры, было не самой тривиальной задачей. Было два решения, которым обычно пользовались разработчики:
    Использование напрямую камеры и разработка своего решение на базе демонстрационного проекта "Компоненты" -> "TfgCamer" -> "Фотокамера". Несмотря на то, что этот способ рабочий и он дает возможности по кастомизации внешнего вида видеоискателя, зачастую требуется просто получить фотографию от пользователя.  Использование нативного API каждой платформы для отправки запроса на получение фотографии системным приложениям. TfgPhotoPicker
    В этом релизе мы предлагаем кроссплатформенное решение в виде специального типа пикера, используемого для выбора фотографии из системной галереи изображений или снятия фотографии с системной камеры. 
    video_2021-05-12_01-16-46.mp4
    Чтобы отправить запрос на получение фотографии с камеры достаточно написать всего три строчки кода:
    uses FGX.Assets, FGX.Assets.Helpers, FGX.Pickers.Photo; procedure TFormMain.btnTakePhotoFromCameraTap(Sender: TObject); begin TfgPickerPhotoFactory.PickPhotoFromCamera(btnTakePhotoFromCamera, procedure(const AFileName: TFileName) begin TfgAssetsManager.Current.AddBitmapFromFile('Photo', AFileName, True); end); end; Для получения фотографии из галереи:
    procedure TFormMain.btnTakePhotoFromLibraryTap(Sender: TObject); begin TfgPickerPhotoFactory.PickPhotoFromLibrary(btnTakePhotoFromLibrary, procedure(const AFileName: TFileName) begin TfgAssetsManager.Current.AddBitmapFromFile('Photo', AFileName, True); end); end; Запрос отправляет через специальную фабрику FGX.Pickers.TfgPickerPhotoFactory, которая предлагает три метода:
    TfgPickerPhotoFactory = class public /// <summary>Создает и возвращает платформенный пикер получения фотографии для ручной работы.</summary> /// <remarks>Удаление пикера лежит на плечах вызываемого кода.</remarks> class function CreatePicker(const AOwner: TObject): TfgPickerPhoto; /// <summary> /// Иницирует получение фотографии с системного приложения камеры. Фотография возвращается в переданную /// анонимную процедуру <c>AOnDidFinishPickingCallback</c>. /// </summary> /// <remarks> /// Вам не требуется следить за временем жизни возвращаемого пикера. Пикер автоматически удалится после того, /// как он будет закрыт пользователем. /// </remarks> class function PickPhotoFromCamera(const AOwner: TObject; const AOnDidFinishPickingCallback: TfgDidFinishPickingCallback): TfgPickerPhoto; /// <summary> /// Иницирует получение фотографии с системного приложения галереи изображений. Фотография возвращается в /// переданную анонимную процедуру <c>AOnDidFinishPickingCallback</c>. /// </summary> /// <remarks> /// Вам не требуется следить за временем жизни возвращаемого пикера. Пикер автоматически удалится после того, /// как он будет закрыт пользователем. /// </remarks> class function PickPhotoFromLibrary(const AOwner: TObject; const AOnDidFinishPickingCallback: TfgDidFinishPickingCallback): TfgPickerPhoto; end; Второй и третий метод предназначены для быстрого получения фотографии с камеры или из галереи. Первый же метод предназначен для ручной настройки пикера и отлова всех событий (открытие, закрытие, отмена и тд.).
    Внимание! Для корректной работы пикера на платформе Android необходимо в настройках проекта включить опцию:
    Project -> Options... -> Application -> Entitlement List -> Security File Sharing = True. Также мы подготовили демонстрационный проект, который позволит вам попробовать эту возможность самостоятельно: "Компоненты" -> "Пикеры" -> "Получение фотографии".
    Всем хорошей рабочей недели. Следите за будущими анонсами FGX Native 1.11.0.0.
  17. Yaroslav Brovin
    Продолжаем серию статей, посвященных новинкам релиза FGX Native 1.11.0.0. И в этой статье поговорим о самой главной и ожидаемой новинке - поддержка полноценных анимаций 🔥🔥🔥.
     
    TfgAnimationManager - центр управления анимациями
    Главным центром управления анимации любого компонента является менеджер анимаций, доступ к которому можно получить через свойство TfgControl.AnimationManager. Именно он отвечает за создание, добавление и удаление аниматоров.
    Создание аниматора
    Чтобы создать нужный аниматор нужно воспользоваться одним из следующих методов TfgAnimationManager:
    function AddOpacityAnimation(const AStartOpacity, AFinishOpacity: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddBoundsAnimation(const AStartBounds, AFinishBounds: TRectF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddScaleAnimation(const AStartScaleX, AFinishScaleX, AStartScaleY, AFinishScaleY: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddRotationAnimation(const AStartAngle, ASweepAngle: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddTranslationAnimation(const AStartPoint, AFinishPoint: TPointF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddGroupAnimation: TfgAnimationGroup; Каждый метод создает соответствующий своему названию тип аниматора с указанными стартовыми и конечными значениями. Например, если вы хотите плавно показать кнопку в течении 1 секунды, достаточно выполнить следующий код.
    uses FGX.Animation; var Animation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}); Animation.Start; Обратите внимание, что в данном случае, созданный аниматор "Animation" останется у компонента и не будет удален, пока вы не сделаете это сами или компонент не будет уничтожен. Если вы планируете часто использовать один и тот же вид анимации на конкретном компоненте, то предпочтительным способом будет являться именование анимации. Например:
    uses FGX.Animaton.Helpers; // Создаем аниматор один раз Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}) .SetName('fade-in'); // Будущие запуски анимации Button.AnimationManager['fade-in'].Start; Если же вам достаточно выполнить анимацию всего лишь один раз, то имеет смысл пометить ее для автоматического удаления опцией TfgAnimationOption.ReleaseOnFinish: 
    uses FGX.Animation.Types, FGX.Animation.Helpers; Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}) .AddOption(TfgAnimationOption.ReleaseAnimationOnFinish) .Start; Хелпер анимации
    Для удобного создания аниматоров мы предлагаем вам готовый хелпер FGX.Animation.Helpers, который позволяет использовать цепочку вызовов методов аниматора и облегчить визуальное восприятие готового кода.
    Без хелпера:
    uses FGX.Animation; var OpacityAnimation: TfgAnimation; OpacityAnimation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}); OpacityAnimation.Duration := 1000 {msec}; OpacityAnimation.AutoReverse := True; OpacityAnimation.Delay := 500 {msec}; OpacityAnimation.Options := OpacityAnimation.Options + [TfgAnimationOption.ReleaseAnimationOnFinish]; OpacityAnimation.Start; С хелпером:
    uses FGX.Animation.Types, FGX.Animation.Helpers; Button.AnimationManager.AddOpacityAnimation(0 {start opacity}) .SetDuration(1000 {msec}) .SetDelay(500 {msec}) .SetAutoReverse .SetReleaseAnimationOnFinish .Start; Чтобы воспользоваться хелперами, необходимо подключить модуль FGX.Animation.Helpers.
    Обзор базовых аниматоров
    Поддерживается 5 базовых типов анимаций:
    Opacity. Изменение прозрачности (TfgControl.Opacity). Bounds. Изменение положения и размера (TfgControl.Position + TfgControl.Size).  Scale. Изменение масштаба отображения компонента. Rotation. Изменение угла поворота компонента. Translate. Выполнение смещения компонента относительно его текущей позиции (TfgControl.Position). Анимация прозрачности (TfgAnimationManager.AddOpacityAnimation)
    Чтобы выполнить анимацию прозрачности нужно создать аниматор через метод TfgAnimationManager.AddOpacityAnimation и указать стартовое и конечное значение свойства TfgControl.Opacity. 
    Image.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 2000 {msec}) .Start; opacity.mp4
    Анимация перемещения и изменения размера (TfgAnimationManager.AddBoundsAnimation)
    Чтобы выполнить анимацию изменения размера и позиции нужно создать аниматор через метод TfgAnimationManager.AddBoundsAnimation и указать стартовый и конечный прямоугольник. Пример ниже демонстрирует интересный прием акцентирования внимания на компоненте через визуальное расширение и сжатие компонента.
    var StartRect: TRectF; StopRect: TRectF; begin StopRect := imgPhoto.Bounds; StartRect := imgPhoto.Bounds; StartRect.Inflate(16, 16); Image.AnimationManager.AddBoundsAnimation(StartRect, StopRect) .Start; bounds.mp4
    Анимация изменения масштаба (TfgAnimationManager.AddScaleAnimation)
    Чтобы выполнить анимацию изменения масштаба нужно создать аниматор через метод TfgAnimationManager.AddScaleAnimation и указать стартовые и конечные значения коэффициентов масштабирования по горизонтали и вертикали.
    Image.AnimationManager.AddScaleAnimation(0.5, 1, 0.5, 1, 1000) .Start; scale.mp4
    Анимация поворота компонента (TfgAnimationManager.AddRotationAnimation)
    Чтобы выполнить анимацию поворота компонента нужно создать аниматор через метод TfgAnimationManager.AddRotationAnimation и указать стартовое значение угла и на сколько градусов нужно совершить поворот (в градусах). При этом, если угол поворота положительный, то поворот осуществляется по часовой стрелки, а если отрицательный, то против часовой стрелки.
    Image.AnimationManager.AddRotationAnimation(0 {start}, 360 {Sweep}, 1000) .Start; rotate.mp4
    Анимация смещения (TfgAnimationManager.AddTranslationAnimation)
    Чтобы выполнить анимацию смещения компонента нужно создать аниматор через метод TfgAnimationManager.AddTranslationAnimation и указать стартовое и конечное смещения значения позиции компонента.
    Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000) .Start; translate.mp4
    TfgAnimation - основа анимации
    После того, как мы посмотрели несколько примеров создания аниматоров вживую, пришло время рассмотреть их настройки детальнее.
    Длительность анимации (TfgAnimation.Duration)
    Общая длительность выполнения текущей анимации в миллисекундах в одну сторону (от стартового значения до конечного).
    Задержка перед запуском (TfgAnimation.Delay)
    Если вам необходимо выполнить анимацию с задержкой, то вы можете это сделать указав значение задержки в миллисекундах в свойстве TfgAnimation.Delay.
    Количество повторений (TfgAnimation.RepeatCount)
    Если вам необходимо повторить анимацию несколько раз или сделать ее бесконечной, то вы можете это сделать при помощи этого свойства, где
    RepeatCount = 0 - повторение анимации бесконечное число раз. RepeatCount > 0 - повторение анимации ровно "RepeatCount" раз. Например при помощи этого свойства легко сделать анимацию тряски: повторим 4 раза движение компонента по горизонтальной оси.
    shake+repeatCount.mp4
    Интерполяция (TfgAnimation.CurveKind)
    Это свойство отвечает за формулу интерполяции значений анимируемых свойств. Пока поддерживается 4 самых распространенных типов интерполяции.
    TfgAnimationCurveKind = (Linear, EaseIn, EaseOut, EaseInOut);
    Краткое описание стратегии изменения анимируемого значения на протяжении всей длительности анимации в зависимости от типа интерполяции:
    Linear - равномерное изменение. Варианты типичного применения: короткие анимации, изменение цвета. EaseIn - медленное начало с постепенным нарастанием скорости к концу анимации. Варианты типичного применения: исчезновения объекта. EaseOut - быстрое начало с постепенным замедлением скорости к концу анимации. Варианты типичного применения: появления объекта. EaseInOut - медленное начало с нарастанием скорости посередине и постепенным замедлением скорости к концу анимации. Варианты типичного применения: перемещение объекта, изменение масштаба. Порядок запуска (TfgAnimation.RunOrder)
    Это свойство актуально только в контексте групповых аниматоров и позволяет указывать порядок запуска текущей анимации в группе. Подробнее это будет рассмотрено в разделе "Групповые анимации".
    TfgAnimationRunOrder.Immediately - запуск анимации в момент старта родительского группового аниматора, либо вместо с предыдущим одноуровневым аниматором. TfgAnimationRunOrder.AfterPrevious - запуск анимации после окончания предыдущей анимации в рамках группового аниматора. Дополнительные настройки (TfgAnimation.Options)
    TfgAnimationOption.StartFromCurrent - Начинать анимацию с текущего значения свойства компонента, а не указанного стартового значения. TfgAnimationOption.AlwaysSetFinalValue - При остановке анимации, эта опция позволяет указать сразу конечное значение свойства компоненту, иначе конечное значение останется таким, какое оно было на момент остановки. TfgAnimationOption.AutoReverse - Нужно ли автоматически выполнить анимацию в обратном порядке после окончания прямой анимации. Актуально для RepeatCount > 0. TfgAnimationOption.ReleaseControlOnFinish - позволяет автоматически удалить компонент по окончании анимации. TfgAnimationOption.ReleaseAnimationOnFinish - позволяет автоматически удалить аниматор по окончании анимации. Название (TfgAnimation.Name)
    Вы можете присвоить уникальное название аниматору, чтобы в последствии обращаться к нему напрямую по его имени.
    Например:
    var FadeAnimation: TfgAnimation; FadeInAnimation := Button.AnimationManager['fade-in']; Групповые анимации
    Для создания сложных анимаций мы предлагаем использовать групповые аниматоры, задача которых сгруппировать несколько анимаций и задать правила их запуска. По умолчанию групповой аниматор запускает все вложенные анимации одновременно. Например, такой аниматор ниже позволяет реализовать анимацию модального открытия формы на Android:
    var AnimationGroup: TfgAnimationGroup; AnimationGroup := LForm.AnimationManager.AddGroupAnimation .Add(LForm.AnimationManager.CreateScaleAnimation(1.125, 1, 1.125, 1)) .Add(LForm.AnimationManager.CreateOpacityAnimation(0, 1)); Мы создаем два аниматора, объединенные в группу, один из которых масштабирует форму, а второй меняет ее прозрачность.
    Групповой аниматор TfgAnimationGroup по сути так же является аниматором TfgAnimation. А это значит, что вы можете их вкладывать друг в друга добиваясь анимации любой сложности.
    Пример ниже показывает последовательно выполнение анимаций: вначале смещение компонента, а затем поворот:
    Image.AnimationManager.AddGroupAnimation .Add(Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000)) .Add(Image.AnimationManager.AddRotationAnimation(0, 360, 1000) .SetRunOrder(TfgAnimationRunOrder.AfterPrevious)) .Start; group-animation-1.mp4
    Вы можете выделить создание подобной анимации в отдельный метод и затем применять к любому компоненту. 
    Шаблоны анимаций
    Это приятный бонус для наших пользователей. Мы предлагаем базовый набор уже готовых анимаций, которые вы можете использовать в своих проектах всего лишь одной строчкой кода. Для того, чтобы воспользоваться шаблонами, нужно подключить модуль FGX.Animation.Templates.
    Чтобы просто потрясти компонент, достаточно просто написать:
    Image.Shake; А если требуется настроить параметры на свой вкус и цвет, можно воспользоваться перегруженной версией:
    Image.Shake(TfgShakeAnimationParams.Default .SetDuration(2000) .SetRepeatCount(10)); Видео ниже демонстрирует все текущие доступные для использования шаблоны:
    templates.mp4
    Среди шаблонов так же доступны различные варианты появления и скрытия компонентов с переносами и без. Вы можете ознакомиться с текущим набором в демо проекте: "Анимация" -> "Шаблоны анимаций".
    Ограничения
    Несмотря на то, что анимации уже работают, у них есть ряд ограничений, часть из которых мы будем постепенно убирать в будущих версиях.
    Нельзя менять стартовые и конечные значения уже созданных анимаций. Это можно делать только путем удаление старого и создания нового аниматора. Изменение свойств анимации во время ее выполнения не приведет их к применению. Все свойства применяются в момент старта анимации. Изменение размера компонента-контейнера через анимацию не приводит к выравниванию дочерних компонентов. Если вам нужно выполнить выравнивание содержимого, то надо добавлять дополнительные аниматоры для перемещения и изменения размеров вложенных компонентов отдельно.  Устаревшее API
    Из-за создания полноценной анимации и выделения старых хелперов анимации TfgAnimationHelper в шаблоны анимации FGX.Animation.Templates, мы помечаем существующие методы анимации FadeIn, FadeOut, как устаревшие. Через несколько релизов мы удалим эти методы из TfgAnimationHelper, чтобы вы пользовались более удобными средствами анимации.
    На текущий момент методы анимации формы остаются как есть. В ближайших релизах эту анимацию мы встроим прямо в TfgForm, в результате чего анимация открытия/закрытия форм будет осуществляться автоматически и не будет требовать от вас лишних строчек кода.
    Итог
    Мы продолжим развивать и совершенствовать реализацию анимаций. Поэтому нам очень важно получить от вам обратную связь о том, что удобно, что нет и чего не хватает. Эта информация поможет нам сделать анимацию лучше и удобнее для всех.
  18. Yaroslav Brovin
    Продолжаем анонсировать интересные возможности новой версии FGX Native 1.11.0.0. И в этот раз - это компонент локализации TfgTranslator.
    В этой версии мы поставляем отдельный bpl-пакет с компонентом локализации TfgTranslator, который мы сами уже давно и успешно используем в реализации FGX Native дизайнера. Однако, мы не рекомендуем его использовать в мобильных приложениях, поскольку все словари с переводами всегда загружаются при создании формы, а так же, поскольку у нас есть иное видение того, как должен осуществляться перевод в мобильных приложениях.
    Несмотря на сказанное - это рабочее решение, которое может помочь вам с локализацией ваших проектов. Мы поставляем этот компонент по правилу "as-is", то есть нет никаких гарантий (в том числе и поддержки) с нашей стороны по его работе. Этот пакет не является постоянным и может быть в будущем исключен из поставки при появлении рекомендованного решения.
    Как установить?
    Чтобы установить компонент локализации нужно выполнить регистрацию нового пакета компонента в среде. Для этого:
    Открываем менеджер пакетов: Main menu -> Component -> Install Packages. Нажимаем кнопку "Add..." Открываем каталог, где установлен FGX Native и открываем каталог, соответствующий версии вашей IDE. Если вы не меняли место установки библиотеки, то: "C:\Users\Yaroslav\AppData\Local\FGX Native\Libs\<версия IDE>\Win32\Release" Выбираем "FGXTranslatorD.<версия IDE>.bpl": Для 10.3 - 260 Для 10.4 - 270 Закрываем окно нажатием на кнопку OK. Теперь компонент TfgTranslator доступен для использования на панели "Pallette": FGX: Translator -> TfgTranslator.
    Как использовать?
    Компонент TfgTranslator выполняет перевод всех строковых свойств в рамках одной формы. Чтобы им воспользоваться, нужно бросить компонент на форму. Чтобы выполнить первичную настройку, необходимо создать список поддерживаемых языков и, по желанию, выполнить перевод текущих строк. 
    По двойному нажатию на компонент открывается редактор:

    Добавление языков
    По умолчанию, в компоненте есть только один язык "default", который используется для всех языков, если перевода нет. Вы можете добавить любое количество дополнительных языков. Для этого нажмите кнопку с глобусом и введите код языка (например "en").

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

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

    Ручные строковые ресурсы
    Вы можете указать свои строковые ресурсы для использования их в рантайме. Для этого надо нажать на кнопку "T+" и указать код строки и ее переводы.


    Перевод
    Выполните перевод текущего словаря путем двойного нажатия на ячейку таблицы.

    Смена языка
    Смена языка осуществляется при помощи свойства TfgTranslator.LangId, где нужно указать нужный язык. При смене кода языка, компонент автоматически выполнит перевод указанных свойств.
    Русский (по умолчанию):

    Английский:

  19. Yaroslav Brovin
    Рады поделиться новинками будущего релиза 1.12.0.0. 
    Очень часто при разработке мобильных приложений разработчики сталкиваются с одними и теми же задачами. Большинство решений, которые есть в интернете, ориентированы под FMX. Однако, зачастую из-за зависимостей в RTL на FMX Java код, эти решения нельзя просто добавить в FGX Native как есть и использовать.
    Поэтому мы решили по мере возможностей предлагать вам решения этих задач в виде расширений для FGX Native. Расширение будет включать необходимую обвязку/компоненты для FGX Native для сторонних OpenSource проектов. Первым таким расширением будет реализация нового компонента генерации штрихкода TfgBarcode на основе библиотеки Zint (https://www.zint.org.uk/).
    Отображение штрихкодов
    Новый пакет расширения FMXNative.Extension.Zint включен в поставку 1.11.8.0. Пакет содержит новый компонент TfgBarcode, поддерживающий отображение огромного числа типов штрихкодов. 

    Свойство Symbology позволяет выбрать тип отображаемого штрихкода. Через свойство Data указываются кодируемые данные. А через группу свойств Appearance вы можете настроить визуальное отображение штрихкода.
    Новое правило именования пакетов FGX Native
    Мы пересмотрели правила именований пакетов библиотеки FGX Native. Поэтому, если вы создаете свои пакеты расширений на основе FGX Native, вам необходимо переименовать зависимости на пакеты.
    FGXNative.Core <- fgx FGXNative.Design <- fgx_design FGXNative.Registration <-fgx_reg FGXNative.Extension.Translator <- FGXTranslatorD FGXNative.Externals <- fgx_externals Так же, если вы используется наш компонент локализации, необходимо:
    После установки новой версии библиотеки запустить среду Среда отобразит ошибку при загрузке пакета FGXTranslatorD. Необходимо отвечать Yes во всех диалогах про этот пакет. Затем открыть список компонентов среды: "Components" -> "Install Packages..." В списке найти строчку, соответствующую FGXTranslatorD и удалить ее при помощи кнопки "Remove". Данный компонент мы теперь регистрируем автоматически при установке FGX Native. Календарь под iOS
    В новой версии так же появится реализация компонента TfgCalendar для iOS. iOS не имеет родной реализации календаря. Поэтому мы с нуля реализуем данный компонент.
    Заключение
    Если у вас есть потребность в миграции некоторых невизуальных компонентов из FMX, пожалуйста, отпишитесь здесь в комментариях:
    Ссылку на стороннюю библиотеку с наличием исходных кодов/OpenSource. Без доступа к исходным кодам мы не сможем выполнить адаптацию под FGX Native. Описание для чего данный компонент нужен. Если кто-то из участников уже озвучил в комментариях нужный вам компонент, просьба отметить такое сообщение реакцией (лайком).
  20. Yaroslav Brovin

    Общая
    Добрый день,
    В ближайшее время выйдет релиз FGX Native 1.13.0.0 с полноценной поддержкой Delphi 11. Обо всех нововведениях по порядку.
    Delphi 11
    Начиная с версии 1.13.0.0 мы включили поддержку Delphi 11. В то же время, мы исключили поддержку 10.3 из инсталлятора на основании результатов голосования:
    Мы переработали все формы дизайнера и добавили полноценную поддержку HiDPI.
    Дизайнер форм
    Добавлен новый режим позволяющий отключать пунктирную рамку компонентов.

    Так же несколько улучшили функцию визуального отображения областей компонентов, добавив отображение областей внутренних отступов бледно зеленым цветов. Это позволяет наглядно и быстро понять, где используются внутренние отступы (TfgControl.Padding).

    Обновления TfgDatePicker и TfgTimePicker
    В этом релизе мы добавили несколько небольших улучшений этих компонентов. Теперь вы можете указать формат ввода времени: 12 или 24 часовой формат. За это отвечает новое свойство TfgTimePicker.Is24HoursMode = (LocaleDependent, True, False). Теперь при старте компонента на платформе Android он по умолчанию выбирает часовой формат на основании текущей локали устройства.
     
    Помимо этого мы добавили режим автоматического расчета размера для этих компонентов AutoSize, который включен по умолчанию. Поэтому, если вам необходимо, чтобы компоненты растягивались по ширине, нужно исключить значение AutoSize.Width.
    Так же, теперь вы можете отдельно указывать задний фон для этих компонентов при помощи свойства BackgroundName.
     
  21. Yaroslav Brovin

    Общая
    Поздравляем вас с наступающим Новым годом!
    Мы благодарим вас за доверие и спасибо, что в этом году вы были с нами. В течении всего года мы прислушивались к вашим пожеланиям и старались сделать все возможное, чтобы наш продукт раз от раза становился удобнее и мощнее.
    В ближайшее время выйдет новый релиз 1.13.3.0. Традиционно в этом релизе вас ждет несколько полезных новинок и улучшений.
    GooglePay - TfgGooglePayClient 
    Первая новинка - это новый компонент TfgGooglePayClient оплаты покупок в вашем приложении через платежную систему GooglePay.
    Настройка 
    Для того, чтобы добавить возможность оплаты покупок в вашем приложении, вам необходимо выполнить первичную настройку на стороне Google - https://developers.google.com/pay/api/web/guides/setup?hl=ru
    В результате этой настройки вы получите идентификатор продавца Google - MerchantId.
    Настройка приложения FGX Native
    Для того, чтобы иметь возможность использовать GooglePay в FGX Native приложении, необходимо добавить в манифест Android приложения следующие строчки в любое место внутрь тега <application>:
     1. Версию GooglePlay сервисов. ТОЛЬКО, если вы не используете "Firebase PushNotification", Maps или AdMob.
    <meta-data android:name="com.google.android.gms.version" android:value="12451000" /> 2. Включить доступ приложения к кошельку:
    <meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" /> 3. Указать идентификатор продавца в свойстве "TfgGooglePayClient.MerchantName", полученный на предыдущем шаге.
    Проверка возможности оплаты через GooglePay
    GooglePay может быть недоступен на устройстве пользователя, поэтому, перед инициированием процесса оплаты, необходимо узнать текущий статус. Это можно сделать через асинхронный метод "TfgGooglePayClient.IsReadyToPayAsync":
    uses FGX.Payments.GooglePay.Types; if gpClient.IsSupported then gpClient.IsReadyToPayAsync(False, procedure (const AStatus: TfgGooglePayStatus) begin // Отображаем/Скрываем кнопку оплаты через GooglePay btnPay.Visible := AStatus = TfgGooglePayStatus.Available; end); Оплата через GooglePay
    Для инициации оплаты необходимо заполнить информацию о проводимой транзакции и воспользоваться асинхронным методом оплаты "TfgGooglePayClient.PayAsync". Минимально необходимая информация в транзакции - это код валюты и цена.
    procedure TFormMain.btnPayTap(Sender: TObject); var TransactionInfo: TfgTransactionInfo; begin TransactionInfo := TfgTransactionInfo.Create; try { Информация о покупке } TransactionInfo.SetCurrencyCode('RUB') .SetTotalPrice(100.12); gpClient.PayAsync(TransactionInfo); finally TransactionInfo.Free; end; end; Описание полей транзакции, смотрите в исходном коде или на сайте GooglePay.
    По результатам обработки запроса, будет вызвано одно из событий:
    "OnPaymentError" - в ходе оплаты произошла ошибка. "OnPaymentComplete" - пользователь выполнил оплату, токен для проведения оплаты передается в параметрах события. "OnPaymentCancelled" - пользователь отменил оплату. Если платеж прошел успешно, то в событии OnPaymentComplete будет передан JSON ответ, из которого вы можете извлечь необходимую информацию согласно документации:
    procedure TFormMain.gpClientPaymentComplete(Sender: TObject; const AResponse: TJSONValue); begin mLog.Lines.Add(Format('Completed: AResponse="%s"', [AResponse.Format])); end; После извлечения платежного токена, вам необходимо провести транзакцию на вашем сервере через ваш банк.
    Если же оплата по каким-то причинам не прошла, вы можете получить информацию об ошибке через событие OnPaymentError. В параметрах передается код ошибки и ее описание. Обратите внимание, что данный код и описание выдается самой системой. Поэтому иногда описание может отсутствовать или содержать неполную информацию (это нормально).
    Диагностика и отладка
    Все детальные ошибки настройки интеграции с GooglePay обычно выводятся в лог. Именно там можно узнать, почему платеж не запускается или не проходит. Обратите внимание, что чаще всего ошибки в лог попадают не от имени приложения, а от системы. Поэтому при поиске проблем, нужно это учитывать (не фильтровать сообщения вашим приложением).
    Все свойства компонента полностью соответствуют оберткам в документации Google Pay. Компонент формирует JSON запрос, который отправляется в нативное API. Вы можете проверить корректность формирования JSON запроса через лог. Для этого необходимо включить расширенное логирование в вашем приложении:
    TfgLog.MinimumLevel := TfgLogLevel.Trace; Полезные ссылки:
    Руководство по использованию бренда GooglePay. Советы UX по интеграции GooglePay. Чек лист по настройке GooglePay. Диагностика проблем. TfgApplicationEvents
    При разработке Android приложений и при использовании Android API очень часто требуется отправить запрос другим активностям и получить от них результат. Раньше это решалось через подписку на широковещательные сообщения  FGX.Platform.Android.TfgActivityResultMessage и TfgActivityNewIntentMessage и требовало написать следующий код:
    constructor TFormMain.Create(AOwner: TComponent); begin inherited; TMessageManager.DefaultManager.SubscribeToMessage(TfgActivityResultMessage, ActivityResultHandler); TMessageManager.DefaultManager.SubscribeToMessage(TfgActivityNewIntentMessage, ActivityNewIntentHandler); end; destructor TFormMain.Destroy; begin TMessageManager.DefaultManager.Unsubscribe(TfgActivityNewIntentMessage, ActivityNewIntentHandler); TMessageManager.DefaultManager.Unsubscribe(TfgActivityResultMessage, ActivityResultHandler); inherited; end; procedure TFormMain.ActivityNewIntentHandler(const Sender: TObject; const M: TMessage); var Message: TfgActivityNewIntentMessage; begin TfgAssert.IsClass(M, TfgActivityNewIntentMessage); Message := TfgActivityNewIntentMessage(M); TfgToast.Show(Format('Получен новый интент: intent=%s', [JStringToString(Message.Value.toString)])); end; procedure TFormMain.ActivityResultHandler(const Sender: TObject; const M: TMessage); var Message: TfgActivityResultMessage; begin TfgAssert.IsClass(M, TfgActivityResultMessage); Message := TfgActivityResultMessage(M); // Intent is available in Message.Data TfgToast.Show(Format('Получен результат из другого приложения: requestCode=%d, resultCode=%d', [Message.RequestCode, Message.ResultCode])); end; Сейчас же мы добавили два новых события "TfgApplicationEvents.OnActivityResult" и "TfgApplicationEvents.OnActivityNewIntent", которые позволяют значительно сократить код и сконцентрироваться только на реализации. 
    procedure TFormMain.fgApplicationEvents1ActivityNewIntent(Sender: TObject; const AIntent: TfgAndroidIntent); begin {$IFDEF ANDROID} TfgToast.Show(Format('Получен новый интент: intent=%s', [JStringToString(AIntent.toString)])); {$ENDIF} end; procedure TFormMain.fgApplicationEvents1ActivityResult(Sender: TObject; const ARequestCode, AResultCode: Integer; const AIntent: TfgAndroidIntent); begin {$IFDEF ANDROID} TfgToast.Show(Format('Получен результат из другого приложения: requestCode=%d, resultCode=%d', [ARequestCode, AResultCode])); {$ENDIF} end; TfgCollectionView
    Мы провели улучшение контроллера выделения элементов и предоставили больше гибкости в точной настройке поведения. Раньше при режиме выделения  "TfgCollectionViewSelectionMode = SingleSelect" мы не позволяли сбросить выделение элемента повторным нажатием. Это было сделано для возможности реализации меню с отображением текущего выбранного раздела. Однако, для некоторых пользователей такое поведение компонента было нежелательным.
    Теперь мы предлагаем вам самостоятельно решить, как должно работать выделение при помощи новых событий  "TfgCollectionView.OnItemCanSelect" и "TfgCollectionView.OnItemCanDeselect". Данные события вызываются непосредственно до момента установки или снятия выделения и позволяют отменить действие при помощи передаваемого параметра AAllow.
    Так же мы исправили ряд ошибок выделения на платформе iOS, так что теперь процесс выделения работает одинаково на всех платформах.
    ВАЖНО! Теперь по умолчанию компонент позволяет сбросить выделение элемента в режиме SingleSelect. 
    Заключении
    Желаем вам свершения всего задуманного, интересных проектов и амбициозных целей!
    Спасибо, что вы с нами!
  22. Yaroslav Brovin
    В этом году нас ждет большое количество новых компонентов и возможностей в библиотеке FGX Native: начиная о завершении добавления iOS платформы в библиотеки, продолжая всевозможными интеграциями мобильных сервисов (оплата, идентификация, встроенные покупки и тд) и заканчивая разработкой новых визуальных компонентов. 
    В последнем релизе 1.13.4.0 мы уже анонсировали добавление сервисов идентификации пользователя в сторонних сервисах. Сервисы идентификации позволяют получить информацию о пользователе используя его учетную запись в других сервисах, таких как GoogleId, AppleID, Facebook, VKontakte и тд. В релизе 1.13.4.0 мы разработали низкоуровневую кроссплатформенную архитектуру сервисов идентификации, которая позволяет нам и вам добавлять реализации любых сервисов идентификации пользователя. Первым таким сервисом стала реализация AppleID (TfgAppleIdAuthenticationClient). На подходе Facebook и другие сервисы. Детально о том, как установить и использовать разработанные компоненты мы поговорим в отдельных статьях.
    В этой статье нам хотелось бы поделиться одним очень мощным и полезным новым компонентом, которые позволит легко оживить ваше приложение и добавить в него сложные анимации. Речь пойдет о поддержке анимации Airbnb Lottie (https://airbnb.io/lottie)

     
    Немного о Lottie
    Lottie - это библиотека с открытым кодом от компании Airbnb для проигрывания анимации, созданной в приложении Adobe After Effects.
    Впервые дизайнеры могут создавать и доставлять красивые анимации без того, чтобы разработчик кропотливо воссоздавал их вручную.
    Анимация представляет собой текстовый файл в формате JSON, в котором содержится описание построения векторного изображения с анимацией. Благодаря чему, файл анимация весит очень мало при этом не теряя в качестве. 
    В библиотеку добавлен новый компонент TfgLottieImage, который позволяет отобразить Lottie анимацию.
    Как использовать?
    1. Для начала надо раздобыть файл анимации. Можно поискать готовые анимации от дизайнеров на ресурсе https://lottiefiles.com/ .

    Помимо этого ресурса, есть еще и другие. Например, ресурс по встраиванию анимированных иконок: https://lordicon.com/ 

    После выбора интересуемой анимации, скачиваем анимацию в формате Lottie JSON. Например, такая анимация ракеты весит всего 25 КБ:
    2022-02-15-00-47-28.mp4
    2. После этого добавляем этот файл анимации в дизайнер ресурсов FGX Native. Добавлен новый тип ресурса "Lottie Анимация":

    После создания нового ресурса, загружаем скаченный ранее файл. В результате чего дизайнер отобразит вам ваш файл анимации. Укажите ресурсу понятное имя, например "Animations\Red Rocket".

    Разместив на форме новый компонент TfgLottieImage, укажите ресурс анимации через свойство AnimationName. 

    Это все, что требуется, чтобы запустить ракету в космос. Запустив приложение на Android или iOS вы увидите летящую ракету.
    Lottie-Demo-Sample.mp4
    Демонстрационный пример
    В поставку включен новый демо-пример "Компоненты" -> "TfgLottieImage" -> "Проигрыватель Lottie анимации".
    Настройки 
    Компонент предлагает базовые настройки.
    ImageMode - Режим отображения изображения (растянуть, вписать, заполнить). Loop - нужно ли запускать анимацию по кругу. Speed - коэффициент скорости. Например: 2 - проигрывать анимацию в два раза быстрее, 0.5 - в два раза медленнее. Duration - длительность анимации в мсек (без учета Speed). Помимо этого, вы можете проверить проигрывается ли сейчас анимация IsAnimating или управлять воспроизведением через:
    Play - начать воспроизведение с начала Stop - остановить (Progress сбрасывается на начало). Pause - приостановить Resume - продолжить с текущего места. Progress - установить текущее место воспроизведения. Коэффициент из диапазона [0..1], где 0 - это начало, 1 - конец. Итоги
    Уверены, данная новинка найдет свое применение в ваших проектах и добавит им изюминки. 
  23. Yaroslav Brovin

    Общая
    Здравствуйте, уважаемые разработчики.
    В этом анонсе мы хотим познакомить вас с теми нововведениями, которые появятся в версии 1.14.0.0.
    Лицензии и коды активации
    Начиная с версии 1.14.0.0 библиотека будет содержать систему защиты, которая построена на кодах активации и файлах лицензий. Каждому клиенту с активной подпиской был выслан индивидуальный код активации на email, привязанный к его учетной записи. Если по какой-то причине вы не получили свой код активации - свяжитесь с нами любым удобным для вас способом.
    При старте Delphi с неактивированной версией библиотеки вам будет предложено ввести индивидуальный код активации.

    После ввода кода активации на сервере происходит привязка вашей лицензии к текущему компьютеру (необходимо наличие активного подключения к сети Интернет), библиотека получает индивидуальный лицензионный файл, который сохраняется на компьютере и однозначно подтверждает ваше право на использование библиотеки. После активации вы можете продолжать пользоваться продуктом как обычно. Информацию о статусе активации и сроке бесплатных обновлений вы можете найти в окне о Delphi: "Help" -> "About Embarcadero RAD Studio".

    Важные сведения, связанные с активацией библиотеки:
    Допускается 3 (три) активации библиотеки на разных физических машинах, исходя из усредненной схемы использования: домашний, рабочий компьютеры и одна активация на случай смены физических комплектующих вашего компьютера. Однако, если по каким-то объективным причинам у вас будет потребность в дополнительных активациях, вы всегда можете связаться с нами любым удобным для вас способом. Не используйте активацию на чужих/ненужных компьютерах. Активацию необходимо производить каждый раз после установки новой версии библиотеки. При этом каждая активация библиотеки на одной и той же машине не считается за отдельную активацию. При обновлении продукта или приобретении новой подписки, вам будет выслан новый код активации, который действует на новый срок. При этом старый код продолжает действовать для старых версий библиотеки, как и ранее. Увеличенные сроки действия подписки 
    В ближайшее время мы планируем расширить тарифные планы путем добавления подписок на 6 месяцев и 1 год. Детали о тарифах будут опубликованы позднее.
    Идентификация через сервис Google Sign in
    Мы продолжаем пополнять поддержку новых сервисов идентификации клиентов. В версии 1.14.0.0 предлагаем новый компонент TfgGoogleSignInAuthenticationClient для идентификации клиента через сервис "Google Sign in". На текущий момент компонент реализован для Android платформы.
    TfgCollectionView и ручное выделение 
    TfgCollectionView поддерживает разные режимы выделения элементов. Ранее при выделении элемента происходило визуальное отображение заднего фона всего элемента, согласно настройкам цвета SelectionColorName/SelectionColor. Однако, если вы используете в качестве элементов TfgCardPanel или другие виды контейнеров, то часто нужно выполнять изменение цвета не всего элемента, а только вложенного контейнера:
    Advanced_animation.mp4.1f5461e85ffcf2d14b43e8518ef918c3.mp4
    В версии 1.14.0.0 мы добавили возможность управлять внешним видом выделения элементов в ручном режиме, что открывает практически безграничные возможности по кастомизации. Новое свойство TfgCollectionView.SelectionOptions.DisplayingMode позволяет указать каким способом нужно отображать выделение. Доступно два способа отображения:
    Auto - обычный (старый) режим. Компонент берет на себя ответственность по изменению внешнего вида выделенных элементов путем изменения цвета заднего фона элемента. (по умолчанию) Manual - ручной режим. В этом режиме компонент делегирует разработчику работу по изменению внешнего вида выделенных элементов. О необходимости выделить/сбросить элемент компонент сообщает с помощью нового события OnUpdateItemSelectionAppearance. В ручном режиме вам необходимо выполнить визуальное выделение или сброс выделения у переданного элемента в событии OnUpdateItemSelectionAppearance. Это событие вызывается каждый раз, когда списку необходимо обновить состояние элемента. Среди аргументов события передается информация о:
    AItem - обертка для работы с элементом. AIsSelected - признак состояния выделения элемента. AInitiator - Кто инициатор обновления выделения элемента. Если вы хотите добавить анимации в процесс выделения элемента, то ориентируйтесь на этот флаг. Если пользователь нажимает на элемент, то в этом параметре будет значение "User", в противном случае "Control". Типичный код ручного выделения может выглядеть так:
    procedure TFormMain.fgCollectionView1UpdateItemSelectionAppearance(Sender: TObject; const AItem: TfgItemWrapper; const AIsSelected: Boolean; const AInitiator: TfgItemSelectionInitiator); var BackgroundPanel: TfgCardPanel; PrimaryLabel: TfgLabel; begin // Извлекаем ссылку на фон и текстовую метку в элементе BackgroundPanel := AItem.GetControlByLookupName<TfgCardPanel>('background'); PrimaryLabel := AItem.GetControlByLookupName<TfgLabel>('primary'); // Определяем параметры цвета выделения фона панели и цвета текста. if AIsSelected then begin BackgroundPanel.BackgroundColorName := R.Theme.Color.PRIMARY_LIGHT_PRIMARY; PrimaryLabel.ColorName := R.Theme.Color.ON_PRIMARY_TEXT; end else begin BackgroundPanel.BackgroundColorName := ''; PrimaryLabel.ColorName := ''; end; // Опционально, можно выполнить любую анимацию if AInitiator = TfgItemSelectionInitiator.User then BackgroundPanel.Shake; end; Добавлен новый демонстрационный пример: "Компоненты" -> "TfgCollectionView" -> "Ручное отображение выделения".
    TfgControlEnumerators
    Теперь доступны два энумератора по обходу дерева компонентов с возможностью управлять обходом. Оба энумератора доступы в классе TfgControlEnumerators.
    TfgControlEnumerators.Enum - Корень -> First..Last child TfgControlEnumerators.ReverseEnum - Корень -> Last..First child Например, обход по всем TfgEdit может выглядеть так:
    TfgControlEnumerators.Enum(Form,   procedure (const AChild: TfgControl; var AAction: TfgEnumControlsAction)   begin     if AChild is TfgEdit then       TfgLog.Debug(AChild.ToString);   end); Помимо обычного обхода есть возможность делать контролируемый обход. Например, поиск поля ввода:
    TfgControlEnumerators.Enum(Form,   procedure (const AChild: TfgControl; var AAction: TfgEnumControlsAction)   begin     if AChild is TfgEdit then     begin       TfgLog.Debug('Edit: ' + AChild.ToString);       AAction := TfgEnumControlsAction.Stop;     end     else       AAction := TfgEnumControlsAction.Continue;   end); Через параметр AAction анонимной функции можно передать дальнейшее направление действия по обходу компонентов:
    Continue - Перейти к следующему компоненту; Discard - Перейти к соседнему компоненту; Stop - Остановить обход. Маленькие приятности
    Теперь компоненты из групп "FGX: Standard" и "FGX: Layout" имеют свои оригинальные иконки, которые позволяют проще находить нужные компоненты в палитре компонентов.

     
  24. Yaroslav Brovin

    Общая
    Вот и прошло лето, а в месте с тем пришло время для крупного релиза, с которым мы вас с удовольствием познакомим.
    FlexBox дизайнер

    Система разметки FlexBox - универсальный инструмент, предлагающий довольно большой ряд редактируемых параметров, разобраться с которыми при первом приближении довольно сложно. В этом релизе мы разработали визуальный редактор параметров для контейнеров FlexBox, наглядно отображающий разные режимы выравнивания. Редактор доступен у свойства TfgLayout.AlignmentChildren, достаточно нажать на кнопку "..." у значения свойства AlignmentChildren любого компонента-контейнера. Он не просто показывает работу опций, но так же и адаптирует их при смене ориентации и тд.
    FlexBoxDesigner.mp4.fa3fd3bd9129367f28613c726623cc0b.mp4
    Переработанный дизайнер ресурсов
    В этом релизе мы полностью переработали дизайнер ресурсов, как внутри, так и снаружи. Добавили новые возможности и улучшили старые. Но обо всем по порядку.
    Автоматическое удаление "лишних" ресурсов
    В старой версии дизайнера при добавлении ресурса цвета создавалось 5 одинаковых ресурсов цвета для каждого типа устройств (Universal, Phone, NormalTablet, LargeTablet, ExtraLargeTablet). Однако, как показала практика,  пользователи используют на всех устройствах один и тот же цвет. Поэтому генерация одинаковых цветов нецелесообразна и с точки зрения дублирования, и с точки зрения скорости загрузки приложения и поиска ресурсов. В связи с этим, теперь дизайнер автоматически определяет дубликаты и удаляет их.
    Было:

    Стало:

    Генерация изображений
    Часто приложение начинает создаваться без наличия готового дизайна. Это в свою очередь усложняет разработку макета, так как зачастую заказчик визуально оценивает прототип. А для этого требуется искать подходящие графические изображения-заглушки, для использования в UI, чтобы разметка смотрелась законченно.
    Теперь можно сгенерировать изображение-заглушку по вашим параметрам и использовать его при проектировании приложения.


    Яркость изображения
    Улучшен алгоритм определения яркости изображений. Теперь более корректно определяется контрастный цвет фона для предварительного просмотра. Напомним, если иконка/изображение использует белые оттенки цветов (светлая), то для предварительного просмотра подбирается темный фон и наоборот.


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


    Умное отображение цвета
    Если ресурс цвета содержит известный код цвета, то вместо кода отображается название цвета. При наведении курсора мыши на превью цвета, отображается ARGB раскладка цвета.

     
    Отображение превью
    Немного увеличен размер предварительного просмотра ресурсов. Так же, если содержимое ресурса не загружено, то вместо фона шахматной доски отображается только пунктирная рамка. Если изображения не загружены для всех коэффициентов масштабирования, то для таких изображений отображается рекомендованный размер с учетом базового размера.

    Улучшения в TfgButton
    Добавлено верхнее и нижнее положение иконки относительно текста. Теперь можно делать кнопки для нижней панели навигации без дополнительных комбинация стандартных компонентов.

    20220904_174816.mp4
    Многопоточный режим TfgPickerPhoto
    При использование в пикере выбора фотографий устройства множественного выбора, процесс извлечения фотографий в вашем приложении мог занимать много времени (в зависимости от количества изображений и их размера). При этом приложение зависало до конца обработки всех фотографий. В этом релизе мы добавили многопоточную загрузки изображений и ускорили их обработку. Чтобы пользователь понимал, что процесс может занимать длительное время, мы добавили анонимную функцию для возможности контроля процесса обработки.
    TfgPickerPhotoFactory.PickPhotosFromLibrary(btnTakePhotoFromLibrary, procedure(const AFileNames: TfgPhotoFiles) begin LoadImages(AFileNames); end, procedure(const AProgress: Single) begin ShowProgress(AProgress); end); Поддержка Android 12
    Добавлена поддержка Android 12. Для корректной публикации приложений в "Google Play Market", необходимо обновить манифест Android приложения. При открытии старого приложения, IDE предложит обновить манифест автоматически. Если вы вносили ручные правки в шаблон манифеста приложения, то перед обновлением манифеста сделайте его копию и затем заново внесите ваши правки. 
    Если по каким-то причинам среда не предложила обновить манифест (если вы ранее отказались от обновления шаблона), то вы можете это сделать вручную. Для этого необходимо добавить атрибут `android:exported="true"` в узел `activity`.

    Delphi 11 Update 2
    Добавлена поддержка Delphi 11 Update 2. Из-за критических изменений на стороне IDE, перестали собираться приложения FGX Native из-за нарушения целостности в Deployment Manager. Данный релиз устраняет эту проблему.
    Надеемся, что новый функционал придется вам по душе и облегчит процесс разработки. Через релиз мы выпустим поддержку стилей, которые значительно упростят процесс верстки интерфейса вашего приложения в дизайнере.
×
×
  • Create New...