<?xml version="1.0"?>
<rss version="2.0"><channel><title>Guides</title><link>https://forum.fgx-native.com/blogs/blog/3-%D1%80%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%B0/</link><description></description><language>en</language><item><title>[&#x420;&#x443;&#x43A;&#x43E;&#x432;&#x43E;&#x434;&#x441;&#x442;&#x432;&#x43E;] &#x422;&#x435;&#x43C;&#x44B; &#x432; FGX Native &#x432; 1.19.0.0</title><link>https://forum.fgx-native.com/blogs/entry/74-%D1%80%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE-%D1%82%D0%B5%D0%BC%D1%8B-%D0%B2-fgx-native-%D0%B2-11900/</link><description><![CDATA[<p>
	Данная статья является полной информацией о темах в <strong>FGX Native</strong> и актуальным руководством, начиная с <strong>1.19.0.0</strong>.
</p>

<ol>
	<li>
		<strong>Введение</strong>

		<ol>
			<li>
				<strong>Виды тем</strong>
			</li>
			<li>
				<strong>Акцентный цвет</strong>
			</li>
			<li>
				<strong>Системная тема и тема приложения</strong>
			</li>
		</ol>
	</li>
	<li>
		<strong>Системная тема</strong>
		<ol>
			<li>
				<strong>Получение параметров системной темы</strong>
			</li>
			<li>
				<strong>Механизмы отслеживания системной темы</strong>
			</li>
			<li>
				<strong>Как управлять системной темой в приложении</strong>
			</li>
			<li>
				<strong>Запрет автоматической смены системной темы в приложении</strong>
			</li>
			<li>
				<b>Темная тема</b>
			</li>
		</ol>
	</li>
	<li>
		<strong>Тема FGX Native</strong>
		<ol>
			<li>
				<strong>Цветовая система Material Design</strong>
				<ol>
					<li>
						<strong>Основной цвет</strong>
					</li>
					<li>
						<strong>Вторичный цвет</strong>
					</li>
					<li>
						<strong>Цвета поверхности, фона и ошибок</strong>
					</li>
					<li>
						<strong>Цвета "На"</strong>
					</li>
					<li>
						<strong>Альтернативные цвета</strong>
					</li>
					<li>
						<strong>Прочее</strong>
					</li>
				</ol>
			</li>
			<li>
				<strong>Генерация темы в FGX Native</strong>
			</li>
			<li>
				<strong>Применение темы</strong>
				<ol>
					<li>
						<strong>Приложение</strong>
					</li>
					<li>
						<strong>Форма</strong>
					</li>
					<li>
						<strong>Принцип смены темы</strong>
					</li>
				</ol>
			</li>
			<li>
				<strong>Использование ресурсов темы</strong>
				<ol>
					<li>
						<strong>Типы значений</strong>
					</li>
					<li>
						<strong>Приоритет</strong>
					</li>
					<li>
						<strong>Применение ресурсов темы</strong>
					</li>
					<li>
						<strong>Фиксация темы</strong>
					</li>
				</ol>
			</li>
			<li>
				<strong>Расширение темы</strong>
			</li>
		</ol>
	</li>
	<li>
		<strong>Пример разработки приложения с поддержкой темной и светлой тем и разных цветовых оттенков.</strong>
		<ol>
			<li>
				<strong>Создание тем в дизайнере ресурсов</strong>
			</li>
			<li>
				<strong>Настройки тем в проекте</strong>
			</li>
			<li>
				<strong>Программная смена тем и акцентированного цвета</strong>
			</li>
		</ol>
	</li>
	<li>
		<strong>Советы</strong>
	</li>
</ol>

<hr>
<p>
	<strong><span style="font-size:22px;">1. Введение</span></strong>
</p>

<p>
	<strong>Тема</strong> — это совокупность настроек, цветов, звуков, шрифтов, курсоров, иконок, фоновых изображений и других элементов, отвечающих за интерфейс приложения.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="5314" href="https://forum.fgx-native.com/uploads/monthly_2025_04/Themes.jpg.9d051d61e0cb289e7228371fe8322496.jpg" rel=""><img alt="Themes.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="5314" data-unique="mhpggx4mw" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_04/Themes.thumb.jpg.0f35349acbbdfa43134e51a74f6158e8.jpg" loading="lazy" height="550"></a>
</p>

<p>
	<span style="font-size:20px;">1.1 Виды тем</span>
</p>

<p>
	В современном мире обычно различают два <strong>вида тем</strong>:
</p>

<ol>
	<li>
		<strong>Светлая тема</strong> - преимущественно использует светлые цвета в UI.
	</li>
	<li>
		<strong>Темная тема</strong> - преимущественно использует темные цвета в UI.
	</li>
</ol>

<p>
	Именно эти два вида распространены в Android и iOS. Далее, в каждом виде могут быть уже темы разных цветовых палитр, с разными акцентными цветами и т.д.
</p>

<p>
	<span style="font-size:20px;">1.2 Акцентный цвет</span>
</p>

<p>
	<strong>Акцентный цвет</strong> - это дополнительный цвет, который контрастирует или дополняет основные цвета, используемые в приложения. По умолчанию, в iOS такой цвет голубой, а в Android - изумрудный.
</p>

<p>
	Вот некоторые задачи, для которых используют акцентные цвета:
</p>

<ul>
	<li>
		<strong>Привлечение внимания</strong>. Яркий акцентный цвет привлекает взгляд пользователей и помогает им ориентироваться на странице.
	</li>
	<li>
		<strong>Организация информации</strong>. Использование акцентного цвета для заголовков и подзаголовков помогает организовать информацию на странице и делает её более понятной для пользователей.
	</li>
	<li>
		<strong>Выделение важных элементов</strong>. Акцентный цвет помогает выделить важные элементы, такие как акционные предложения или срочные сообщения, и привлечь внимание пользователей к ним.
	</li>
</ul>

<p>
	При выборе акцентного цвета часто используют правило 60-30-10: 60% — основной цвет, 30% — акцентный, 10% — второй акцентный цвет, если он имеется.
</p>

<p>
	<span style="font-size:20px;">1.3 Системная тема и тема приложения</span>
</p>

<p>
	В дальнейшем, когда мы будем говорить про тему, то мы будем рассматривать два типа тем:
</p>

<ol>
	<li>
		<strong>Системная тема</strong> (Обязательная). Это та, которая поставляется вместе с операционной системой и все приложения используют ее по умолчанию.
	</li>
	<li>
		<strong>Тема приложения</strong> (Необязательная). Это та, которая поставляется вместе с приложением и предназначена для переопределения системной темы.
	</li>
</ol>

<p>
	<strong><span style="font-size:22px;">2. Системная тема</span></strong>
</p>

<p>
	Тема операционной системы / системная тема — это совокупность настроек, цветов, звуков, шрифтов, курсоров, иконок, фоновых изображений и других элементов, отвечающих за интерфейс ОС. Эти ресурсы уже включены в дистрибутив операционной системы. Практически каждое приложение прямо или косвенно использует эти ресурсы. При запуске приложения, каждый компонент выбирает цвета, настройки шрифтов и многое другое из текущей темы системы.
</p>

<p>
	Разработчик может оставить внешнее отображение компонентов, как есть, доверив их системе. Либо же, может переопределить их на уровне своего приложения и настроить внешний вид уже так, как он хочет на уровне темы приложения. 
</p>

<p>
	В любом случае, получение параметров системной темы, может пригодиться для динамической настройки внешнего вида вашего приложения.
</p>

<p>
	<span style="font-size:20px;">2.1 Получение параметров системной темы</span>
</p>

<p>
	В <strong>FGX Native</strong> предоставляет кроссплатформенный механизм для получения некоторых параметров системной темы и отслеживания их изменения. В любой момент времени вы можете запросить параметры системной темы через <strong>FGX.SystemInfo.TfgSystemInfo.Appearance</strong>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7023_9" style=""><span class="pln">  /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Данные о отображении операционной системы.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
  TfgSystemAppearance = class
  private
    function GetSystemColor(const Index: TfgSystemColorType): TAlphaColor;
    function GetThemeKind: TfgSystemThemeKind;
  public
    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">
    ///   Акцентный цвет операционной системы. Обычно используется для подчеркивания элементов компонентов.
    /// </span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    property AccentColor: TAlphaColor index TfgSystemColorType.Accent read GetSystemColor;
    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Вид системной темы.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    property ThemeKind: TfgSystemThemeKind read GetThemeKind;
  end;</span></pre>

<ul>
	<li>
		<strong>ThemeKind</strong> - вид системной темы (Светлая/Темная). 
	</li>
	<li>
		<strong>AccentColor</strong> - акцентный цвет в текущей теме.
	</li>
</ul>

<p>
	В случае, если вам понадобятся другие параметры системной темы, пожалуйста, дайте нам об этом знать и оставьте заявку через <a href="https://forum.fgx-native.com/tickets/opened/%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9/" rel="">Feature Request</a>.
</p>

<p>
	<span style="font-size:20px;">2.2 Механизмы отслеживания изменений системной темы.</span>
</p>

<p>
	При изменении любых параметров системной темы, которые влияют на приложение, система оповещает приложение о таких изменениях. Эти изменения можно узнать следующими способами:
</p>

<p>
	<strong>Первый способ:</strong> На уровне формы есть событие <strong>TfgForm.OnSystemAppearanceChanged</strong>, которое вызывается каждый раз, когда меняется один из параметров отображения системной темы.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7023_7" style=""><span class="pln">TfgSystemAppearanceChangedEvent = procedure(Sender: TObject; const AAppearance: TfgSystemAppearance) of object;</span></pre>

<p>
	В параметре <strong>AAppearance (FGX.Platform.TfgSystemAppearance)</strong> передается объект, позволяющий извлечь базовую информацию о теме.
</p>

<p>
	Для удобства, это событие вызывается всегда один раз при первом отображении формы. Это сделано, чтобы вы могли поместить код по адаптации внешнего вида формы в одно место без необходимости отдельно запрашивать текущие параметры системной темы.
</p>

<p>
	<strong>Второй способ</strong>: Если вы хотите отслеживать изменения в системной теме вне формы, то вы можете подписаться на широковещательную рассылку на сообщение <strong>FGX.Platform.TfgSystemAppearanceChangedMessage</strong>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7023_13" style=""><span class="pln">/// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Уведомление о смене системной темы.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
TfgSystemAppearanceChangedMessage = class(TObjectMessage</span><span class="tag">&lt;TfgSystemAppearance&gt;</span><span class="pln">);</span></pre>

<p>
	Полученный объект <strong>TfgSystemAppearance</strong> удалять не нужно.
</p>

<p>
	<span style="font-size:20px;">2.3 Управление системной темой в приложении.</span>
</p>

<p>
	Как мы упомянули выше, системная тема определяет внешний вид вашего приложения по умолчанию. Однако, пользователи вашего приложения могут иметь свои предпочтения в использовании светлой или темной темы в рамках вашего приложения. И поэтому FGX Native предлагает механизм для указания этого предпочтения.
</p>

<p>
	Управление применением системной темой к приложению осуществляется при помощи настроек <strong>Application.Themes</strong>. Вид системной темы указывается в свойстве: <strong>Application.Themes.Kind</strong>.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7023_15" style=""><span class="pln">  TfgThemeKind = (SystemDefault, Light, Dark);</span></pre>

<p>
	Допускает три варианта значений:
</p>

<ol>
	<li>
		<strong>Light </strong>- приложение использует светлую тему.
	</li>
	<li>
		<strong>Dark </strong>- приложение использует темную тему.
	</li>
	<li>
		<strong>SystemDefault </strong>- приложение использует такую же тему, как и в системе. При смене темы в системе, автоматически изменится тема и в приложении. Только, если приложение поддерживает темную тему (смотри следующий раздел).
	</li>
</ol>

<p>
	<span style="font-size:20px;">2.4 Запрет автоматической смены темы в приложении</span>
</p>

<p>
	Если ваше приложение не поддерживает темную тему. Например, если вы используете свой дизайн или вы не предусмотрели отображение приложения в темной теме, то вы можете отключить темную тему для приложения, чтобы приложение не пыталось её использовать. Это выполняется в настройках проекта Project -&gt; FGX Options -&gt; Приложение -&gt; Темы. Необходимо снять галку "<strong>Включить темную тему</strong>".
</p>

<p>
	<span style="font-size:20px;">2.5 Темная тема</span>
</p>

<p>
	Не смотря на то, что темная системная тема появилась относительно давно, ее полноценная поддержка есть не на всех версиях.
</p>

<ul>
	<li>
		iOS 13.0+. До 13 версии поддержки нет.
	</li>
	<li>
		Android 10+ (Level 29+). До 10 версии есть только адаптация.
	</li>
</ul>

<p>
	<strong><span style="font-size:22px;">3. Тема FGX Native</span></strong>
</p>

<p>
	Тема FGX Native представляет собой ни что иное, как заранее определенный набор цветовых ресурсов, которые помещены в одну папку и имеют относительно этой папки "известные" для FGX Native названия. В качестве цветовой системы использует цветовая системы <strong>Material Design</strong> 2.0 по умолчанию. Не смотря на это, вы можете использовать свои цветовые системы, которые вам могут быть удобнее. Выбор в большей степени зависит от вашего дизайна приложения.
</p>

<p>
	Прежде, чем перейти непосредственно к использованию темы в FGX Native, следует разобраться с принципом построения и использования системы <strong>Material Design</strong>.  
</p>

<p>
	<span style="font-size:20px;">3.1 Цветовая система Material Design</span>
</p>

<p>
	<strong>Примечание</strong>: Данный текст частично взят и переработан с учетом специфики FGX Native <a href="https://m2.material.io/design/color/the-color-system.html" rel="external nofollow" target="_blank">с официального сайта</a> <strong>Material Design</strong>.
</p>

<p>
	Система цветов помогает вам применять цвета в UI вашего приложения осмысленным образом. В системе Material Design 2.0 вы выбираете основной (<strong>Primary</strong>) и дополнительный (<strong>Secondary</strong>) цвета для представления вашего бренда. Затем на основании этих двух цветов строятся все остальные цвета, включая темные и светлые варианты каждого цвета.
</p>

<p>
	Базовая цветовая тема состоит из следующих цветов:
</p>

<ol>
	<li>
		Первичный/Основной (<strong>Primary</strong>) и вторичный (<strong>Secondary</strong>) цвета.
	</li>
	<li>
		Варианты основных и дополнительных цветов (<strong>Primary Varian</strong>, <strong>Secondary Variant</strong>). Эти цвета в FGX Native имеют следующие названия:  
		<ol>
			<li>
				"<strong>Primary\Dark Primary</strong>", "<strong>Secondary\Dark Primary</strong>" - Темный вариант основного и вторичного цветов
			</li>
			<li>
				"<strong>Primary\Light Primary</strong>", "<strong>Secondary\Light Primary</strong>" - Светлый вариант основного и вторичного цветов
			</li>
		</ol>
	</li>
	<li>
		Дополнительные цвета пользовательского интерфейса, такие как цвета фона, поверхностей, ошибок, типографики и иконок.
	</li>
</ol>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5282" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.6888495be43106bf28661565257f278c.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5282" data-unique="3vktavqmt" style="height: auto; width: 800px;" width="829" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.9246fa9ec8bf2efbd58ac221e5b18b94.png" loading="lazy" height="746.1"></a>
</p>

<p>
	<span style="font-size:18px;">3.1.1. Основной цвет</span>
</p>

<p>
	<span style="background-color: rgb( var(--theme-area_background_reset) ); color: rgb( var(--theme-text_color) );">Это цвет, который чаще всего отображается на экранах и в компонентах вашего приложения. Он же используется как акцентированный цвет для многих компонентов.</span>
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5283" data-unique="73wxnsywq" style="width: 300px; height: auto;" width="574" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.9f18d8b1ffcc8d9fb600e6e69252e863.png" loading="lazy" height="103.32">
</p>

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

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5284" data-unique="ws9c232al" style="width: 440px; height: auto;" width="840" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.c30a7917841b9a55e96339a3eed392da.png" loading="lazy" height="201.6">
</p>

<p>
	<span style="font-size:18px;">3.1.2 Вторичный цвет</span>
</p>

<p>
	Вторичный цвет обеспечивает больше возможностей для акцентирования и выделения вашего продукта. Наличие вторичного цвета необязательно и должно применяться умеренно для акцентирования выбранных частей вашего пользовательского интерфейса.
</p>

<p>
	Если у вас нет вторичного цвета, основной цвет также можно использовать для акцентирования элементов.
</p>

<p>
	Вторичные цвета лучше всего подходят для:
</p>

<ul>
	<li>
		Плавающие кнопки действий
	</li>
	<li>
		Элементы управления выбором, такие как ползунки и переключатели
	</li>
	<li>
		Выделение выделенного текста
	</li>
	<li>
		Индикаторы прогресса
	</li>
	<li>
		Ссылки и заголовки
	</li>
</ul>

<p>
	Как и основной цвет, ваш вторичный цвет может иметь темные и светлые варианты. Цветовая тема может использовать ваш основной цвет, вторичный цвет и темные и светлые варианты каждого цвета.
</p>

<p>
	<span style="font-size:18px;">3.1.3 Цвета поверхности / фона и ошибок</span>
</p>

<p>
	Цвета поверхности, фона и ошибок обычно не представляют бренд и не зависят от основного и вторичного цветов. Однако, именно они и добавляют визуального порядка в пользовательском интерфейсе:
</p>

<ul>
	<li>
		<strong>Цвета поверхности (Surface)</strong> влияют на поверхности компонентов, таких как карточки <strong>TfgForm </strong>/ <strong>TfgCardPanel</strong> / <strong>TfgBottomSheetLayout </strong>/ <strong>TfgDrawerLayout</strong>, списки <strong>TfgCollectionView</strong>/<strong>TfgListMenu </strong>и меню.
	</li>
	<li>
		<strong>Цвет фона (Background)</strong> отображается за прокручиваемым содержимым. Базовый фон и цвет поверхности — #FFFFFF.
	</li>
	<li>
		<strong>Цвет ошибки (Error)</strong> указывает на ошибки в компонентах, такие как недопустимый текст в текстовом поле. Базовый цвет ошибки — #B00020.
	</li>
</ul>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5285" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.4fd8e0cefb774576468265c0fc3e85f1.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5285" data-unique="e45c98hv3" style="width: 500px; height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.4332e7e0ce92f3e960f23f37acc2f3aa.png" loading="lazy" height="730"></a>
</p>

<p>
	Если попробовать упростить эту модель и перенести ее на компоненты FGX Native, то можно выделить основные правила использования:
</p>

<ol>
	<li>
		<strong>Background </strong>обычно используется, как самый задний цвет контейнера верхнего уровня. Например, <strong>TfgForm</strong>.
	</li>
	<li>
		<strong>Surface </strong>используется, как цвет заднего фона для контейнеров, которые лежат на контейнере с фоном <strong>Background</strong>. Чаще всего это <strong>TfgCardPanel</strong>, <strong>TfgBottomSheetLayout</strong>
	</li>
</ol>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5286" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.306f6804b74c7f6a81fd38a7365a3c2e.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5286" data-unique="ogszq1jdz" style="height: auto;" width="588" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.e858def11b00b0c0f7ea1d3755c78266.png" loading="lazy" height="746.76"></a>
</p>

<p>
	<span style="font-size:18px;">3.1.4 Цвета На/On</span>
</p>

<p>
	Поверхности приложений используют цвета из определенных категорий в вашей цветовой палитре, например, основной цвет. Всякий раз, когда элементы, такие как текст или иконки, появляются перед этими поверхностями, эти элементы должны использовать цвета, разработанные так, чтобы быть четкими и разборчивыми по сравнению с цветами позади них.
</p>

<p>
	Эта категория цветов называется «<strong>На/On</strong>» цветами, ссылаясь на тот факт, что они окрашивают элементы, которые появляются «на» поверх поверхностей и используют следующие цвета: основной цвет, вторичный цвет, цвет поверхности, фоновый цвет или цвет ошибки. Когда цвет появляется «на» поверх основного цвета, он называется «над основным цветом». Они маркируются с использованием исходной цветовой категории (например, основной цвет) с префиксом «On».
</p>

<p>
	«On» цвета применяются в основном к тексту, иконографии и штрихам. Иногда они применяются к поверхностям.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5287" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.38e81f32c03d47fb47857fc1499c1b53.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5287" data-unique="vgd4xsdls" style="height: auto;" width="750" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.c0bddbdf7eb060c2608181f666749d94.png" loading="lazy" height="750"></a>
</p>

<p>
	Такие цвета есть для всех цветов: основного, вторичного, поверхности, фона и ошибок цветов. В FGX Native такой набор состоит из 6 цветов:
</p>

<ol>
	<li>
		<strong>Text </strong>- основной цвет текст. 
	</li>
	<li>
		<strong>Secondary Text</strong> - цвет дополнительного текста. Используется для выделения второстепенной текстовой информации, как примечание, подзаголовок и тд.
	</li>
	<li>
		<strong>Icon </strong>- цветовой оттенок иконок, отображаемых на текущем цвете.
	</li>
	<li>
		<strong>Dividers </strong>- цвет полосок разделителей. Например, полоса-разделитель элементов в списке <strong>TfgCollectionView</strong>.
	</li>
	<li>
		<strong>Hint Text</strong> - цвет текста для подсказки ввода текста в поля ввода (<strong>TextPrompt</strong>)
	</li>
	<li>
		<strong>Disabled Text</strong> - текст на компонентах, не доступных для взаимодействия.
	</li>
</ol>

<p>
	Пример ниже иллюстрирует ручное применение цветов темы для элементов кнопки. Если кнопка использует основной цвет <strong>"Primary"</strong>, как фон. То, соответственно, иконка и текста должны использовать цвета из группы цветов "<strong>On Primary</strong>"
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5288" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.240ea91ba053cde0fd1839809eb0566e.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5288" data-unique="ggryn3fvd" style="height: auto;" width="625" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.0b7a166bcff77c6bcecc430a3f8561d0.png" loading="lazy" height="750"></a>
</p>

<p>
	<span style="font-size:18px;">3.1.5 Альтернативные цвета</span>
</p>

<p>
	Используемая цветовая система является рекомендованной, но не обязательной. Вы всегда можете, как добавить в нее дополнительные основные "<strong>Primary</strong>" цвета, чтобы расширить разнообразие цветов, так и использовать любую другую, например из Material Design 3.0. 
</p>

<p>
	Например, приложение <strong>LEDPanel</strong> из <a href="https://forum.fgx-native.com/blogs/entry/68-codegear-a-smart-backpack-controlled-from-a-mobile-application-with-fgx-native/" rel="">выступления про разработку приложения</a>, как раз демонстрирует использование альтернативной цветовой системы:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5290" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.74b5e27faf3e37b6b4ef5608351a5992.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5290" data-unique="qewhaa0a3" style="width: 200px; height: auto;" width="340" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.c44608e3864e0cbbe772562d333ec468.png" loading="lazy" height="748"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5292" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.e9ac43f0d248df496d4422517e560b47.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5292" data-unique="2nyhgh4sx" style="width: 206px; height: auto;" width="351" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.a9a9489d57e1aab8b8a9f0e4ed508312.png" loading="lazy" height="747.63"></a>
</p>

<p>
	<span style="font-size:18px;">3.1.6 Прочее</span>
</p>

<p>
	Об остальных вариантах использования цветов и правил их применения следует обратиться к официальной документации.
</p>

<ul>
	<li>
		<a href="https://m2.material.io/design/color/applying-color-to-ui.html#usage" rel="external nofollow">Официальная документация</a>
	</li>
</ul>

<p>
	<span style="font-size:20px;">3.2 Генерация темы FGX Native</span>
</p>

<p>
	Для того, чтобы добавить тему буквально в один клик, мы предлагаем генератор темы в дизайнере ресурсов (Project -&gt; FGX Assets Manager). Он доступен либо в контекстном меню дерева ресурсов "Сгенерировать тему" <img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5293" data-unique="vp6oz6wu2" style="width: 18px; height: auto;" width="37" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.840dda155dc3f0abc494e14b9ea057e3.png" loading="lazy" height="38.85">, либо через соответствующую иконку на панели инструментов.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5294" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.22556512a63b6512ee36362229c746b4.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5294" data-unique="hu1q6qws8" style="height: auto;" width="761" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.2d42c72dd49794a92202200ddbcb2088.png" loading="lazy" height="745.78"></a>
</p>

<p>
	В самом верху окна вам необходимо выбрать <strong>тип темы</strong>. Здесь все просто: "светлая" или "темная".
</p>

<p>
	Затем выбираете два базовых цвета: Основной <strong>Primary/P</strong> и Вторичный <strong>Secondary/S</strong> цвета. Левой кнопкой мыши выбирается основной цвет <strong>P</strong>, а правой - вторичный <strong>S</strong>.
</p>

<p>
	При выборе основных цветов, генератор автоматически определяет оттенок группы цветов "<strong>On</strong>" используемой на каждом из двух цветов. При необходимости вы можете откорректировать группы при помощи радиокнопок внизу. Если основной цвет яркий, то для соблюдения контраста, все элемента отображаемые На ярком цвете, должны быть темными и наоборот. После нажатия на кнопку "Сгенерировать", мы получаем наборы цветом согласно системе цветов Material Design.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5296" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.fddd11f0ffe8b947f3d2bc549c21ecf6.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5296" data-unique="dhx7syebh" style="width: 200px; height: auto;" width="301" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.be0a533003edf2a44dff6f9a104c2035.png" loading="lazy" height="749.49"></a>
</p>

<p>
	Если вы планируете использовать несколько тем в вашем приложении, мы рекомендуем группировать темы по типу (Светлая / Темная) и цветовым оттенкам. Например, так:
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5262" data-unique="yvpd1ksn9" style="width: 200px; height: auto;" width="484" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.b34945c9c832a229cac234a3dbbec99b.png" loading="lazy" height="392.04">
</p>

<p>
	Обратите внимание, что если вы хотите использовать темы вашем приложении, то вам как минимум надо сгенерировать светлую тем, а максимум, добавить еще и темную.
</p>

<p>
	<span style="font-size:20px;">3.3 Применение темы</span>
</p>

<p>
	В FGX Native тема может применяться на двух уровнях:
</p>

<ol>
	<li>
		Приложение
	</li>
	<li>
		Форма
	</li>
</ol>

<p>
	<span style="font-size:18px;">3.3.1 Приложение</span>
</p>

<p>
	Тема, применяемая на уровне приложения автоматически применяется ко всем формам и ко всем компонентам. Кроме случаев, о которых будет сказано далее. 
</p>

<p>
	Тема может быть задана двумя способами.
</p>

<p>
	<em><strong>1. На уровне настроек проекта (DesignTime) с 1.19.0.0:</strong></em> Этот основной способ и он позволяет применить тему, как в дизайнере, так и автоматически на старте приложения на устройстве.
</p>

<p>
	Чтобы задать тему на уровне приложения, нужно зайти в настройки проекта Project -&gt; FGX Options... -&gt; Приложение -&gt; Темы
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5297" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.0a5826ce03ea0da7c31a161dcb02845e.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5297" data-unique="w56ub4n00" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.c8917a1a5fe69a47a0493ed5b7f52a95.png" loading="lazy" height="650"></a>
</p>

<p>
	В поле (1) мы можем указать способ выбора темы при старте приложения. Доступны три варианта:
</p>

<ol>
	<li>
		<strong>Согласно системной теме</strong>. Если на устройстве используется светлая тема, то будет использоваться светлая тема в приложении, если же в системе используется темная, то в приложении автоматически будет применена темная тема
	</li>
	<li>
		<strong>Светлая </strong>- Независимо от системной темы, внутри приложения будет использовать светлая тема. 
	</li>
	<li>
		<strong>Темная </strong>- Независимо от системной темы, внутри приложения будет использовать темная тема. 
	</li>
</ol>

<p>
	В поле (2) указываем название светлой FGX Native темы из дизайнера ресурсов. Если вы использовали нашу рекомендацию по группировке и именованию тем, то это может быть "<strong>Themes\Light\Green</strong>" (Светлая тема с зеленым основным цветов).
</p>

<p>
	В поле (3) включаем или отключаем поддержку темной темы в приложении. Возможно, ваш дизайн приложения не предусматривает темную тему или у вас ее нет. В этом случае, необходимо убедиться, что галка с этого поля снята.
</p>

<p>
	В поле (4) указываем название темной темы из дизайнера ресурсов (если включена поддержка темной темы).
</p>

<p>
	В момент старта приложения FGX Native применяет тему согласно вашим настройкам. Например, вот так:
</p>

<p>
	 <a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5270" href="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074208.png.b64851ccccaac9abda20a63a5153947a.png" rel=""><img alt="Screenshot_20250328-074208.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5270" data-unique="dyef9183g" style="width: 300px; height: auto;" width="337" src="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074208.thumb.png.c20517f99a468aafaae7b3a0153827e1.png" loading="lazy" height="748.14"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5272" href="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074226.png.14bf1a22e4116bb0bb4cae16a34f3a2d.png" rel=""><img alt="Screenshot_20250328-074226.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5272" data-unique="h58kq5eig" style="width: 300px; height: auto;" width="337" src="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074226.thumb.png.4475ce94677a8b6d1d4eb405d5a8aa1b.png" loading="lazy" height="748.14"></a>
</p>

<p>
	<strong>В режиме выполнения (Runtime):</strong> Этот способ может использоваться, если вы хотите позволить пользователю менять вашу тему в соответствии с его предпочтениями. За настройки темы (аналогичные 3.3.1) отвечает свойство <strong>Application.ThemeSettings</strong>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2963_13" style=""><span class="pln">/// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Название светлой темы FGX Native, используемой по умолчанию во всех формах.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
property LightThemeName: TfgThemeName read FLightThemeName write SetLightThemeName;
/// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Название темной темы FGX Native, используемой по умолчанию во всех формах.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
property DarkThemeName: TfgThemeName read FDarkThemeName write SetDarkThemeName;
/// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Применяемая тема по умолчанию.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
property ThemeKind: TfgThemeKind read FThemeKind write SetThemeKind;</span></pre>

<p>
	По сути здесь те же свойства, что и в настройках проектах, кроме возможность отключить темную тему во всем приложении.
</p>

<p>
	Например, если вы хотите добавить несколько вариантов тем для разных акцентных цветов, то вы можете это сделать так (если вы используете предложенные вариант группировки тем в дизайнере ресурсов)
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2963_15" style=""><span class="pln">  Application.ThemeSettings.LightThemeName := 'Themes\Light\' + AccentColorName;
  Application.ThemeSettings.DarkThemeName := 'Themes\Dark\' + AccentColorName;</span></pre>

<p>
	В любой момент времени, изменяя название темы приведет к автоматическом применению темы ко всему приложению.
</p>

<p>
	Узнать используемое в текущий момент времени название темы приложения можно через <strong>Application.ThemeName</strong>.
</p>

<p>
	<span style="font-size:18px;">3.3.2 Форма</span>
</p>

<p>
	Если по каким-то соображениям, вы не хотите, чтобы на каком-то экране/форме у вас использовалась тема приложения, вы можете ее переопределить локально на уровне формы, указав ее имя в свойстве <strong>TfgForm.ThemeName</strong>:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5298" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.0cec2ac03f42dfd782fd2a56d09c6658.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5298" data-unique="092kgo4jx" style="width: 800px; height: auto;" width="999" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.96f5f226e2dd0995dbc01df0a1e8372c.png" loading="lazy" height="839.16"></a>
</p>

<p>
	В этом случае все вложенные компоненты будут автоматически использовать тему формы, а не приложения.
</p>

<p>
	<span style="font-size:18px;">3.3.3 Принцип смены темы</span>
</p>

<p>
	Когда меняется тема в приложении или локально в рамках одной формы, форма сообщает всем компонентам дерева о необходимости сменить тему. У каждого компонента вызывается виртуальный метод <strong>TfgControl.ThemeChanged</strong> и передается имя новой темы "<strong>AThemeName</strong>":
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8760_7" style=""><span class="pln">/// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Информирует, что изменена тема и следует обновить связи с ресурсами.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
procedure ThemeChanged(const AThemeName: TfgThemeName); virtual;</span></pre>

<p>
	Затем каждый компонент в зависимости от набора настроек выполняет применение новой темы к свойствам. Например, каждый компонент имеет задний фон <strong>BackgroundName</strong>, который поддерживает темизацию. Поэтому базовая реализация вызывает метод для установки нового имени темы для фона при помощи <strong>BackgroundLink.ChangeTheme </strong>(<strong>BackgroundLink </strong>- это сущность, связывающая ресурс фона с компонентом).
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8760_9" style=""><span class="pln">procedure TfgControl.ThemeChanged(const AThemeName: TfgThemeName);
begin
  TfgAssert.IsNotNil(BackgroundLink, 'BackgroundLink');

  if TfgDebugAssetsOption.Themes in TfgLibraryDiagnostics.DebugAssetsOptions then
    TfgLog.Trace(ThemesTag, SThemesApplyingNewTheme, [ToString, AThemeName]);

  BackgroundLink.ChangeTheme(AThemeName);
  SendMessage</span><span class="tag">&lt;TfgThemeName&gt;</span><span class="pln">(TfgControlMessages.WM_THEME_CHANGED, AThemeName);
end;</span></pre>

<p>
	Если в имени ресурса используется указание на использование темы (наличие ":", как разделитель между название темы и ресурса), то происходит автоматическая замена старой темы на новую. В противном случае, ничего не происходит. 
</p>

<p>
	<span style="font-size:20px;">3.4 Использование ресурсов темы</span>
</p>

<p>
	После того, как мы научились делать свою тему и применять ее, теперь необходимо научиться настройке внешнего вида компонента на основании текущей темы.
</p>

<p>
	Компоненты FGX Native предлагают широкий набор свойств, отвечающих за изменение внешнего вида компонента. Например, <strong>TfgButton</strong> дает возможность поменять цвет фона, рамки, текста, перекрасить иконку и т.д.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5299" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.ebb792b1afd3c05970e5833ca8d89de5.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5299" data-unique="wikps52xd" style="width: 330px; height: auto;" width="650" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.d84c5298e6852570b20550112c0b1279.png" loading="lazy" height="747.5"></a>
</p>

<p>
	<span style="font-size:18px;">3.4.1 Типы значений</span>
</p>

<p>
	Большинство компонентов уже настроены для работы с ресурсами будущей темы. Это значит, что часть свойств компонента, отвечающие за связь с ресурсами цвета и настройку внешнего вида, уже могут быть по умолчанию связаны с темой. Чтобы это понять, достаточно посмотреть на свойство в инспекторе объектов:
</p>

<p>
	1. Если в свойстве <u>ничего не указано</u>, то значит будет использовать соответствующий цвет из системной темы. Например: у кнопки по умолчанию не используется цвет из темы, поэтому ее внешний вид и цвет будет отличаться в Android и iOS.
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5300" data-unique="ut6aifxtm" style="width: 400px; height: auto;" width="734" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.355543e8efcd41a5b55c3ec747b4921e.png" loading="lazy" height="51.38">
</p>

<p>
	2. Если в свойстве бледно серым цветом указано название ресурса, то это название ресурса из темы FGX Native, которое будет использоваться, если в приложении создана тема. Например, форма по умолчанию использует цвет "<strong>Background</strong>":
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5302" data-unique="srwxmhsfy" style="width: 400px; height: auto;" width="735" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.69d798af5e89c606c4b6876a5c63a886.png" loading="lazy" height="161.7">
</p>

<p>
	На изображении выше видно, что по умолчанию форма использует белый цвет <strong>Background </strong>из светлой темы с зеленым основным цветом "<strong>Themes\Light\Green</strong>".
</p>

<p>
	3. Если в свойстве значение указано бледно серым цветом и слева от названия вы видите рамку с красным крестиком, это значит, что либо в приложении нет темы FGX Native, либо в текущей теме нет ресурса с именем <strong>Background</strong>.
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5301" data-unique="udktzob86" style="width: 400px; height: auto;" width="749" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.1393466f4fa95c73ae02fd83407e37a4.png" loading="lazy" height="172.27">
</p>

<p>
	4. Если в свойстве название ресурса указано ярким цветом, то это значит, что цвет указан вручную и переопределяет цвет по умолчанию из темы, если он есть.  
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5303" data-unique="z03oaz905" style="width: 500px; height: auto;" width="870" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.af24272079a8ee39efb02899fd48de41.png" loading="lazy" height="43.5">
</p>

<p>
	5. <span style="background-color: rgb( var(--theme-area_background_reset) ); color: rgb( var(--theme-text_color) );">Начиная с <strong>1.19.0.0</strong>. Цветовое свойство допускает указание кода цвета напрямую в качестве имени ресурса. </span>
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5305" data-unique="526mnrs0q" style="width: 282px; height: auto;" width="486" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.d183fd2f09a66397297c5e2715da8e4f.png" loading="lazy" height="48.6">
</p>

<p>
	<span style="font-size:18px;">3.4.2 Приоритеты</span>
</p>

<p>
	Большинство цветовых свойств компонентов FGX Native присутствует в двух вариантах:
</p>

<ol>
	<li>
		С постфиксом "Name": <strong>TintColorName</strong>, <strong>ColorName</strong>
	</li>
	<li>
		Без постфикса "Name": <strong>TintColor</strong>, <strong>Color</strong>
	</li>
</ol>

<p>
	Если вы видите такие парные свойства, значит они оба отвечают за настройку одной характеристики внешнего вида компонента. Приоритет у таких свойств следующий в порядке убывания и наличия: 
</p>

<ol>
	<li>
		Указанное вручную название ресурса цвета.
	</li>
	<li>
		Указанное название ресурса цвета из темы по умолчанию.
	</li>
	<li>
		Значение цвета из свойства <strong>Color</strong>, <strong>TintColor </strong>и т.д.
	</li>
	<li>
		Значение цвета из системной темы (определяется каждым компонентов самостоятельно реализацией).
	</li>
</ol>

<p>
	Данное дублирование появилось с самого начала разработки FGX Native и было предназначено только для быстрого прототипирования компонентов в дизайнере и облегчения перехода разработчиков с VCL и FMX. Однако, использование цвета напрямую не было рекомендовано к использованию. Несмотря на это, главным и основным способом указания цвета остается использование цвета через имя ресурса. В будущих версиях мы планируем скрыть из дизайнера все свойства с прямым заданием кода цвета и перенесем эту возможность напрямую в свойство имени цвета (Как указано в конце раздела 3.4.1).
</p>

<p>
	<span style="font-size:20px;">3.4.3 Применение ресурсов темы</span>
</p>

<p>
	Для корректного отображения некоторых компонентов, которые могут иметь несколько вариантов отображения (например, кнопка), вам необходимо настроить внешний вид, используя ручное указание ресурсов темы.
</p>

<p>
	Например, мы используем в приложении заполненную (<strong>Contained</strong>) цветом кнопку с иконкой. Указываем цвета для иконки, текста и оттенок согласно системе цветов. И тогда при переключении темы с "<strong>Themes\Dark\Green</strong>" на "<strong>Themes\Light\Blue</strong>" внешний вид кнопки будет согласован с темами. 
</p>

<p>
	При указании ресурса из темы важно (начиная с <strong>1.19.0.0</strong>) использовать "<strong>:</strong>", как знак разделитель темы и ресурса темы. Соответственно, если у нас есть тема: "<strong>Themes\Light\Blue</strong>", а внутри цвет "<strong>Secondary\Color</strong>", то полное имя ресурса будет выглядит так "<strong>Themes\Light\Blue<span style="font-size:20px;">:</span>Secondary\Color</strong>" 
</p>

<p>
	 <a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5307" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.ef6838b4399b83f377502afd0a0a11e5.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5307" data-unique="ef89sxcmd" style="height: auto;" width="666" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.5111b4d2bb87e5683a7536f0d181cd90.png" loading="lazy" height="745.92"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5308" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.be0ef0b688950a705309b0c65ce7e1cc.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5308" data-unique="zrdh5mq7m" style="height: auto;" width="650" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.b429e384f0ace3bddd3cef8951929ade.png" loading="lazy" height="747.5"></a>
</p>

<p>
	При смене темы формы или приложения, все свойства, которые используют имена ресурсов с указанием темы с ":" будут автоматически обновлены на использование новой темы. 
</p>

<p>
	<span style="font-size:18px;">3.4.4 Фиксация ресурса цвета</span>
</p>

<p>
	Возможны ситуации, когда необходимо использовать цвет из темы, но без автоматического обновления. Например, вы сделали несколько тем с разными акцентными цветами, и хотите их отобразить на форме. В таком случае, не нужно использовать ":", как разделитель ресурсов, а использовать "\". Тогда при смене темы такие значения не будут изменены.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5276" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.04aceffe50bd2a91db550a98146eee46.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5276" data-unique="6thsc1890" style="width: 700px; height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.d94fb13b90bd6093fa7756e574e73c7f.png" loading="lazy" height="310"></a>
</p>

<p>
	<span style="font-size:20px;">3.5 Расширение темы</span>
</p>

<p>
	Использование темы не ограничено лишь цветами. Вы можете добавлять в структуру темы ресурсы любого типа и использовать их. Например, вы можете использовать разные наборы иконок в темах.
</p>

<p>
	<strong><span style="font-size:22px;">4. Пример разработки приложения с поддержкой темной и светлой тем и разных цветовых оттенков.</span></strong>
</p>

<p>
	Рассмотрим применение тем на практике. В качестве площадки для практики возьмем любое приложение. Вы можете взять свое. Я же взял заготовку из демонстрационных проектов. 
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5265" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.563d3043aec86ca8945e744975965a86.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5265" data-unique="o2gr0phdq" style="height: auto; width: 300px;" width="503" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.f321a38076f20e8bce31e955c825b80b.png" loading="lazy" height="749.47"></a>
</p>

<p>
	В данном проекте нет никакого использования ресурсов, а так же нет никаких тем.
</p>

<p>
	Перед нами стоят следующие задачи:
</p>

<ol>
	<li>
		Добавить поддержку темной и светлой тем.
	</li>
	<li>
		Добавить возможность переключать темы вручную.
	</li>
	<li>
		Добавить возможность переключать темы автоматически согласно настройкам системной темы на устройстве.
	</li>
	<li>
		Добавить возможность менять акцентированный цвет. В примере рассмотрим два цвета: зеленый и синий. На практике как цвета, так и их количество может быть любым.
	</li>
</ol>

<p>
	<span style="font-size:20px;">4.1 Создание тем в дизайнере ресурсов</span>
</p>

<p>
	Добавление поддержки тем начинается с создания темы в дизайнере ресурсов. У нас должно быть два вида тем:
</p>

<ol>
	<li>
		Светлая
	</li>
	<li>
		Темная
	</li>
</ol>

<p>
	А так же два вида акцентированного (Primary) цвета для каждого вида тем:
</p>

<ol>
	<li>
		Зеленый
	</li>
	<li>
		Синий.
	</li>
</ol>

<p>
	В результате у нас должно получиться 4 темы. Для удобства организации тем в дизайнере ресурсов я решил использовать такую группировку:
</p>

<ol>
	<li>
		Первый уровень - <strong>Themes</strong>, сюда складываем все виды тем.
	</li>
	<li>
		Второй уровень - <strong>Dark</strong>/<strong>Light </strong>- группировка всех тем по виду.
	</li>
	<li>
		Третий уровень - <strong>Green</strong>/<strong>Blue </strong>акцентированный цвет.
	</li>
</ol>

<p>
	Открываем дизайнер ресурсов <strong>Project</strong> -&gt; <strong>FGX Assets Manager.</strong>
</p>

<p>
	Создаем такую структуру.
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5262" data-unique="emkc6q6gg" style="width: 244px; height: auto;" width="484" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.b34945c9c832a229cac234a3dbbec99b.png" loading="lazy" height="392.04">
</p>

<p>
	После чего пользуемся встроенным мастером создания темы и создаем две темы с одинаковыми акцентированными цветами для светлой и темной тем. В результате должно получиться вот так:
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5263" data-unique="e4x8rsdmk" style="width: 280px; height: auto;" width="563" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.ff5b5632b8ae54738f0466b02720c030.png" loading="lazy" height="731.9"><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5264" data-unique="04i45ovpv" style="width: 280px; height: auto;" width="561" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.f46cf0f68390a9f679ac12b1b3f89831.png" loading="lazy" height="729.3"><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5267" data-unique="lvcu5lk9m" style="width: 235px; height: auto;" width="473" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.5254aa720ce62c9c7915ec0033f100f5.png" loading="lazy" height="733.15"><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5268" data-unique="9q3xn8vdb" style="width: 235px; height: auto;" width="469" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.12fe55ccf215927f8c45257a377071ec.png" loading="lazy" height="726.95">
</p>

<p>
	<span style="font-size:20px;">4.2 Настройки тем в проекте</span>
</p>

<p>
	Наши <strong>FGX Native</strong> темы готовы, теперь сохраняем изменения и переходим к настройке тем в проекте. Для этого открываем настройки проекта <strong>Project</strong> -&gt; <strong>FGX Options...</strong>-&gt; <strong>Приложение</strong> -&gt; <strong>Темы</strong>.
</p>

<ol>
	<li>
		Выбираем конфигурацию "<strong>All Configurations - All platforms</strong>", чтобы наши настройки тем применились для всех платформ и конфигураций.
	</li>
	<li>
		Пусть при старте у нас будет использоваться такая же тема, как и в системе. Для этого в "<strong>Используемая тема при старте</strong>" (2) выбираем "<strong>Согласно системной теме</strong>"
	</li>
	<li>
		В поле "<strong>название светлой темы</strong>" (3) указываем одну из двух наших светлых тем. Будем считать, что зеленый акцентированный цвет будет использоваться по умолчанию. Поэтому указываем соответствующую светлую тему: "<strong>Themes\Light\Green</strong>"
	</li>
	<li>
		Включаем поддержку темной темы в приложении (4). 
	</li>
	<li>
		В поле "<strong>название темной темы</strong>" (5) указываем соответствующую темную тему: "<strong>Themes\Dark\Green</strong>"
	</li>
</ol>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5269" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.652f4ae37375e6bb0ff210991d79f778.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5269" data-unique="gpe91z38d" style="width: 600px; height: auto;" width="999" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.1aab9c84287d22ef3b2569d817207e65.png" loading="lazy" height="759.24"></a>
</p>

<p>
	Теперь при старте нашего приложения, приложение автоматически получит тему с зеленым акцентированным цветом соответствующего типа. Запускаем и проверяем. При старте в системе установлена светлая тема, она же и применилась в приложении. Меняем системную тему на темную при помощи панели управления <strong>Android</strong> или <strong>iOS</strong> и приложение автоматически меняет ее на темную.
</p>

<p>
	 <a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5270" href="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074208.png.b64851ccccaac9abda20a63a5153947a.png" rel=""><img alt="Screenshot_20250328-074208.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5270" data-unique="dyef9183g" style="width: 300px; height: auto;" width="337" src="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074208.thumb.png.c20517f99a468aafaae7b3a0153827e1.png" loading="lazy" height="748.14"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5271" href="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074219.png.e1d8e3e465805aef009a241ae5623928.png" rel=""><img alt="Screenshot_20250328-074219.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5271" data-unique="fsm79c57g" style="width: 300px; height: auto;" width="337" src="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074219.thumb.png.019a99b91d13a0c4b1cefd3a36800913.png" loading="lazy" height="748.14"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5272" href="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074226.png.14bf1a22e4116bb0bb4cae16a34f3a2d.png" rel=""><img alt="Screenshot_20250328-074226.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5272" data-unique="h58kq5eig" style="width: 300px; height: auto;" width="337" src="https://forum.fgx-native.com/uploads/monthly_2025_03/Screenshot_20250328-074226.thumb.png.4475ce94677a8b6d1d4eb405d5a8aa1b.png" loading="lazy" height="748.14"></a>
</p>

<p>
	Как вы можете видеть, компоненты уже адаптированы и заточены на использование тем FGX Native, поэтому в данном случае мы не выполняли никакой ручной настройки компонентов.
</p>

<p>
	Половина дела уже сделана. Добавлена поддержка двух тем с автоматической синхронизацией с системной темой. Теперь необходимо добавить возможность ручного управления темами и акцентированным цветом. 
</p>

<p>
	<span style="font-size:20px;">4.3 Программная смена тем и акцентированного цвета</span>
</p>

<p>
	Чтобы пользователь мог менять тему в приложении по своему усмотрению, создадим такую панель управления, выдвигаемую снизу экрана. Для этого используем <strong>TfgRadioButton</strong> и <strong>TfgBottomSheetLayout</strong>.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5273" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.ab15ee4da133080fbad00bf9836a205e.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5273" data-unique="ogftmbnvg" style="width: 600px; height: auto;" width="821" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.2607f3002317d9be222ed62e79ca2857.png" loading="lazy" height="747.11"></a>
</p>

<p>
	Чтобы пользователь видел акцентированный цвет, для нижней группы радио кнопок по отдельности указываем соответствующий акцентированный цвет из темных или светлых тем:
</p>

<p>
	Для синего цвета используем такое указание название цвета: "<strong>Themes\Light\Blue\Primary\Color</strong>".
</p>

<p>
	<span style="color:#e74c3c;"><strong>Важно</strong></span>: чтобы в качестве разделителя имени темы "<strong>Themes\Light\Blue</strong>" и ресурса "<strong>Primary\Color</strong>" использовался разделитель "<strong>\</strong>". В этом случае, при любой смене темы данное имя не будет изменяться. В противном случае, при смене темы цвет так же будет изменяться.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5276" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.04aceffe50bd2a91db550a98146eee46.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5276" data-unique="61p0tokls" style="width: 700px; height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.d94fb13b90bd6093fa7756e574e73c7f.png" loading="lazy" height="310"></a>
</p>

<p>
	Задаем группы (<strong>TfgRadioButton.GroupName </strong>) "<strong>ThemeKind</strong>" и "<strong>AccentColor</strong>" для трех верхних и двух нижних групп радиокнопок соответственно. Тип используемой темы задается при помощи перечисляемого типа "<strong>TfgThemeKind = (SystemDefault, Light, Dark);</strong>". Чтобы нам было удобнее, задаем трем верхним радио кнопкам соответствующие значениям <strong>TfgThemeKind</strong> целочисленные значения от 0 до 2 в свойстве <strong>Tag</strong>.
</p>

<p>
	Теперь при выборе типа темы, нам нужно отразить это изменение в приложении. Для этого выбираем три верхних <strong>TfgRadioButton </strong>и пишем такой обработчик <strong>OnChanged.ChangeTheme</strong>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_229_20" style=""><span class="pln">procedure TFormMain.ChangeTheme(Sender: TObject);
var
  RadioButton: TfgRadioButton;
begin
  TfgAssert.IsClass(Sender, TfgRadioButton);

  RadioButton := TfgRadioButton(Sender);
  Application.ThemeSettings.ThemeKind := TfgThemeKind(RadioButton.Tag); // Свойство Tag содержит целочисленное значение TfgThemeKind
end;</span></pre>

<p>
	Проверяем, <strong>Sender</strong> действительно ли является <strong>TfgRadioButton</strong>. Затем извлекаем целочисленное значение <strong>TfgThemeKind</strong> и устанавливаем его в настройки приложения <strong>Application.ThemeSettings.ThemeKind</strong>.
</p>

<p>
	Для того, чтобы поменять акцентированный цвет, нам нужно поменять название светлой и темной тем в <strong>Application.ThemeSettings</strong>. Для этого пишем такой обработчик для двух нижних радиокнопок:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1140_25" style=""><span class="pln">procedure TFormMain.ChangeAccentColor(Sender: TObject);
var
  RadioButton: TfgRadioButton;
  AccentColorName: TfgThemeName;
begin
  TfgAssert.IsClass(Sender, TfgRadioButton);

  RadioButton := TfgRadioButton(Sender);
  AccentColorName := RadioButton.Text;
  Application.ThemeSettings.LightThemeName := 'Themes\Light\' + AccentColorName;
  Application.ThemeSettings.DarkThemeName := 'Themes\Dark\' + AccentColorName;
end;</span></pre>

<p>
	Берем название акцентированного цвета напрямую из названия <strong>TfgRadioButton</strong>. И формируем новое название тем.
</p>

<p>
	Проверяем. Запускаем наше приложение.
</p>

<p>
	<video class="ipsEmbeddedVideo" controls="" data-fileid="5277" data-unique="jizf73fv2" id="ips_uid_1954_6" src="https://forum.fgx-native.com/uploads/monthly_2025_03/video_2025-03-28_04-12-07.mp4.3bfe680c266d18f557a38a83290a9e82.mp4" style="width: 300px" data-controller="core.global.core.embeddedvideo" preload="metadata">
		<source type="video/mp4" src="https://forum.fgx-native.com/uploads/monthly_2025_03/video_2025-03-28_04-12-07.mp4.3bfe680c266d18f557a38a83290a9e82.mp4"><a class="ipsAttachLink" data-fileext="mp4" data-fileid="5277" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=5277&amp;key=e252e3a4e76fd211a961f97562283883" rel="">video_2025-03-28_04-12-07.mp4</a>
	</source></video>
</p>

<p>
	Вот таким незамысловатым способом можно легко добавить поддержку тем в <strong>1.19.0.0</strong>.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="5275" href="https://forum.fgx-native.com/uploads/monthly_2025_03/image.png.d22c0f3455ea022c8ac6598f5b027f65.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="5275" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2025_03/image.thumb.png.7a543ecdd6e15bea4185eb7e1c70d4f0.png" loading="lazy" height="310"></a>
</p>

<p>
	<strong><span style="font-size:22px;">5. Советы</span></strong>
</p>

<ol>
	<li>
		При проектировании интерфейса всегда учитывайте, что у вас должна быть поддержка светлой и темной тем.
	</li>
	<li>
		Лучше сразу добавить в самом начале две базовые темы: светлая и темная с одним из основных цветов.
	</li>
	<li>
		При настройке внешнего вида компонентов, используйте ресурсы из темы, где это необходимо. Это сильно упростит вам дальнейшую настройку внешнего вида приложения и добавление поддержки новых тем. 
	</li>
	<li>
		Вы всегда можете проверить корректность внешнего вида приложения в дизайнере, вручную указав название темы в форме, либо воспользовавшись переключателем вида темы в дизайнере форм.
	</li>
	<li>
		Не используйте зашитые коды цветов прямо в компонентах (свойства <strong>Color</strong>, <strong>TintColor </strong>и т.д.), иначе при смене темы, эти цвета останутся без адаптации. 
	</li>
	<li>
		При любом использовании цветов, выносите его в ресурсы. Если вы понимаете, что данный цвет может зависеть от темы, то смело включайте его в состав тем.
	</li>
</ol>
]]></description><guid isPermaLink="false">74</guid><pubDate>Thu, 27 Mar 2025 22:43:40 +0000</pubDate></item><item><title>&#x418;&#x43D;&#x442;&#x435;&#x433;&#x440;&#x430;&#x446;&#x438;&#x44F; Android &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;. &#x41F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x438; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x43E; &#x441; 1.15.2.0</title><link>https://forum.fgx-native.com/blogs/entry/56-%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-android-%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA-%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%BE-%D0%B8-%D0%B1%D1%8B%D1%81%D1%82%D1%80%D0%BE-%D1%81-11520/</link><description><![CDATA[<p>
	Добрый вечер, уважаемые Delphi разработчики.
</p>

<p style="text-align: justify;">
	Не секрет, что в Java/Kotlin мире огромное количество готовых и бесплатных к использованию Android библиотек, чего нельзя сказать о Delphi. Более того, если речь идет про внешние устройства для устройств на базе Android, то производитель всегда поставляет SDK в виде Android библиотеки.  Будь то софт для работы с устройством по USB, промышленный сканер, медицинское оборудование или что-либо другое, все обычно имеет готовый SDK. <span style="background-color: rgb( var(--theme-area_background_reset) ); color: rgb( var(--theme-text_color) );">Если же вы хотите воспользоваться облачными сервисами аналитики от Google или Yandex, то опять же самым удобным вариантом будет использование готового поставляемого SDK.</span>
</p>

<p style="text-align: justify;">
	К сожалению, надо отметить, что крайне редко производитель поставляет SDK<strong> </strong>для языка Delphi. Что в итоге делает процесс интеграции SDK на другом языке в Delphi не самой тривиальной задаче и требует специальных интеграции со стороны разработчиков. В этой статье мы рассмотрим о новых возможностях по интеграции библиотек для Android приложения на базе FGX Naitve.   
</p>

<p>
	С радостью хотим с вами поделиться новыми возможностями в <strong>FGX Native</strong> в области интеграции сторонних Android библиотек в ваше приложение. Долгое время Delphi не позволяла и до сих пор не позволяет с легкостью добавлять существующие Android-библиотеки. Это значит, что весь мир использования существующих Java библиотек под Android<strong> </strong>для Delphi был практически недоступен.  Почему это так, и в чем трудности, я затронул в статье в главе "<strong>Почему переход на AndroidX не был выполнен ранее?</strong>":
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-embedauthorid="1" data-embedcontent="" data-embedid="embed7273415733" id="ips_uid_4176_6" src="https://forum.fgx-native.com/blogs/entry/50-fgx-native-%D0%BF%D0%B5%D1%80%D0%B5%D1%85%D0%BE%D0%B4%D0%B8%D1%82-%D0%BD%D0%B0-androidx-%D1%81-11500/?do=embed" style="overflow: hidden; height: 414px; max-width: 502px;" loading="lazy"></iframe>

<p>
	И о чем я рассказал в статье (раздел "<strong>Поддержка сторонних Android-библиотек</strong>")
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-embedauthorid="1" data-embedcontent="" data-embedid="embed7831738357" id="ips_uid_4176_7" src="https://forum.fgx-native.com/blogs/entry/52-%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B8-android-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9-%D1%81%D0%BE-%D0%B7%D0%BD%D0%B0%D1%87%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC-%D0%BF%D1%80%D0%B8%D1%80%D0%BE%D1%81%D1%82%D0%BE%D0%BC-%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8-%E2%80%8B%F0%9F%94%A5%E2%80%8B/?do=embed" style="overflow: hidden; height: 414px; max-width: 502px;" loading="lazy"></iframe>

<p>
	Раньше вы могли добавлять только JAR библиотеки (стандартная возможность RAD Studio IDE). Чуть позже, мы добавили поддержку AAR библиотеки (FGX Native 1.15.0.0). А начиная с FGX Native 1.15.2.0 мы расширили эту поддержку и теперь вы можете просто указать название публичной библиотеки, без необходимости искать JAR/AAR и всех зависимостей.
</p>

<p>
	<strong><span style="font-size:22px;">Андроид библиотека</span></strong>
</p>

<p>
	Андроид библиотека идентифицируется тремя параметрами:
</p>

<ol><li>
		<strong>Группа </strong>- Уникальное название группы, в рамках которой могут находиться разные библиотеки. Обычно название группы отражает название компании и направление библиотек.<br>
		Например: "<strong>com.yandex.android</strong>"
	</li>
	<li>
		<strong>Артефакт </strong>- короткое название библиотеки в рамках группы (1).<br>
		Например: "<strong>mobmetricalib</strong>"
	</li>
	<li>
		<strong>Версия</strong>. Номер версии.<br>
		Например: "<strong>5.2.0</strong>"
	</li>
</ol><p>
	Объединенные параметры, разделенные ":", квалифицируют библиотеку среди остальных: "<strong>com.yandex.android:mobmetricalib:5.2.0</strong>".
</p>

<p>
	Управление используемыми библиотеки в приложении <strong>FGX Native</strong> для Android осуществляется через наш менеджер, доступный через главное меню:  "Project -&gt; FGX Android Libraries".
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="4035" href="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.ed019fa7d3e0b1244c9a71b1ea3c0ef4.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4035" data-unique="aib15gdbn" style="width: 500px; height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.e69a1f40497ab5e98d0ffd08eb082f3e.png" loading="lazy" height="590"></a>
</p>

<p>
	Существует два способа интеграции Андроид-библиотеки.
</p>

<p>
	<strong>1. Старый</strong>. Долго, сложно и не поддерживает транзитивные зависимости. Добавление файла библиотеки и всех зависимостей вручную. 
</p>

<p>
	Для этого вам надо:
</p>

<ol><li>
		Cкачать физический файл библиотеки в JAR или AAR формате.
	</li>
	<li>
		Определить все используемые транзитивные зависимости и скачать их файлы так же.
	</li>
	<li>
		После чего вручную добавить их через мастер "<strong>FGX Android Libraries</strong>".
	</li>
</ol><p>
	Например, чтобы этим способом добавить поддержку <strong>Yandex AppMetrika</strong> версии 5.2.0 нужно найти и добавить в сумме 11 файлов библиотек:
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="4036" data-unique="3knd6p9a3" width="258" alt="image.png" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.e1d30ebbaedd4f8d0d801723d9c72b71.png" loading="lazy" height="234.78"></p>

<p>
	<strong>2. Новый</strong>. Указание названия библиотеки для автоматического скачивания библиотеки и всех зависимостей и интеграция в FGX Native приложение. 
</p>

<p>
	Начиная с <strong>1.15.2.0 </strong>достаточно указать полное название библиотеки и все остальное произойдет автоматически.
</p>

<p>
	Чтобы добавить новую зависимость, нужно нажать на кнопку "+" и выбрать "Зависимость-библиотека". После чего указать полное имя зависимости или воспользоваться быстрым поиском для поиска интересуемой зависимости.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="4034" href="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.c1f9591aab0bcab97bb9a0431e7da329.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4034" data-unique="c9k5bju98" style="width: 500px; height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.81f0fae13eacd08d4775948a41bd62f9.png" loading="lazy" height="670"></a>
</p>

<p>
	Таким способом достаточно указать только полное наименование библиотеки. Например, та же Yandex AppMetrika добавляется путем добавления зависимости на "<strong>com.yandex.android:mobmetricalib:5.2.0</strong>".
</p>

<p>
	<strong><span style="font-size:22px;">Репозитории</span></strong>
</p>

<p>
	Все публичные <strong>Android</strong> библиотеки обычно хранятся в репозиториях. <strong>Репозиторий</strong> - это центральное хранилище, где можно найти библиотеку нужной версии, нужного автора (пакет), узнать используемые зависимости (библиотеки часто используют другие для своей работы). Среди наиболее известных публичных репозиториев:
</p>

<ul><li>
		Maven Central - <a href="https://mvnrepository.com/" ipsnoembed="true" rel="external nofollow" target="_blank">https://mvnrepository.com/</a>
	</li>
	<li>
		Google Maven - <a href="https://maven.google.com/web/index.html" ipsnoembed="true" rel="external nofollow" target="_blank">https://maven.google.com/web/index.html</a>
	</li>
</ul><p>
	Помимо общеизвестных, любой желающий может развернуть свой репозиторий и хранить там свои наработки. В таком репозитории можно получить информацию о любой библиотеке. Например, Яндекс предлагает библиотеку "<strong>mobmetricalib</strong>" для работы с <a href="https://appmetrica.yandex.ru/" rel="external nofollow" target="_blank">AppMetrika</a>. Библиотека называется "<strong>com.yandex.android » mobmetricalib</strong>" и может быть найдена в одном из таких репозиториев:
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4029" data-unique="t4gcspsna" style="height: auto;" width="577" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.46f1766ba7654a857e932247e5a59131.png" loading="lazy" height="467.37"> 
</p>

<p>
	А так же здесь вы можете узнать, какие другие библиотеки использует данная библиотека:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="4030" href="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.be09ac99d4f2387e53d1cb4813bd0570.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4030" data-unique="a65jfkahp" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.41aeb921e7e6ac1798a7d3794841d25e.png" loading="lazy" height="290"></a>
</p>

<p>
	<strong>FGX Native</strong> подключает два публичных репозитория по умолчанию (<strong>Maven Central</strong>, <strong>Google Maven</strong>). Вы можете управлять списком репозиториев и добавлять свои, открыв список кнопкой "<strong>Репозитории</strong>", если это требуется:
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4032" data-unique="j539nnmfc" style="width: 435px; height: auto;" width="871" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.4ecadf5f4df6807dc4edeefc67873624.png" loading="lazy" height="644.54"> <img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="4033" data-unique="j0p5usevg" style="width: 435px; height: auto;" width="871" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.fa062231b5388eb4a5dfe98140655e7b.png" loading="lazy" height="435.5"></p>

<p>
	<strong><span style="font-size:22px;">Как использовать добавленные библиотеки в коде?</span></strong>
</p>

<p>
	После того, как вы интегрировали стороннюю библиотеку, встает вопрос о том, как вызвать API, которое она поставляет. Для этого вам нужно получить заголовочные файлы. Это можно сделать при помощи нашей утилиты Java2Delphi, входящей в поставку FGX Native.
</p>

<p>
	Описание работы утилиты описано в этой статье:
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-embedauthorid="1" data-embedcontent="" data-embedid="embed2028955528" src="https://forum.fgx-native.com/blogs/entry/23-%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D0%B0-%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8-%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BE%D1%87%D0%BD%D1%8B%D1%85-%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-java-java2delphi/?do=embed" style="overflow: hidden; height: 417px; max-width: 502px;" loading="lazy"></iframe>

<p>
	Всем спасибо за внимание
</p>
]]></description><guid isPermaLink="false">56</guid><pubDate>Tue, 17 Jan 2023 21:20:01 +0000</pubDate></item><item><title>Firebase Push-&#x443;&#x432;&#x435;&#x434;&#x43E;&#x43C;&#x43B;&#x435;&#x43D;&#x438;&#x44F; &#x43D;&#x430; iOS &#x441; 1.15.2.0</title><link>https://forum.fgx-native.com/blogs/entry/55-firebase-push-%D1%83%D0%B2%D0%B5%D0%B4%D0%BE%D0%BC%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BD%D0%B0-ios-%D1%81-11520/</link><description><![CDATA[<p>Добрый день, уважаемые разработчики.</p><p>В этой статье мы рассмотрим настройку и использование сервиса <strong>Firebase Messaging</strong> (<strong>FCM</strong>)для приема <strong>push</strong>-уведомлений на платформе <strong>iOS</strong>.</p><p>Начиная с версии <strong>FGX Native 1.15.2.0</strong>, вы можете использовать <strong>Firebase </strong>не только на <strong>Android</strong>, но теперь и на <strong>iOS</strong>. Тем самым не нужно выполнять дополнительные действия для конвертации токенов устройств из <strong>Apple Push Service</strong> (<strong>APS</strong>) в токен Firebase (<strong>FCM</strong>), сделав ваш код полностью кроссплатформенным.</p><p>Перед тем, как приступить к работе с уведомлениями, необходимо выполнить регистрацию аккаунта Google.</p><p><strong>Регистрация приложения в Firebase для iOS</strong></p><p>1. Откройте <a rel="external nofollow" href="https://console.firebase.google.com/"><strong>Firebase Console</strong></a> и выполните вход в учетную запись Google. </p><p>2. Нажмите кнопку "<strong>Создать проект</strong>"</p><p><img class="ipsImage ipsRichText__align--block" data-fileid="4021" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.6bc3e454dcc9a10793e68215ffb746f3.png" alt="image.png" title="image.png" width="857" height="402" loading="lazy"></p><p>3. Укажите название вашего проекта и нажмите кнопку "<strong>Continue</strong>". Вы можете использовать любое название. Например: "<strong>FGX Native project</strong>". </p><p><img class="ipsImage ipsRichText__align--block" data-fileid="3998" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.fa7ea1c97ed6747d716a1a218b20ba8f.png" alt="image.png" title="image.png" width="717" height="573" loading="lazy"></p><p>4. На текущей странице вы можете отключить поддержку <strong>Google Analytics</strong>. Вы можете ее отключить. Однако, рекомендуем ее оставить. Так в будущем вы сможете использовать аналитику для данного проекта. Нажмите кнопку "<strong>Continue</strong>".</p><p><img class="ipsImage ipsImage_thumbnailed ipsRichText__align--block" data-fileid="3999" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.3eb2f5937f143bdf7d431c6bbf2ce10b.png" alt="image.png" title="image.png" width="809" height="744" data-full-image="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.1c5e9563dc7cf17131c2c27a9d55ecf2.png" loading="lazy"></p><p>5. Выберите или создайте аккаунт <strong>Google Analytics</strong>. Я взял созданные раннее, в который будет добавлена аналитика для нового проекта. Нажмите кнопку "<strong>Create Project</strong>".</p><p><img class="ipsImage ipsRichText__align--block" data-fileid="4000" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.4935ac3a14c8ce8eb6f09ac5862f3e0c.png" alt="image.png" title="image.png" width="786" height="573" loading="lazy"></p><p>6. Ожидаем окончания процесса создания проекта в <strong>Firebase</strong>. По окончании нажимаем "<strong>Continue</strong>". Когда проект будет создан, вы увидите главную страницу:</p><p><img class="ipsImage ipsRichText__align--block" data-fileid="3995" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.710ca0dc6b9c7bd4b6031bf9d7295c2d.png" alt="image.png" title="image.png" width="859" height="429" loading="lazy"></p><p>7. Теперь необходимо зарегистрировать ваше <strong>FGX Native</strong> <strong>iOS</strong> приложение для этого нажимаете на кнопку с логотипом <strong>iOS</strong>.</p><p>8. Указываете имя пакета вашего iOS приложения, такое же, как у вашего приложения (если оно есть), или такое, какое оно будет (его можно будет указать)</p><ul><li><p>Если у вас уже есть приложение, то узнать название пакета можно в настройках проекта: <strong>Project</strong> -&gt; <strong>Options...</strong> -&gt; <strong>Version Info</strong> &gt; <strong> CFBundleIdentifier </strong>".</p></li><li><p>Если у вас еще нет приложения, то придумайте название пакета. Например: "<strong>ru.fgx.pushnotificationdemo</strong>".</p></li></ul><p><img class="ipsImage ipsRichText__align--block" data-fileid="4016" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.605a4b4251ac9c1c5370cdb4bc843169.png" alt="image.png" title="image.png" width="480" height="417" loading="lazy"></p><p>9. Нажмите кнопку "<strong>Register app</strong>".</p><p>10. Скачиваем конфигурационный файл "<strong>GoogleService-Info.plist</strong>", нажав на кнопку "Download" и сохраняем файл в папку FGX Native проекта (можно сохранить в любое другое место). Этот файл содержит настройки для инициализации FGX Native приложения на iOS.</p><p>14. Заканчиваем добавление вашего приложения путем нажатия кнопок "<strong>Next</strong>" -&gt; "<strong>Next</strong>" -&gt; "<strong>Continue to console</strong>"</p><p>15. Теперь вы увидите ваше iOS приложение на главной странице.</p><p><img class="ipsImage ipsImage_thumbnailed ipsRichText__align--block" data-fileid="4017" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.933d7cb3d8799774f90fdf8a02487685.png" alt="image.png" title="image.png" width="1000" height="350" data-full-image="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.08b99609d1e55f4f4309a5ffdcdcc58b.png" loading="lazy"></p><p>Теперь необходимо выполнить настройку FGX Native приложения в IDE.</p><p><strong>Настройка приложения</strong></p><p>1. Откройте существующий проект или создайте новый.</p><ul><li><p>Если вы создаете новый проект, то в мастере создания проекта обязательно укажите (на основании шага 8 регистрации приложения в Firebase):</p><ul><li><p>Идентификатор организации. Например: "ru.fgx".</p></li><li><p>Имя проекта. Например: "pushnotificationdemo".</p></li></ul></li><li><p>Если открываете существующий, то убедитесь, что название пакета в <strong>Project</strong> -&gt; <strong>Options...</strong> -&gt; <strong>Version Info</strong> &gt; <strong> CFBundleIdentifier </strong>" соответствует названию из шага 8.</p></li></ul><p>2. Откройте: "Главное меню" -&gt; "Project -&gt;  Deployment".</p><p>2.1. В выпадающем списке конфигурации выберите "<strong>All Configurations -&gt; iOS-Device 64-bit platform</strong>".</p><p><strong>Примечание</strong>: Если вы хотите разделять настройки для разных конфигураций, выберете соответствующую конфигурацию.    </p><p>2.2. Добавьте ранее скаченный файл настроек "<strong>GoogleService-Info.plist</strong>" (на основании шага 10 регистрации приложения в Firebase).</p><p><img class="ipsImage ipsImage_thumbnailed ipsRichText__align--block" data-fileid="4018" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.f0a048adfbd3f2cb7d6892679dc43852.png" alt="image.png" title="image.png" width="1000" height="120" data-full-image="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.943e8693002b6bff66909129b9a84c79.png" loading="lazy"></p><p><strong>Примечание:</strong> Если этого не сделать, то при старте приложение упадет.</p><p>3. Сохраните изменения.</p><p>4. Откройте главную форму вашего приложения и подключите модуль <strong>FGX.PushNotification.FCM</strong>. </p><p><strong>Примечание</strong>: <strong>FGX Native</strong> использует <strong>Firebase </strong>по умолчанию на <strong>Android</strong>. Однако, на <strong>iOS </strong>мы используем <strong>Apple Push Service</strong> по умолчанию. Поэтому <strong>Firebase </strong>библиотека не линкуется по умолчанию. По этому важно подключить данный модуль. </p><p>5. Добавьте на форму компонент <strong>TfgPushNotificationService</strong> и укажите "<strong>ServiceNamne = FCM</strong>".</p><p>Минимально необходимая настройка вашего приложения для получения пуш уведомлений выполнена. Если приложение будет свернуто или выгружено из памяти, то при отправке push-уведомление отобразиться в центре уведомлений устройства. Если же приложение активно, то пуш уведомление не будет попадать в центр уведомления устройства.</p><p><strong>Получение токена устройства</strong></p><p>При первом старте приложения, оно выполняет свою регистрацию в облаке <strong>Firebase</strong>. При этом облако выдает устройству уникальный токен <strong>DeviceToken</strong>. Перед тем, как отправить тестовое уведомление, необходимо узнать токен устройства. Для получения токена устройства нужно написать обработчик события "<strong>TfgPushNotificationService.OnDeviceTokenChanged</strong>". Данное событие вызывается каждый раз, когда выдается новый токен устройства. Токен устройства может меняться.</p><p>Получив токен, вам необходимо передать его на ваш сервер, отправляющий Push-уведомления для будущих отправок сообщений. </p><p>В данном примере, мы не будем его сохранять, а выведем в лог устройства.</p><pre spellcheck="" class="ipsCode language-plaintext" data-language="Plain Text"><code>procedure TFormMain.PushServiceDeviceTokenChanged(Sender: TObject; const ADeviceToken: string);
begin
  TfgLog.Info('Device token changed: deviceToken="%s"', [ADeviceToken]);
end;</code></pre><p><strong>Получение push-уведомления</strong></p><p>Для получения токена устройства нужно написать обработчик события "<strong>TfgPushNotificationService.OnPushNotificationReceived</strong>". Данное событие вызывается, когда устройство принимает push-уведомление.</p><p><strong>Примечание</strong>: В зависимости от реализации, событие может вызываться в разные моменты времени. Например, если приложение не в памяти или в фоне, то событие вызовется в момент нажатия пользователем на уведомление в Центре локальных уведомлений.</p><p>Пример вывода в лог полученного push-уведомления:</p><pre spellcheck="" class="ipsCode language-plaintext" data-language="Plain Text"><code>procedure TFormMain.PushServicePushNotificationReceived(Sender: TObject; const ANotification: TfgPushNotification);
begin
  TfgLog.Info('Notification received: notification="%s"', [ANotification.ToString]);
end;</code></pre><p>Запустите приложение и запомните токен устройства из консоли. </p><p>О том, как пользоваться Console для просмотра логов устройства, читайте в статье:</p><div class="ipsEmbeddedOther"><iframe src="https://forum.fgx-native.com/blogs/entry/32-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0-%D0%B8-%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-ios-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D1%8B-console/?do=embed" allowfullscreen="" data-embedauthorid="2" data-embedcontent="" data-embedid="embed6168701375" style="overflow: hidden; height: 237px; max-width: 502px;" loading="lazy"></iframe></div><p><strong>Отправка тестового сообщения</strong></p><p>Чтобы отправить тестовое сообщение на конкретное устройство, можно воспользоваться <strong>Firebase </strong>консолью.  </p><p>1. Откройте консоль: <a rel="external nofollow" href="https://console.firebase.google.com"><strong>https://console.firebase.google.com</strong></a></p><p>2. Перейдите в меню навигации к разделу: "<strong>Engage -&gt; Messaging</strong>"</p><p>3. Нажмите кнопку "<strong>Create your first campaign</strong>".</p><p>4. Выберите тип "<strong>Firebase Notification Messages</strong>".</p><p>4. Заполните данные уведомления. Например так:</p><p><img class="ipsImage ipsImage_thumbnailed ipsRichText__align--block" data-fileid="4019" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.5fc44190c8ccc73650c296cc5f58ad40.png" alt="image.png" title="image.png" width="1000" height="600" data-full-image="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.75aea13cd8f7e5f148ae0beb687d1c15.png" loading="lazy"></p><p>5. Нажмите кнопку "<strong>Send test message</strong>". Консоль предложит указать на какие устройства необходимо отправить данное уведомление.</p><p>6. Укажите в поле токен устройства (раздел "Получение токена устройства") и нажмите кнопку "+".</p><p>7. Выполните отправку уведомления, путем нажатия на кнопку "Протестировать" и наблюдайте появление вашего уведомления в центре локального уведомления на устройстве:</p><p><img class="ipsImage ipsImage_thumbnailed ipsRichText__align--block" data-fileid="4020" src="https://forum.fgx-native.com/uploads/monthly_2023_01/image.thumb.png.8a98e168a41e605fcebdfc56f24d4aab.png" alt="image.png" title="image.png" width="346" height="747" data-full-image="https://forum.fgx-native.com/uploads/monthly_2023_01/image.png.f3e670366ec9e42022f7173065972fe6.png" loading="lazy"></p><p><strong>Получение данных уведомления при старте приложения</strong></p><p>Если пользователь нажимает на <strong>push</strong>-уведомление в центре уведомлений, то система запустит ваше приложение. В любой момент времени можно получить данные стартового уведомления напрямую из локального Firebase сервиса (Раздел "Получение Push-уведомлений").</p><pre spellcheck="" class="ipsCode language-plaintext" data-language="Plain Text"><code>var 
  Notifications: TArray&lt;TfgPushNotification&gt;; 
begin 
  Notifications := fgPushNotificationService1.StartupNotifications;
end;</code></pre><h1><span data-i-color="red">ВАЖНО!</span></h1><p><em>Приложение падает на старте и вы используете компоненты </em><strong><em>FireDAC</em></strong><em>. (спасибо <a href="https://forum.fgx-native.com/profile/73-roman/" class="ipsMention" data-mentionid="73" data-ipshover="" data-ipshover-target="https://forum.fgx-native.com/profile/73-roman/?do=hovercard" rel="">@Roman</a>)</em></p><blockquote class="ipsQuote" cite="" data-ipsquote=""><header class="ipsQuote_citation">
		Quote
	</header><div class="ipsQuote_contents" data-ipstruncate=""><p>Отдельно хочу отметить, что при использовании в приложении компонента <strong>TFDConnection </strong>с драйвером SQLite (<strong>TFDConnection.DriverName=SQLite</strong>), по умолчанию устанавливается режим статической привязки движка <strong>SQLite</strong>. Что в свою очередь, после интеграции <strong>Firebase</strong>, приводит к падению iOS-приложения при запуске.</p><p>Для исправления проблемы необходимо:</p><ol><li><p>вместе с TFDConnection разместить компонент <strong>TFDPhysSQLiteDriverLink</strong>;</p></li><li><p>установить динамическую привязку SQLite: <strong>TFDPhysSQLiteDriverLink.EngineLinkage=slDynamic</strong>;</p></li><li><p>в модуле, который использует <strong>TFDConnection</strong>, из uses удалить <strong>FireDAC.Phys.SQLiteWrapper.Stat</strong>. </p></li></ol><p>Обратите внимание!<br>Все вышеописанное справедливо ТОЛЬКО для <strong>iOS</strong>!</p><p>Для Android необходима статическая привязка движка <strong>SQLite</strong>!</p><p>Чтобы ваше приложение на <strong>Android </strong>смогло работать с БД, необходимо пойти по одному из вариантов:</p><ol><li><p>для <strong>Android </strong>использовать отдельный модуль данных со статической привязкой SQLite;</p></li><li><p>перед сборкой <strong>Android</strong>-приложения вернуть значение <strong>TFDPhysSQLiteDriverLink.EngineLinkage=slStatic</strong>.</p></li></ol><p>Надеюсь, эта информация позволит избежать аналогичных ошибок <span class="ipsEmoji" title="">😉</span></p></div></blockquote>]]></description><guid isPermaLink="false">55</guid><pubDate>Wed, 11 Jan 2023 00:01:00 +0000</pubDate></item><item><title>&#x421;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x430;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;. &#x410;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x44F; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; VK Login</title><link>https://forum.fgx-native.com/blogs/entry/44-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-vk-login/</link><description><![CDATA[<p>
	В этой статье мы разберем настройку и использование сервиса <strong>VK Login</strong> с помощью <strong>TfgVKLoginAuthenticationClient</strong>.
</p>

<p style="text-align: center;">
	 
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="PNG" data-fileid="3407" href="https://forum.fgx-native.com/uploads/monthly_2022_05/0.PNG.b8ca2820942eb0fb0a4b19be233c01fd.PNG" rel=""><img alt="0.PNG" class="ipsImage ipsImage_thumbnailed" data-fileid="3407" data-unique="9lwiso7s2" style="height: auto;" width="421" src="https://forum.fgx-native.com/uploads/monthly_2022_05/0.thumb.PNG.94d7826fe8703cfe69f2542c20eb314f.PNG" loading="lazy" height="749.38"></a>
</p>

<p>
	<span style="font-size:22px;"><strong>Настройка серверной части</strong></span>
</p>

<ol><li>
		Переходим по <a href="https://vk.com/apps?act=manage" rel="external nofollow">ссылке</a> и попадаем в список приложений. Нажимаем на кнопку <strong>Create</strong> 

		<p style="text-align: center;">
			<img alt="1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3402" data-unique="nlzzmvxl9" style="height: auto;" width="996" src="https://forum.fgx-native.com/uploads/monthly_2022_05/1.png.98014dec9c32c65dac5c20c1a3dd759e.png" loading="lazy" height="418.32"></p>
	</li>
	<li>
		Заполняем название, выбираем тип <strong>Standalone app</strong> и нажимаем кнопку <strong>Connect app</strong>
		<p style="text-align: center;">
			<img alt="2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3403" data-unique="u28w4lir9" style="height: auto;" width="996" src="https://forum.fgx-native.com/uploads/monthly_2022_05/2.png.abe139fbea9f4fa65be8c03058addc73.png" loading="lazy" height="418.32"></p>
	</li>
	<li>
		После подтверждения по телефонному звонку попадаем на страницу вновь созданного приложения и переходим в раздел <strong>Settings</strong>
	</li>
	<li>
		В настройках запоминаем значение параметра <strong>App ID</strong> (он далее понадобится нам при настройке <strong>Delphi </strong>приложения)
	</li>
	<li>
		На этой же странице указываем идентификатор нашего приложения в поле <strong>App Bundle ID for iOS</strong> (также понадобится далее при настройке <strong>Delphi </strong>приложения)
	</li>
	<li>
		<strong>App status</strong> изменяем на <strong>Application on and visible to all</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3405" href="https://forum.fgx-native.com/uploads/monthly_2022_05/3.png.8f76a24a914410457c2bd4da205b72a6.png" rel=""><img alt="3.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3405" data-unique="wj9id4lts" style="height: auto;" width="877" src="https://forum.fgx-native.com/uploads/monthly_2022_05/3.thumb.png.8f79c89e0fd53f54e564e1ee01d41391.png" loading="lazy" height="745.45"></a>
		</p>
	</li>
	<li>
		<p>
			Сохраняем настройки с помощью кнопки <strong>Save</strong>.
		</p>
	</li>
</ol><p style="text-align: center;">
	 
</p>

<p>
	<span style="font-size:22px;"><strong>Настройка клиентской части</strong></span>
</p>

<ol><li>
		<p>
			Переходим в настройки <strong>iOS </strong>профиля приложения и назначаем <strong>CFBundleIdentifier </strong>из шага <strong>5</strong> настройки серверной части
		</p>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3408" href="https://forum.fgx-native.com/uploads/monthly_2022_05/4.png.05902134c9bce0696c0f38ba8de249cf.png" rel=""><img alt="4.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3408" data-unique="i081dl0ub" style="height: auto;" width="942" src="https://forum.fgx-native.com/uploads/monthly_2022_05/4.thumb.png.bf7c3d0a8b247af6fb33792821382d78.png" loading="lazy" height="744.18"></a>
		</p>
	</li>
	<li>
		<p>
			Открываем в текстовом редакторе файл <strong>info.plist.TemplateiOS.xml</strong> из директории проекта и сразу после плейсхолдера <strong>&lt;%StoryboardInfoPListKey%&gt;</strong> добавляем следующий текст
		</p>
	</li>
</ol><pre class="ipsCode prettyprint lang-xml prettyprinted" id="ips_uid_3321_21" style=""><span class="tag">&lt;key&gt;</span><span class="pln">CFBundleURLTypes</span><span class="tag">&lt;/key&gt;</span><span class="pln">
</span><span class="tag">&lt;array&gt;</span><span class="pln">
  </span><span class="tag">&lt;dict&gt;</span><span class="pln">
    </span><span class="tag">&lt;key&gt;</span><span class="pln">CFBundleTypeRole</span><span class="tag">&lt;/key&gt;</span><span class="pln">
    </span><span class="tag">&lt;string&gt;</span><span class="pln">Editor</span><span class="tag">&lt;/string&gt;</span><span class="pln">
    </span><span class="tag">&lt;key&gt;</span><span class="pln">CFBundleURLName</span><span class="tag">&lt;/key&gt;</span><span class="pln">
    </span><span class="tag">&lt;string&gt;</span><span class="pln">vkAPP-ID</span><span class="tag">&lt;/string&gt;</span><span class="pln">
    </span><span class="tag">&lt;key&gt;</span><span class="pln">CFBundleURLSchemes</span><span class="tag">&lt;/key&gt;</span><span class="pln">
    </span><span class="tag">&lt;array&gt;</span><span class="pln">
      </span><span class="tag">&lt;string&gt;</span><span class="pln">vkAPP-ID</span><span class="tag">&lt;/string&gt;</span><span class="pln">
    </span><span class="tag">&lt;/array&gt;</span><span class="pln">
  </span><span class="tag">&lt;/dict&gt;</span><span class="pln">
</span><span class="tag">&lt;/array&gt;</span><span class="pln">
</span><span class="tag">&lt;key&gt;</span><span class="pln">LSApplicationQueriesSchemes</span><span class="tag">&lt;/key&gt;</span><span class="pln">
</span><span class="tag">&lt;array&gt;</span><span class="pln">
    </span><span class="tag">&lt;string&gt;</span><span class="pln">vk</span><span class="tag">&lt;/string&gt;</span><span class="pln">
    </span><span class="tag">&lt;string&gt;</span><span class="pln">vk-share</span><span class="tag">&lt;/string&gt;</span><span class="pln">
    </span><span class="tag">&lt;string&gt;</span><span class="pln">vkauthorize</span><span class="tag">&lt;/string&gt;</span><span class="pln">
</span><span class="tag">&lt;/array&gt;</span><span class="pln">
</span><span class="tag">&lt;key&gt;</span><span class="pln">VKAppID</span><span class="tag">&lt;/key&gt;</span><span class="pln">
</span><span class="tag">&lt;string&gt;</span><span class="pln">APP-ID</span><span class="tag">&lt;/string&gt;</span></pre>

<p>
	где <strong>APP-ID</strong> - <strong>App ID</strong> из шага <strong>4</strong>
</p>

<p>
	<span style="color:#c0392b;"><strong>Внимание!</strong></span> Если вы в приложении используете одновременно аутентификацию <strong>Facebook Login</strong>, то необходимо скомбинировать вышеуказанные ключи с имеющимися ключами от <strong>Facebook Login</strong>.
</p>

<p>
	Итоговый файл можно посмотреть в прикрепленном демо проекте <a class="ipsAttachLink" data-fileid="3409" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=3409&amp;key=47142c8431ed0cf0581285551d3da0c6" data-fileext="zip" rel="">Authentication - Clients.zip</a>
</p>

<p>
	Спасибо за внимание.
</p>
]]></description><guid isPermaLink="false">44</guid><pubDate>Mon, 23 May 2022 23:08:49 +0000</pubDate></item><item><title>&#x421;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x430;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;. &#x410;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x44F; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; Google Sign-In</title><link>https://forum.fgx-native.com/blogs/entry/43-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-google-sign-in/</link><description><![CDATA[<p>
	В этой статье мы разберем настройку и использование сервиса <strong>Google Sign-In</strong> с помощью <strong>TfgGoogleSignInAuthenticationClient</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="3368" href="https://forum.fgx-native.com/uploads/monthly_2022_05/0.jpeg.271a8d55a0d2ff936dc03c004bd82a67.jpeg" rel=""><img alt="0.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="3368" data-unique="l14wrlw9e" style="height: auto;" width="345" src="https://forum.fgx-native.com/uploads/monthly_2022_05/0.thumb.jpeg.e3c6073cf2665b94f12afdd87d9a880b.jpeg" loading="lazy" height="748.65"></a>
</p>

<p style="text-align: center;">
	 
</p>

<p>
	<span style="font-size:22px;"><strong>Настройка серверной части</strong></span>
</p>

<ol><li>
		Переходим по <a href="https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project" rel="external nofollow">ссылке</a> и попадаем н<span id="cke_bm_1151C" style="display: none;"> </span>а страницу документации с пошаговым мастером настройки, запускаемым по кнопке <strong>Configure a project</strong>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3371" href="https://forum.fgx-native.com/uploads/monthly_2022_05/1.png.23efd219f4ee5f2d26a67d80941eab9a.png" rel=""><img alt="1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3371" data-unique="pccqyqa5a" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/1.thumb.png.835e5fa5580b77bfb4dd5203bcba68d0.png" loading="lazy" height="610"></a>
		</p>
	</li>
	<li>
		Запускаем мастер и указываем имя проекта (внутреннее именование, невидимое для конечного пользователя)
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3372" href="https://forum.fgx-native.com/uploads/monthly_2022_05/2.png.aa09b6b55ca98c269fbf5a0d88742b16.png" rel=""><img alt="2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3372" data-unique="sigm0idzx" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/2.thumb.png.68803387801bc50bb65a54588a78e5fc.png" loading="lazy" height="610"></a>
		</p>
	</li>
	<li>
		Указываем имя продукта для <strong>OAuth </strong>клиента, которое увидит конечный пользователь в диалоге аутентификации
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3380" href="https://forum.fgx-native.com/uploads/monthly_2022_05/3.png.35211126bd0a0797946d5ed96a96c030.png" rel=""><img alt="3.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3380" data-unique="09k4wl7hf" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/3.thumb.png.d213c553d6b4898dbd02d2bb5e830006.png" loading="lazy" height="610"></a>
		</p>
	</li>
	<li>
		Далее в выпадающем списке выбираем тип клиента <strong>Android</strong>, указываем имя пакета (далее понадобится нам при настройке <strong>Delphi </strong>приложения) и отпечаток сертификата (получение рассмотрено ниже)
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3374" href="https://forum.fgx-native.com/uploads/monthly_2022_05/4.png.e4f65c79b1fb883f5219c8d0760690f6.png" rel=""><img alt="4.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3374" data-unique="fguvhip5z" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/4.thumb.png.7ffc998ec79f5a13c3dd7c5ee6f5d332.png" loading="lazy" height="610"></a>
		</p>
	</li>
	<li>
		Завершаем настройку (при надобности сохраните конфигурационные данные клиента)
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3379" href="https://forum.fgx-native.com/uploads/monthly_2022_05/6.png.93f2c6982a81045e815076ba55fbd4f4.png" rel=""><img alt="6.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3379" data-unique="048kj5m2l" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/6.thumb.png.7a2509046da1ba906cd27fa3d9292234.png" loading="lazy" height="610"></a>
		</p>
	</li>
</ol><p style="text-align: center;">
	 
</p>

<p>
	<span style="font-size:16px;"><strong>Получение SHA-1 отпечатка сертификата</strong></span>
</p>

<p>
	При сборке <strong>Android </strong>приложение подписывается сертификатом разработчика. От типа сборки, режима конфигурации и версии <strong>Delphi </strong>будет зависеть местоположение файла сертификата от которого мы будет получать отпечаток. Ниже будет рассмотреть вариант получения отпечатка для <strong>Debug </strong>сборки в режиме конфигурации <strong>Development </strong>для <strong>Delphi 11.</strong>
</p>

<p>
	Открываем командуню строку <strong>Windows </strong>и выполяем следующую команду 
</p>

<pre><code>keytool -list -v -alias androiddebugkey -keystore "C:\Users\%USERNAME%\AppData\Roaming\Embarcadero\BDS\22.0\debug.keystore"</code></pre>

<p>
	где <strong>%USERNAME%</strong> - имя залогиненого пользователя <strong>Windows</strong>
</p>

<p>
	<strong>22.0</strong> - версия <strong>Delphi 11</strong> (для <strong>Delphi 10.4</strong> этот параметр будет равен <strong>21.0</strong>).
</p>

<p>
	Если вы используете собственный сертификат разработчика и режим конфигурации <strong>Application Store</strong>, подставьте путь к вашему <strong>.keystore</strong> файлу.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3376" href="https://forum.fgx-native.com/uploads/monthly_2022_05/5.png.379e4936259b5c831c49913891b4c3e2.png" rel=""><img alt="5.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3376" data-unique="ptdjsymnv" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_05/5.thumb.png.cd8f0bfebfdb3c1766d6c3e92a0e8d61.png" loading="lazy" height="550"></a>
</p>

<p>
	<span style="font-size:22px;"><strong>Настройка клиентской части</strong></span>
</p>

<ol><li>
		<p>
			Переходим в настройки <strong>Android </strong>профиля приложения и назначаем <strong>package </strong>из шага 4 настройки серверной части
		</p>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3377" href="https://forum.fgx-native.com/uploads/monthly_2022_05/7.png.b0c6992c7951fedc7a41ac7c1c572ff7.png" rel=""><img alt="7.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3377" data-unique="ikf2vj7z5" style="height: auto;" width="940" src="https://forum.fgx-native.com/uploads/monthly_2022_05/7.thumb.png.90ff0d08c1a9c8655c27995168a73909.png" loading="lazy" height="742.6"></a>
		</p>
	</li>
	<li>
		<p>
			Открываем в текстовом редакторе файл <strong>AndroidManifest.template.xml</strong> из директории проекта и сразу после закрывающего тега <strong>&lt;/activity&gt;</strong> добавляем следующий текст
		</p>
	</li>
</ol><pre class="ipsCode prettyprint lang-xml prettyprinted" id="ips_uid_44_8" style=""><span class="pln">        </span><span class="com">&lt;!-- Google Play Services version, which are used in this application. This value is checked by Play Services in runtime --&gt;</span><span class="pln">
        </span><span class="tag">&lt;meta-data</span><span class="pln"> </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">"com.google.android.gms.version"</span><span class="pln"> </span><span class="atn">android:value</span><span class="pun">=</span><span class="atv">"12451000"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
		
        </span><span class="tag">&lt;activity</span><span class="pln">
            </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">"com.google.android.gms.auth.api.signin.internal.SignInHubActivity"</span><span class="pln">
            </span><span class="atn">android:excludeFromRecents</span><span class="pun">=</span><span class="atv">"true"</span><span class="pln">
            </span><span class="atn">android:exported</span><span class="pun">=</span><span class="atv">"false"</span><span class="pln">
            </span><span class="atn">android:theme</span><span class="pun">=</span><span class="atv">"@android:style/Theme.Translucent.NoTitleBar"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">

        </span><span class="com">&lt;!--
            Service handling Google Sign-In user revocation. For apps that do not integrate with
            Google Sign-In, this service will never be started.
        --&gt;</span><span class="pln">
        </span><span class="tag">&lt;service</span><span class="pln">
            </span><span class="atn">android:name</span><span class="pun">=</span><span class="atv">"com.google.android.gms.auth.api.signin.RevocationBoundService"</span><span class="pln">
            </span><span class="atn">android:exported</span><span class="pun">=</span><span class="atv">"true"</span><span class="pln">
            </span><span class="atn">android:permission</span><span class="pun">=</span><span class="atv">"com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">	</span></pre>

<p>
	Внимание! Если в настройках вашего проекта вклюены опции <strong>AdMob Service</strong>, <strong>Maps Service</strong> или <strong>Receive push notifications </strong>указывать первую строку с версией <strong>Google Play Services</strong> необязательно, т.к. она добавится автоматически. 
</p>

<p>
	Итоговый файл можно посмотреть в прикрепленном демо проекте <a class="ipsAttachLink" data-fileext="zip" data-fileid="3378" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=3378&amp;key=76ef1f801c1eb020322204dd2e08dff5" rel="">Authentication - Clients.zip</a>
</p>

<p>
	Спасибо за внимание.
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">43</guid><pubDate>Sun, 15 May 2022 18:19:31 +0000</pubDate></item><item><title>&#x421;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x430;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;. &#x410;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x44F; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; Facebook Login</title><link>https://forum.fgx-native.com/blogs/entry/41-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-facebook-login/</link><description><![CDATA[<p>
	В этой статье мы разберем настройку и использование сервиса <strong>Facebook Login</strong> с помощью <strong>TfgFacebookLoginAuthenticationClient</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="PNG" data-fileid="3207" href="https://forum.fgx-native.com/uploads/monthly_2022_03/9.PNG.428a37fe5384ef0d18d522e133cf3661.PNG" rel=""><img alt="9.PNG" class="ipsImage ipsImage_thumbnailed" data-fileid="3207" data-unique="esgaikkaf" style="height: auto;" width="421" src="https://forum.fgx-native.com/uploads/monthly_2022_03/9.thumb.PNG.40dfef2f2ccf36827eba04fecb5e7aaa.PNG" loading="lazy" height="749.38"></a>
</p>

<p>
	<span style="font-size:22px;"><strong>Настройка серверной части</strong></span>
</p>

<ol><li>
		Переходим по <a href="https://developers.facebook.com/apps/" rel="external nofollow">ссылке</a> и попадаем в список приложений
	</li>
	<li>
		Для создания нового приложения нажимаем кнопку <strong>Create App</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3208" href="https://forum.fgx-native.com/uploads/monthly_2022_03/1.png.a6d4f0c80953c7fffb7a117a5d9eb619.png" rel=""><img alt="1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3208" data-unique="snjcx8dl9" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/1.thumb.png.7252dfb59de68c90c590d429a27832db.png" loading="lazy" height="190"></a>
		</p>
	</li>
	<li>
		Выбираем наиболее подходящий под вашу задачу тип приложения
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3209" href="https://forum.fgx-native.com/uploads/monthly_2022_03/2.png.c730f501f10843098098c1f493b55ff6.png" rel=""><img alt="2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3209" data-unique="0z6gjneb8" style="height: auto;" width="999" src="https://forum.fgx-native.com/uploads/monthly_2022_03/2.thumb.png.227cefc7274e52e9fb2701b1eb44833a.png" loading="lazy" height="749.25"></a>
		</p>
	</li>
	<li>
		Заполняем название приложения и контактную информацию
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3213" href="https://forum.fgx-native.com/uploads/monthly_2022_03/3.png.9da77bdb8311884abc499b68c1bf7c9f.png" rel=""><img alt="3.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3213" data-unique="dcer0bkk7" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/3.thumb.png.ac73163000db1ab960a5e9ee260c1050.png" loading="lazy" height="450"></a>
		</p>
	</li>
	<li>
		После завершения создания нового приложения мы попадаем на страницу настроек приложения. Заходим в настройки сервиса <strong>Facebook Login</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3214" href="https://forum.fgx-native.com/uploads/monthly_2022_03/4.png.4f47255075326e82aed580dd2ed33c83.png" rel=""><img alt="4.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3214" data-unique="0xfpvnn1w" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/4.thumb.png.053a9ce7470d24015ee5310644ec7ce3.png" loading="lazy" height="620"></a>
		</p>
	</li>
	<li>
		Выбираем платформу <strong>iOS</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3215" href="https://forum.fgx-native.com/uploads/monthly_2022_03/5.png.0aa6dfc8fda72b5a310c540359aa6b82.png" rel=""><img alt="5.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3215" data-unique="vfqbtvjr0" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/5.thumb.png.bee3716ce2b73aad2f0830329704f22c.png" loading="lazy" height="310"></a>
		</p>
	</li>
	<li>
		Далее идёт пошаговая настройка. Большая часть шагов не представляет для нас интереса. <br>
		В шаге 2 необходимо указать <strong>Bundle ID</strong> (он далее понадобится нам при настройке <strong>Delphi </strong>приложения)
		<p style="text-align: center;">
			<img alt="6.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3217" data-unique="v9bkayuzn" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/6.png.40bda507581a5794fab4d544229f4513.png" loading="lazy" height="550"></p>
		В шаге 3 нужно включить опцию <strong>Enable Single Sign On</strong>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3216" href="https://forum.fgx-native.com/uploads/monthly_2022_03/7.png.58cfce341434e452245862813496f8da.png" rel=""><img alt="7.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3216" data-unique="eoiiswj7w" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/7.thumb.png.8813fd738a886f4c9116b1eb3b8076c2.png" loading="lazy" height="530"></a>
		</p>
	</li>
	<li>
		Скопируем несколько значений из серверных настроек, которые понадобятся нам для настройки <strong>Delphi </strong>приложения наравне с <strong>Bundle ID</strong> из предыдущего шага:<br>
		a) <strong>App ID</strong>, который можно взять в тулбаре настроек, либо со страницы <strong>Settings-Basic</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3219" href="https://forum.fgx-native.com/uploads/monthly_2022_03/8.png.6f8a540058cd1cd19fa1568788274173.png" rel=""><img alt="8.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3219" data-unique="4yjpqm66e" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/8.thumb.png.2c618470937af96ee4490c7e730852e1.png" loading="lazy" height="210"></a>
		</p>
		b) <strong>Client token</strong>, который находится на странице <strong>Settings-Advanced-Security</strong>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3220" href="https://forum.fgx-native.com/uploads/monthly_2022_03/9.png.d6a1ab81a1655395047ff48f2026a948.png" rel=""><img alt="9.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3220" data-unique="bo75p67nr" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/9.thumb.png.021a6aadfb21446128ec1d93be4d3414.png" loading="lazy" height="370"></a>
		</p>
	</li>
</ol><p>
	<span style="font-size:22px;"><strong>Настройка клиентской части</strong></span>
</p>

<ol><li>
		<p>
			Переходим в настройки <strong>iOS </strong>профиля приложения и назначаем <strong>CFBundleIdentifier </strong>из шага 7 настройки серверной части
		</p>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3164" href="https://forum.fgx-native.com/uploads/monthly_2022_03/8.png.2260f7b6c309b2a92abc4b4560e32b83.png" rel=""><img alt="8.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3164" data-unique="9dwjty4gc" style="height: auto; width: 800px;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/8.thumb.png.13c4638e08e71120fd89d79e91b2dba4.png" loading="lazy" height="740"></a>
		</p>
	</li>
	<li>
		<p>
			Открываем в текстовом редакторе файл <strong>info.plist.TemplateiOS.xml</strong> из директории проекта и сразу после плейсхолдера <strong>&lt;%StoryboardInfoPListKey%&gt;</strong> добавляем следующий текст
		</p>

		<pre><code class="language-xml">&lt;key&gt;CFBundleURLTypes&lt;/key&gt;
&lt;array&gt;
  &lt;dict&gt;
  &lt;key&gt;CFBundleURLSchemes&lt;/key&gt;
  &lt;array&gt;
    &lt;string&gt;fbAPP-ID&lt;/string&gt;
  &lt;/array&gt;
  &lt;/dict&gt;
&lt;/array&gt;
&lt;key&gt;FacebookAppID&lt;/key&gt;
&lt;string&gt;APP-ID&lt;/string&gt;
&lt;key&gt;FacebookClientToken&lt;/key&gt;
&lt;string&gt;CLIENT-TOKEN&lt;/string&gt;
&lt;key&gt;FacebookDisplayName&lt;/key&gt;
&lt;string&gt;APP-NAME&lt;/string&gt;
&lt;key&gt;LSApplicationQueriesSchemes&lt;/key&gt;
&lt;array&gt;
  &lt;string&gt;fbapi&lt;/string&gt;
  &lt;string&gt;fb-messenger-share-api&lt;/string&gt;
&lt;/array&gt;</code></pre>

		<p>
			где <strong>APP-ID</strong> - <strong>App ID</strong> из шага <strong>8a</strong><br><strong>CLIENT-TOKEN</strong> - <strong>Client token</strong> из шага <strong>8b</strong><br><strong>APP-NAME</strong> - имя приложения<br><br>
			Итоговый файл можно посмотреть в прикрепленном демо проекте <a class="ipsAttachLink" data-fileext="zip" data-fileid="3221" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=3221&amp;key=619f4055953386e54dab1d9c8c4f9e5a" rel="">Authentication - Clients.zip</a>
		</p>
	</li>
</ol><p>
	 
</p>

<p>
	Спасибо за внимание.
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">41</guid><pubDate>Wed, 30 Mar 2022 22:05:53 +0000</pubDate></item><item><title>&#x421;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x430;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;. &#x410;&#x443;&#x442;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x44F; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; Apple ID</title><link>https://forum.fgx-native.com/blogs/entry/40-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-apple-id/</link><description><![CDATA[<p>
	Этой статьей мы начинаем серию статей по клиентам аутентификации, которые впервые появились в версии <strong>1.13.4.0</strong>. Мы планируем постепенно добавлять новые сервисы аутентификации. На момент написания данной статьи поддерживаются три клиента для платформы <strong>iOS</strong>: <strong>TfgAppleIdAuthenticationClient</strong>, <strong>TfgFacebookLoginAuthenticationClient </strong>и <strong>TfgVKLoginAuthenticationClient</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3199" href="https://forum.fgx-native.com/uploads/monthly_2022_03/9.png.21f7563692fa744d90194a0ff568c570.png" rel=""><img alt="9.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3199" data-unique="vrm687upw" style="height: auto;" width="421" src="https://forum.fgx-native.com/uploads/monthly_2022_03/9.thumb.png.894259a5c34ee92416c4a349e5f744d6.png" loading="lazy" height="749.38"></a>
</p>

<p style="text-align: center;">
	 
</p>

<p>
	<strong><span style="font-size:22px;">Что такое аутентификация?</span></strong>
</p>

<p>
	Согласно<a href="https://ru.wikipedia.org/wiki/%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F" rel="external nofollow"> википедии</a> «аутентификация» — это процедура проверки подлинности. Те другими словами это доказательство того, что перед вами именно тот пользователь, кем он представился. В обычной жизни можно провести аналогию со сличением личности по паспорту.
</p>

<p>
	<span style="font-size:22px;"><strong>Что является результатом аутентификации?</strong></span>
</p>

<p>
	Основным результатом аутентификации является идентификатор аккаунта (<strong>TfgAccountId</strong>), а так же ряд дополнительных полей наличие и состав которых зависит от сервиса аутентификации и желания пользователя их предоставить. Как правило, сервисы возвращают имя пользователя, email.
</p>

<p>
	<span style="font-size:22px;"><strong>Сервис аутентификации в библиотеке FGX Native</strong></span>
</p>

<p>
	Каждый сервис аутентификации реализует интерфейс <strong>IFGXAuthenticationService</strong>, который включает в себя метод по входу, выходу и проверке состояния авторизации по указанному индентификатору аккаунта.
</p>

<p>
	За регистрацию, хранение и поиск сервисов аутентификации отвечает класс <strong>TfgAuthenticationServiceManager</strong>.
</p>

<p>
	Для упрощения работы с сервисами добавлены клиенты аутентификации — компоненты, которые можно привычным способом бросить на форму в дизайнере и настроить с помощью инспектора объектов.
</p>

<p>
	<span style="font-size:22px;"><strong>Клиент для аутентификации с помощью Apple ID - TfgAppleIdAuthenticationClient (iOS)</strong></span>
</p>

<p>
	Общие сведения по использованию <a href="https://developer.apple.com/documentation/authenticationservices?language=objc" rel="external nofollow">фреймворка</a>.
</p>

<p>
	Абсолютно все сервисы аутентификации требуют предварительной настройки на стороне сервера и на стороне клиента (приложения).
</p>

<p>
	<span style="color:#c0392b;"><strong>Важно</strong></span>: необходимо иметь платный аккаунт разработчика.
</p>

<p>
	<span style="font-size:16px;"><strong>Настройка серверной части.</strong></span>
</p>

<ol><li>
		Переходим по <a href="https://developer.apple.com/account/resources/identifiers/list" rel="external nofollow">ссылке </a> и попадаем в список идентификаторов приложений.
	</li>
	<li>
		Нажимаем кнопку добавления нового идентификатора приложения.
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3158" href="https://forum.fgx-native.com/uploads/monthly_2022_03/3.png.1c57d91e7b867c653a58df8ee3369e80.png" rel=""><img alt="3.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3158" data-unique="iflcb36b3" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/3.thumb.png.ed1229a9a929094ef9267ca1e39aceef.png" loading="lazy" height="290"></a>
		</p>
	</li>
	<li>
		Выбираем опцию <strong>App IDs</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3159" href="https://forum.fgx-native.com/uploads/monthly_2022_03/4.png.ba9ce2f3de8402f65e255c51e85f62fc.png" rel=""><img alt="4.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3159" data-unique="gdkkzav3o" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/4.thumb.png.4b6d7732625b02b0d55526ec61def845.png" loading="lazy" height="450"></a>
		</p>
	</li>
	<li>
		Тип идентификатора <strong>App</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3160" href="https://forum.fgx-native.com/uploads/monthly_2022_03/5.png.8e9a127ba0117737b7e2cf12ab7f70e3.png" rel=""><img alt="5.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3160" data-unique="n3k19a7cb" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/5.thumb.png.542156d9a57b73fe29adf6280203fe25.png" loading="lazy" height="320"></a>
		</p>
	</li>
	<li>
		Добавляем описание, указываем уникальный <strong>Band ID</strong> (он далее понадобится нам при настройке приложения) и отмечаем галку напротив опции <strong>Sign In with Apple</strong>
		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3161" href="https://forum.fgx-native.com/uploads/monthly_2022_03/7.png.21610e1b5defbb509486ef4dcd0ea0d4.png" rel=""><img alt="7.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3161" data-unique="dtkii6s4n" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/7.thumb.png.0b11509a73affed0622b65ceccc39326.png" loading="lazy" height="600"></a>
		</p>
	</li>
	<li>
		<p>
			Подтверждаем изменения и сохраняем новый идентификатор.
		</p>
	</li>
</ol><p>
	<span style="font-size:16px;"><strong>Настройка клиентской части.</strong></span>
</p>

<ol><li>
		<p>
			Для успешной сборки приложения необходимо в <strong>SDK </strong>добавить фреймворк <strong>AuthenticationServices </strong>.
		</p>

		<p>
			Для этого необходимо открыть настройки <strong>SDK</strong> <em>Tools-Options-Deployment-SDK Manager</em>, в списке <strong>SDK</strong> выбрать <strong>iOS </strong>и нажать кнопку добавления нового элемента.
		</p>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3162" href="https://forum.fgx-native.com/uploads/monthly_2022_03/1.png.ad1a318c84477b638d4c4629a0fbd8d8.png" rel=""><img alt="1.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3162" data-unique="iinmbh4nt" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/1.thumb.png.b12b5ebd5d550fc8205e02b27214d3fc.png" loading="lazy" height="570"></a>
		</p>
	</li>
	<li>
		<p>
			Добавляем фреймворк со следующими параметрами:
		</p>

		<pre><code>Path: $(SDKROOT)/System/Library/Frameworks
Name: AuthenticationServices
Type: Framework</code></pre>

		<p style="text-align: center;">
			<img alt="2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3163" data-unique="l621v8rqq" style="height: auto; width: 380px;" width="484" src="https://forum.fgx-native.com/uploads/monthly_2022_03/2.png.c5c6cdeee0aee9b5138d2befe31c0378.png" loading="lazy" height="522.72"></p>
	</li>
	<li>
		<p>
			Нажимаем кнопку <strong>Update Local File Cache</strong> для обновления <strong>SDK</strong>.
		</p>
	</li>
	<li>
		<p>
			Переходим в настройки <strong>iOS </strong>профиля приложения и назначаем <strong>CFBundleIdentifier </strong>из шага 5 настройки серверной части.
		</p>

		<p style="text-align: center;">
			<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="3164" href="https://forum.fgx-native.com/uploads/monthly_2022_03/8.png.2260f7b6c309b2a92abc4b4560e32b83.png" rel=""><img alt="8.png" class="ipsImage ipsImage_thumbnailed" data-fileid="3164" data-unique="9dwjty4gc" style="height: auto; width: 800px;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2022_03/8.thumb.png.13c4638e08e71120fd89d79e91b2dba4.png" loading="lazy" height="740"></a>
		</p>
	</li>
</ol><p>
	<span style="font-size:22px;"><strong>Демо пример использования клиентов аутентификации</strong></span>
</p>

<p>
	В версии <strong>1.14.0.0</strong> в поставку библиотеки будет включен пример по использованию клиентов аутентификации, который будет расширяться по мере добавления новых сервисов.
</p>

<p>
	Данный пример вы можете загрузить уже сейчас не дожидаясь следующего релиза <a class="ipsAttachLink" data-fileext="zip" data-fileid="3200" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=3200&amp;key=3cbf3e12d9e81e45a39befc2371729ab" rel="">Authentication - Clients.zip</a>.
</p>

<p>
	 
</p>

<p>
	Спасибо за внимание.
</p>
]]></description><guid isPermaLink="false">40</guid><pubDate>Mon, 28 Mar 2022 21:43:00 +0000</pubDate></item><item><title>&#x41D;&#x43E;&#x432;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43F;&#x43E;&#x43D;&#x435;&#x43D;&#x442;&#x44B;-&#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x44B; &#x43F;&#x430;&#x433;&#x438;&#x43D;&#x430;&#x446;&#x438;&#x438; &#x432;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x43A;&#x43E;&#x43C;&#x43F;&#x43E;&#x43D;&#x435;&#x43D;&#x442;&#x43E;&#x432; TfgVirtualPagerLayout &#x438; TfgPagerLayout</title><link>https://forum.fgx-native.com/blogs/entry/37-%D0%BD%D0%BE%D0%B2%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D1%8B-%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D1%8B-%D0%BF%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0%D1%86%D0%B8%D0%B8-%D0%B2%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D0%BE%D0%B2-tfgvirtualpagerlayout-%D0%B8-tfgpagerlayout/</link><description><![CDATA[<p>
	Добрый вечер,
</p>

<p style="text-align: justify;">
	Мы плотно работаем над новой версией библиотеки <strong>FGX Native</strong>, в которую войдут новые компоненты-контейнеры и многие другие улучшения. В этой статье мы хотели бы поделиться двумя новыми компонентами-контейнерами <strong>TfgVirtualPagerLayout</strong> и <strong>TfgPagerLayout</strong>, которые появятся в релизе <strong>1.13.1.0</strong>. 
</p>

<p>
	<span style="font-size:22px;"><strong>TfgVirtualPagerLayout</strong></span>
</p>

<p style="text-align: justify;">
	Это базовый компонент, который предназначен для динамической загрузки/выгрузки страниц по мере их необходимости. В отличии от привычных подходов с добавлением вложенных компонентов заранее в дизайнере, этот компонент запрашивает загрузку/выгрузку страницы через события <strong>OnLoadPage</strong> и <strong>OnUnloadPage</strong> по мере их необходимости. Это значит, что фактически вместо загрузки 10-20 страниц, он загружает только видимую и еще 1-2 смежных в зависимости от текущего состояния компонента и, как следствие, ускоряет загрузку приложения.
</p>

<p style="text-align: justify;">
	На базе данного компонента можно легко сделать оптимизированный слайдер изображений. Например вот такой:
</p>

<p style="text-align: justify;">
	<video class="ipsEmbeddedVideo" controls="" data-fileid="2973" data-unique="71qmnbe8b" id="ips_uid_4353_6" src="https://forum.fgx-native.com/uploads/monthly_2021_11/PhotoSlider.mp4.51a710daea562eff861dab2b35a54d5a.mp4" style="max-width: 300px" data-controller="core.global.core.embeddedvideo" preload="metadata"><source type="video/mp4" src="https://forum.fgx-native.com/uploads/monthly_2021_11/PhotoSlider.mp4.51a710daea562eff861dab2b35a54d5a.mp4"><a class="ipsAttachLink" data-fileext="mp4" data-fileid="2973" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=2973&amp;key=4e10a7a5c201db247ee8a350b1282912" rel="">PhotoSlider.mp4</a>
	</source></video></p>

<p>
	Компонент не хранит все страницы у себя и работает по cхожему c <strong>TfgCollectionView </strong>принципу, те запрашивает необходимую информацию у разработчика через набор событий. Перед использованием компонента, вам необходимо написать обработчики для 3-х событий:
</p>

<ul><li>
		<strong>OnGetPageCount </strong>- вернуть общее количество страниц в компоненте.
	</li>
	<li>
		<strong>OnLoadPage</strong> - вернуть компонент страницы. Это может быть любой визуальный компонент. Вы можете создавать  страницу в этом событии динамически, а можете реализовать пул объектов, чтобы повторно использовать выгруженные ранее страницы.
	</li>
	<li>
		<strong>OnUnloadPage</strong> - можно выполнить уничтожение страницы или вернуть страницу в пул объектов для дальнейшего повторного использования.
	</li>
</ul><p>
	Типичным примером реализации данных событий может быть такой код, создающий страницы с текстом на базе <strong>TfgLabel</strong>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8544_9"><span class="pln">procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer);
begin
  // Сообщаем компоненту о количестве страниц.
  ACount := 100;
end;

procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl);
var
  LPage: TfgLabel;
begin
  // Создаем страницу на базе TfgLabel, которая будет отображать номер страницы.
  LPage := TfgLabel.Create(nil);
  LPage.Font.Size := 30;
  LPage.Text := Format('Page %d', [AItemIndex]);
  APage := LPage;
end;

procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer;
  const APage: TfgControl);
begin
  // Удаляем страницу.
  APage.Free;
end;</span></pre>

<p>
	В результате получим:
</p>

<p>
	<video class="ipsEmbeddedVideo" controls="" data-fileid="2974" data-unique="fdhu3sd9l" id="ips_uid_4353_7" src="https://forum.fgx-native.com/uploads/monthly_2021_11/Basic_Text_Pages.mp4.973884ec3e69398563dd470c6041a2c6.mp4" style="max-width: 300px" data-controller="core.global.core.embeddedvideo" preload="metadata"><source type="video/mp4" src="https://forum.fgx-native.com/uploads/monthly_2021_11/Basic_Text_Pages.mp4.973884ec3e69398563dd470c6041a2c6.mp4"><a class="ipsAttachLink" data-fileext="mp4" data-fileid="2974" href="https://forum.fgx-native.com/applications/core/interface/file/attachment.php?id=2974&amp;key=4bd2399757a8c4d4717a544167f78701" rel="">Basic_Text_Pages.mp4</a>
	</source></video></p>

<p>
	 
</p>

<p style="text-align: justify;">
	<span style="font-size:20px;">Пул страниц</span>
</p>

<p style="text-align: justify;">
	В этом примере вы можете обратить внимание, что если страницы по структуре одинаковые, то смысла удалять страницу и создавать заново особо не имеет смысла. Поэтому для этого случая, можно написать простой пул объектов, который не будет удалять вкладку, как только она не нужна, а складывать ее в список для дальнейшего повторного использования. Для реализации пула страниц создадим два списка:
</p>

<ol><li style="text-align: justify;">
		Список используемых страниц в компоненте в текущий момент времени - <strong>FAcquiredPages</strong>.
	</li>
	<li style="text-align: justify;">
		Список использованных страниц, которые уже не используются в текущий момент времени - <strong>FReleasedPages</strong>.
	</li>
</ol><p style="text-align: justify;">
	Код по объявлению списков выглядит так:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4353_9" style=""><span class="pln">type
  TFormMain = class(TfgForm)
  private
    FAcquiredPages: TList</span><span class="tag">&lt;TfgLabel&gt;</span><span class="pln">;
    FReleasedPages: TObjsetList</span><span class="tag">&lt;TfgLabel&gt;</span><span class="pln">;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  FormMain: TFormMain;

implementation

{$R *.xfm}

uses
  System.SysUtils, FGX.Application, FGX.Dialogs, FGX.Log;

{ TFormMain }

constructor TFormMain.Create(AOwner: TComponent);
begin
  inherited;
  FAcquiredPages := TList</span><span class="tag">&lt;TfgLabel&gt;</span><span class="pln">.Create;
  FReleasedPages := TObjsetList</span><span class="tag">&lt;TfgLabel&gt;</span><span class="pln">.Create;
end;

destructor TFormMain.Destroy;
begin
  FreeAndNil(FAcquiredPages);
  FreeAndNil(FReleasedPages);
  inherited;
end;</span></pre>

<p style="text-align: justify;">
	Теперь, когда компонент запрашивает страницу мы выполняем простые действия:
</p>

<ul><li style="text-align: justify;">
		Если страница есть в пуле, то мы ее извлекаем.
	</li>
	<li style="text-align: justify;">
		Если свободной страницы в пуле нет, то создаем новую.
	</li>
</ul><p style="text-align: justify;">
	Когда же страница выгружается компонентом, мы просто возвращаем ее в пул.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8544_13" style=""><span class="pln">procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer);
begin
  ACount := 100;
end;

procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl);
var
  Page: TfgLabel;
begin
  if FReleasedPages.Count = 0 then
  begin
    // В пуле нету свободных страниц, создаем новую
    Page := TfgLabel.Create(nil);
    Page.Font.Size := 30;
  end
  else
    // В пуле есть свободная страница, берем ее
    Page := FReleasedPages.ExtractAt(0);

  // Переносим страницу в список используемых страниц.
  FAcquiredPages.Add(Page);

  // Задаем текст и возвращаем страницу
  Page.Text := Format('Page %d', [AItemIndex]);
  APage := Page;
end;

procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer;
  const APage: TfgControl);
begin
  TfgAssert.IsClass(APage, TfgLabel);

  // Возвращаем страницу в пул для повторного использования
  FAcquiredPages.Remove(APage as TfgLabel);
  FReleasedPages.Add(APage as TfgLabel);
end;</span></pre>

<p style="text-align: justify;">
	Теперь мы получили такое же приложение, как и без использования пула, но теперь страницы не пересоздаются по мере их пролистывания, а повторно используются. Тем самым мы ускоряем процедуру загрузки страниц. 
</p>

<p style="text-align: justify;">
	Таким образом, этот компонент позволяет ускорить загрузку приложения за счет загрузки только необходимых страниц, а не всех сразу. На базе данного компонента можно легко реализовать слайдер изображение с большим количеством изображений и многое другое.
</p>

<p style="text-align: justify;">
	<span style="font-size:20px;">Динамическое изменение страниц</span>
</p>

<p style="text-align: justify;">
	Поскольку компонент запрашивает страницы и их количество у разработчика, то при любом изменении количества страниц, удаление/добавление страниц необходимо уведомить об этом компонент при помощи следующих методов:
</p>

<ul><li style="text-align: justify;">
		<strong>Reload</strong> - Уведомляет компонент о том, что список страниц изменился и надо заново его построить.
	</li>
	<li style="text-align: justify;">
		<strong>NotifyPageInserted </strong>- Уведомляет компонент, что в список вставлены новые страницы по указанным индексам.
	</li>
	<li style="text-align: justify;">
		<strong>NotifyPageRemoved </strong>- Уведомляет компонент, что из списка нужно удалить страницы по указанным индексам.
	</li>
</ul><p style="text-align: justify;">
	<span style="color:#e74c3c;">Состав страниц нельзя менять в процессе переключения вкладок!</span>
</p>

<p style="text-align: justify;">
	<span style="font-size:20px;">Дополнительные события</span>
</p>

<p style="text-align: justify;">
	Данный компонент предлагает широкий набор дополнительных событий, позволяющих полностью контролировать процесс смены вкладок:
</p>

<ul><li>
		<strong>OnChanged</strong> - Вызывается только при интерактивной смене вкладки, как только компонент понимает на какую вкладку окончательно переключается пользователь. 
	</li>
	<li>
		<strong>OnBeginDragging</strong> - Вызывается, когда пользователь опустил палец на экран и начал двигать содержимое. 
	</li>
	<li>
		<strong>OnEndDragging</strong> - Вызывается, когда пользователь поднял палец с экрана и закончил двигать содержимое.
	</li>
	<li>
		<strong>OnBeginScrolingAnimation</strong> - Вызывается, когда началась анимация смены вкладки.
	</li>
	<li>
		<strong>OnEndScrolingAnimation</strong> - Вызывается, когда анимация смены вкладки закончилась.
	</li>
</ul><p>
	<span style="font-size:22px;"><strong>TfgPagerLayout</strong> </span>
</p>

<p>
	Этот компонент-контейнер построен на базе <strong>TfgVirtualPagerLayout</strong> и в отличии от <strong>TfgVirtualPagerLayout</strong> выравнивает все добавленные в него компоненты по страницам. Он не выгружает/загружает страницы и по сути является аналогом <strong>TfgPageControl</strong>. Вы добавляете в него любые компоненты и <strong>TfgPagerLayout</strong> сам осуществляет их выравнивание и переключение.<br>
	 
</p>
]]></description><guid isPermaLink="false">37</guid><pubDate>Tue, 16 Nov 2021 00:17:34 +0000</pubDate></item><item><title>&#x421;&#x431;&#x43E;&#x440;&#x43A;&#x430; &#x438; &#x430;&#x43D;&#x430;&#x43B;&#x438;&#x437; &#x43B;&#x43E;&#x433;&#x43E;&#x432; &#x434;&#x43B;&#x44F; iOS &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; &#x443;&#x442;&#x438;&#x43B;&#x438;&#x442;&#x44B; Console</title><link>https://forum.fgx-native.com/blogs/entry/32-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0-%D0%B8-%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-ios-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D1%8B-console/</link><description><![CDATA[<p style="text-align: justify;">
	Здравствуйте.<br>
	В этой статье мы поговорим об отладке приложений на <strong>iOS </strong>с помощью логирования (часть материала будет актуальна и для <strong>Android</strong>). 
</p>

<p style="text-align: justify;">
	<span style="font-size:24px;"><strong>Общие сведения.</strong></span><br>
	Логирование позволяет получать информацию о работе вашего приложении даже когда оно запущено без отладчика, при фатальных падениях приложения и тд. <br>
	Особенно тема логирования актуальна для мобильных платформ, т.к. здесь, к сожалению, <strong>Delphi </strong>отладчик не может похвастаться такой же стабильностью и качеством, как отладчик для платформы <strong>Win32</strong>. Пошаговая отладка выливается в мучительное ожидание переходов, показываемые отладчиком значения могут не соответствовать действительности, либо вообще отсутствовать и тд. 
</p>

<p style="text-align: justify;">
	<span style="color:#c0392b;"><strong>Важно!</strong></span> Логирование не заменяет полностью<strong> </strong>отладчик, а является вспомогательным инструментом. 
</p>

<p style="text-align: justify;">
	Условно механизм логирования можно разделить на источник логов и на утилиты для сборки и просмотра логов.
</p>

<p>
	<span style="font-size:24px;"><strong>Источники логов.</strong></span>
</p>

<p style="text-align: justify;">
	Источником логов может быть как библиотека <strong>FGX Native</strong>, операционная система, так и само приложение (сообщения отправленные непосредственно разработчиком). На первые два варианта разработчик особо не может повлиять, поэтому более подробно остановимся на третьем варианте.
</p>

<p style="text-align: justify;">
	Отправка сообщения в лог осуществляется с помощью кроссплатформенного класса <strong>TfgLog</strong>. Все методы <strong>TfgLog </strong>являются классовыми, а сам класс существует в единственном экземпляре - это означает, что для его использования нет необходимости создавать экземпляр класса. 
</p>

<p style="text-align: justify;">
	Основным методом класса является метод <strong>Log </strong>позволяющий отправить строку с указанным уровнем лога.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_11" style=""><span class="pln">    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Выводит в системный лог сообщение </span><span class="tag">&lt;c&gt;</span><span class="pln">AMessage</span><span class="tag">&lt;/c&gt;</span><span class="pln"> типа </span><span class="tag">&lt;c&gt;</span><span class="pln">ALogType</span><span class="tag">&lt;/c&gt;</span><span class="pln">.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    class procedure Log(const ALevel: TfgLogLevel; const AMessage: string);</span></pre>

<p style="text-align: justify;">
	Уровни лога определяют степень важности того или иного события.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_13" style=""><span class="pln">  /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Уровень логирования.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
  TfgLogLevel = (Trace, Debug, Info, Warning, Error, Fatal);</span></pre>

<p>
	Вы можете определить минимальный уровень лога с помощью свойства <strong>MinimumLevel</strong>, чтобы уменьшить количество выводимых в лог сообщений
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_15" style=""><span class="pln">    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">
    ///   Указывает минимальный уровень лога, начиная с которого сообщение будет выводиться в системный лог.
    ///   Порядок следования уровней: Debug, Info, Warning, Error, Fatal. Debug - самый низкий.
    /// </span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    /// </span><span class="tag">&lt;remarks&gt;</span><span class="pln">
    ///   Для </span><span class="tag">&lt;c&gt;</span><span class="pln">DEBUG</span><span class="tag">&lt;/c&gt;</span><span class="pln"> конфигурации выводятся все типы сообщений по умолчанию. Для </span><span class="tag">&lt;c&gt;</span><span class="pln">RELEASE</span><span class="tag">&lt;/c&gt;</span><span class="pln"> сообщений выше
    ///   </span><span class="tag">&lt;c&gt;</span><span class="pln">Info</span><span class="tag">&lt;/c&gt;</span><span class="pln">. Если вы хотите видеть в релизной сборке вашего приложения и отладочные сообщения, то задайте
    ///   значение </span><span class="tag">&lt;c&gt;</span><span class="pln">TfgLogLevel.Debug</span><span class="tag">&lt;/c&gt;</span><span class="pln"> в это свойство. Данная настройка распространяется только на этот класс. На
    ///   логирование через сервис </span><span class="tag">&lt;c&gt;</span><span class="pln">IFGXLoggerService</span><span class="tag">&lt;/c&gt;</span><span class="pln"> она не действует.
    /// </span><span class="tag">&lt;/remarks&gt;</span><span class="pln">
    class property MinimumLevel: TfgLogLevel read FMinimumLogLevel write FMinimumLogLevel;</span></pre>

<p>
	Для удобства у класса <strong>TfgLog </strong>есть набор одноименных методов, соответствующих каждому уровню лога. Например:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_17" style=""><span class="pln">    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">
    ///   Выводит в системный лог низкоуровневое отладочное сообщение </span><span class="tag">&lt;c&gt;</span><span class="pln">AMessage</span><span class="tag">&lt;/c&gt;</span><span class="pln"> для выполнения трассировки.
    /// </span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    class procedure Trace(const AMessage: string); overload;
    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">Выводит в системный лог отладочное сообщение </span><span class="tag">&lt;c&gt;</span><span class="pln">AMessage</span><span class="tag">&lt;/c&gt;</span><span class="pln">.</span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    class procedure Debug(const AMessage: string); overload;</span></pre>

<p>
	В дополнение, у каждого такого метода существует перегруженная версия, принимающая во втором аргументе список параметров для отправки форматированной строки:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_19" style=""><span class="pln">    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">
    ///   Выводит в системный лог низкоуровневое отладочное сообщение </span><span class="tag">&lt;c&gt;</span><span class="pln">AMessage</span><span class="tag">&lt;/c&gt;</span><span class="pln"> с поддержкой форматирования </span><span class="tag">&lt;c&gt;</span><span class="pln">System.Format</span><span class="tag">&lt;/c&gt;</span><span class="pln">.
    /// </span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    class procedure Trace(const AFormat: string; const Args: array of const); overload;
    /// </span><span class="tag">&lt;summary&gt;</span><span class="pln">
    ///   Выводит в системный лог отладочное сообщение </span><span class="tag">&lt;c&gt;</span><span class="pln">AMessage</span><span class="tag">&lt;/c&gt;</span><span class="pln"> с поддержкой форматирования </span><span class="tag">&lt;c&gt;</span><span class="pln">System.Format</span><span class="tag">&lt;/c&gt;</span><span class="pln">.
    /// </span><span class="tag">&lt;/summary&gt;</span><span class="pln">
    class procedure Debug(const AFormat: string; const Args: array of const); overload;</span></pre>

<p>
	<br><span style="font-size:24px;"><strong>Сборка и просмотр логов.</strong></span>
</p>

<p style="text-align: justify;">
	Для просмотра логов с <strong>iOS </strong>используется утилита, работающая на компьютере под управлением <strong>macOS </strong>под названием <strong>Console</strong>.<br>
	Для просмотра логов с <strong>Android </strong>используется утилита работающая на компьютере под управлением <strong>Windows </strong>под названием <strong>logcat</strong>.<br>
	Частично логирование в контексте <strong>Android </strong>было затронуто ранее в <strong>Уроке 1</strong> <a href="https://youtu.be/8iuf87f4S8A?t=923" rel="external nofollow">«Настройка окружения, Hello World приложение и логирование»</a>.<br>
	В данной статье мы сосредоточимся на утилите <strong>Console</strong>.
</p>

<p style="text-align: justify;">
	<strong><span style="color:#c0392b;">Важно!</span></strong> Подразумевается, что вы имеете настроенную связку: компьютер под управлением <strong>macOS </strong>к которому подключено устройство с <strong>iOS</strong>. 
</p>

<p style="text-align: justify;">
	Исходные данные: на устройстве с <strong>iOS </strong>установлено приложение под названием <strong>TestLogging</strong>, которое имеет только две кнопки, при нажатии на которые отправляются сообщения в системный лог.<br>
	Код выглядит следующим образом:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3537_9" style=""><span class="pln">uses
  System.SysUtils, FGX.Application, FGX.Dialogs, FGX.Log;

procedure TFormMain.fgButton1Tap(Sender: TObject);
begin
  TfgLog.Debug('Hello from TfgLog.Debug');
end;

procedure TFormMain.fgButton2Tap(Sender: TObject);
begin
  TfgLog.Info('Hello from TfgLog.Info');
end;</span></pre>

<p style="text-align: justify;">
	Теперь перейдем непосредственно к утилите сбора и просмотра логов.<br>
	Запустите утилиту <strong>Console </strong>которая находится в <strong>Launchpad </strong>-&gt; <strong>Other</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="2637" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_3706212814.jpeg.2dfe25fc61f0664885af17f9132e635c.jpeg" rel=""><img alt="tg_image_3706212814.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="2637" data-unique="7e73pw42r" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_3706212814.thumb.jpeg.87df21fbbbd75df8f8d151151222c358.jpeg" loading="lazy" height="620"></a>
</p>

<p>
	 
</p>

<p style="text-align: justify;">
	Главное окно состоит из меню навигации в левой части (1), тулбара с органами управления вверху (2) и списка логов, который занимают остальную клиентскую область окна (3).
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="2638" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_133399642.jpeg.055188c1b6f688c281dcde0a45d683d7.jpeg" rel=""><img alt="tg_image_133399642.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="2638" data-unique="2e8rqnklw" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_133399642.thumb.jpeg.c230d17b943b3c8249f59919f47e8470.jpeg" loading="lazy" height="540"></a>
</p>

<p>
	 
</p>

<p style="text-align: justify;">
	Теперь выбираем в меню навигации слева устройство из списка <strong>Devices </strong>с которого мы хотим получать логи. В нашем случае это устройство с именем <strong>IPhone</strong>.
</p>

<p style="text-align: center;">
	<img alt="tg_image_196408901.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="2639" data-unique="uk12ydw3i" style="height: auto;" width="383" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_196408901.jpg.6e45ae3cc1874d40b418a7561b7c33a0.jpg" loading="lazy" height="743.02"></p>

<p>
	 
</p>

<p style="text-align: justify;">
	Теперь запускаем сбор логов с помощью кнопки тулбара <strong>Start </strong>или кликнув по ссылке <strong>Start streaming</strong> находящейся в центре списка логов.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="2640" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_133399641.jpg.1c5363c9fe763f5b7a177afe3442e040.jpg" rel=""><img alt="tg_image_133399641.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="2640" data-unique="ahfu4qszf" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_133399641.thumb.jpg.cfdefe0bd80b90b891193ba85c2c513c.jpg" loading="lazy" height="460"></a>
</p>

<p style="text-align: justify;">
	После старта список логов будет быстро наполняться сообщениями. <br>
	Список логов представляет собой таблицу с настраиваемыми колонками. Вы можете настроить видимость колонок по своему усмотрению с помощью контекстного меню, вызываемого по клику на заголовки таблицы.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="2641" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_196408903.jpg.2aefcbee74374c442f779df757e598e0.jpg" rel=""><img alt="tg_image_196408903.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="2641" data-unique="vaq9scrnk" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_196408903.thumb.jpg.8ef18526419a204fc6c448e0ab2ca188.jpg" loading="lazy" height="350"></a>
</p>

<p style="text-align: justify;">
	 
</p>

<p style="text-align: justify;">
	Самая полезная для нас информация находится в колонке <strong>Message </strong>- это непосредственно текстовое сообщение лога. Более удобно текстовое сообщение просматривать в окне детальной информации, которое можно открыть двойным кликом по строке списка логов, либо с помощью кнопки тулбара <strong>Info</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="2643" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_4251286926.jpeg.04a000e8caa501f0524531c100c2b95b.jpeg" rel=""><img alt="tg_image_4251286926.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="2643" data-unique="7so84flgj" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_4251286926.thumb.jpeg.18248616a322f90d1526187ae94ba620.jpeg" loading="lazy" height="690"></a>
</p>

<p style="text-align: justify;">
	Теперь запустим наше тестовое приложение и последовательно нажмем обе кнопки.
</p>

<p style="text-align: justify;">
	Лог содежит тысячи записей, среди которых практически невозможно найти интересующие нас строки.  Для решения этой задачи существуют фильтры, которые располагаются в правой части тулбара. Механизм фильтрация довольно гибкий и позволяет комбинировать несколько фильтров по разным колонкам с учетом выбранного способа сравнения (частичное или полное совпадение включая вариант с отрицанием).
</p>

<p style="text-align: justify;">
	<strong><span style="color:#c0392b;">Важно!</span></strong> Фильтрация осуществляется без учета регистра.
</p>

<p>
	Есть несколько способов, как можно отобразить только те строки, которые относятся к нашему приложению. Самый простой вариант - отфильтровать по имени процесса. Вводим фразу <strong>TestLogging</strong> в окно <strong>Search </strong>и нажимаем клавишу <strong>Enter </strong>на клавиатуре. По-умолчанию создастся фильтр с типом <strong>Any </strong>и способом сравнения <strong>Containts. </strong>Теперь изменим тип фильтра с <strong>Any </strong>на<strong> Process</strong>, a<strong> Containts </strong>на <strong>Equal, </strong>что означает, что в списке логов останутся только те строки, текст которых в колоноке равен  <strong>TestLogging</strong>. 
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="2644" href="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_1332426471.jpg.b41b509735c5fd2985150c76e3ffd391.jpg" rel=""><img alt="tg_image_1332426471.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="2644" data-unique="bhyj9k65o" style="height: auto;" width="1000" src="https://forum.fgx-native.com/uploads/monthly_2021_07/tg_image_1332426471.thumb.jpg.0fc1711eda74aedfce9cecac2f04b9b8.jpg" loading="lazy" height="690"></a>
</p>

<p>
	На скриншоте видно, как строки переданные самой библиотекой <strong>FGX Native</strong>, так и те, которые были отправлены после нажатия на кнопки (отмечены стрелками). Теперь вы можете изучать собранную информацию просматривая сообщения. При необходимости вы можете сохранить выделенные строки в буфер обмена, либо передать их в другое приложение к помощью кнопки тулбара <strong>Share</strong>.
</p>

<p>
	 
</p>

<p>
	Логирование - мощный инструмент, который может пригодиться в самых трудных и запутанных ситуациях при поиске ошибок. 
</p>

<p>
	Спасибо за внимание и удачной отладки!
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">32</guid><pubDate>Tue, 06 Jul 2021 09:19:39 +0000</pubDate></item><item><title>&#x423;&#x442;&#x438;&#x43B;&#x438;&#x442;&#x430; &#x433;&#x435;&#x43D;&#x435;&#x440;&#x430;&#x446;&#x438;&#x438; &#x437;&#x430;&#x433;&#x43E;&#x43B;&#x43E;&#x432;&#x43E;&#x447;&#x43D;&#x44B;&#x445; &#x444;&#x430;&#x439;&#x43B;&#x43E;&#x432; &#x434;&#x43B;&#x44F; Java (Java2Delphi)</title><link>https://forum.fgx-native.com/blogs/entry/23-%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D0%B0-%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8-%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BE%D1%87%D0%BD%D1%8B%D1%85-%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-java-java2delphi/</link><description><![CDATA[<p>
	В ближайшие дни выйдет новый релиз библиотеки <strong>FGX Native</strong> 1.9.3.0, главной новинкой которой будет утилита командной строки для генерации заголовочных файлов <strong>Delphi</strong> для использования <strong>Java API</strong> /<strong>Android API</strong>. 
</p>

<p>
	Утилита располагается в каталоге "<strong>$(FGX)\Tools\Java2Delphi</strong>" и в ее состав входят:
</p>

<ol><li>
		<strong>Java2Delphi.exe</strong> - утилита.
	</li>
	<li>
		<strong>config.template.json</strong> - Шаблон конфигурационного файла, в котором указаны правила формирования итоговых Delphi-модулей.
	</li>
	<li>
		<strong>api-versions.android-28.xml</strong> - Файл с информацией об <strong>Android API</strong> 28 версии.
	</li>
	<li>
		<strong>UsedGUID.txt</strong> - набор использованных GUID значений для <strong>Delphi </strong>интерфейсов.
	</li>
	<li>
		<strong>run.bat</strong> - пакетный файл для запуска утилиты в любом месте.
	</li>
</ol><p>
	Перед первым применением необходимо выполнить настройку утилиты.
</p>

<p>
	<strong><span style="font-size:22px;">Настройка</span></strong>
</p>

<p>
	Управление утилитой идет при помощи конфигурационного <strong>json</strong>-файла, передаваемого через аргументы командной строки. Перед первым применением, необходимо:
</p>

<p>
	1. Создать каталог в любом месте, где будут размещены все результаты генерации.
</p>

<p>
	2. Скопировать файл "<strong>run.bat</strong>" в каталог (1).
</p>

<p>
	3. Скопировать конфигурационный шаблон "<strong>config.template.json"</strong> в каталог (1) и назвать его <strong>"config.json"</strong> (название может быть любым).
</p>

<p>
	4. Отредактировать базовые настройки Java окружения:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_7" style="">
<span class="pln">    "javap": "$(JAVA_HOME)\\bin\\javap.exe",
    "jar": "$(JAVA_HOME)\\bin\\jar.exe",</span></pre>

<p>
	<strong>Java2Delphi </strong>использует две утилиты командной строки из <strong>Java SDK</strong>: "<strong>javap.exe</strong>" и "<strong>jar.exe</strong>". По умолчанию она использует переменную окружения <strong>$(JAVA_HOME)</strong>. Если она у вас указана в <strong>Windows</strong>, то этот шаг можно пропустить. Если нет, то либо необходимо добавить ее с указанием местоположения <strong>Java JDK</strong>:
</p>

<p>
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2192" data-unique="f9k2gndbi" style="height: auto;" width="691" src="https://forum.fgx-native.com/uploads/monthly_2021_03/image.png.d59891920782eaca4b8cddd96c5b44c4.png" loading="lazy" height="228.03"></p>

<p>
	или напрямую указать пути к требуемым утилитам.
</p>

<p>
	5. Указываем пути, куда будут помещены результаты генерации (<strong>опционально</strong>).
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_9" style="">
<span class="pln">    "outputDir": ".\\Headers",
    "signatureOutputDir": ".\\Signatures",</span></pre>

<ul><li>
		<strong>outputDir </strong>- каталог, куда будут помещены pas файлы с необходимыми обертками <strong>Java</strong>/<strong>Android Api</strong>.
	</li>
	<li>
		<strong>signatureOutputDir</strong> - вспомогательный каталог, куда будут помещены вспомогательные файлы с сигнатурами <strong>Java </strong>классов.
	</li>
</ul><p>
	После выполнения первичной настройки файла конфигурации, приступим теперь к указанию, какие <strong>Java </strong>классы надо транслировать.
</p>

<p>
	<strong><span style="font-size:22px;">Правила генерации файлов</span></strong>
</p>

<p>
	Для того, чтобы сгенерировать заголовочные файлы необходимо указать:
</p>

<ol><li>
		<strong>Jar</strong>-библиотеки, которые содержат необходимые <strong>Java </strong>классы.
	</li>
	<li>
		Указать требуемые для перевода <strong>Java </strong>классы.
	</li>
	<li>
		Указать, в какие <strong>Delphi </strong>модули разместить результирующие обертки.
	</li>
</ol><p>
	<span style="font-size:20px;">1. Указываем нужные jar библиотеки.</span>
</p>

<p>
	Библиотеки указываются в секции <strong>jars</strong>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_11" style="">
<span class="pln">"jars": [
        "E:\\Development\\Android\\platforms\\android-28\\android.jar"
    ],</span></pre>

<p>
	По умолчанию, мы всегда подключаем <strong>jar</strong> библиотеку <strong>Android</strong> (по-этому не удаляйте ее, если хотите совместимости с <strong>Android API</strong>).<br><strong><span style="color:#e74c3c;">Вам необходимо откорректировать расположение данного файла с учетом вашей системы. </span></strong>
</p>

<p>
	<span style="font-size:20px;">2. Указываем требуемые для перевода <strong>Java </strong>классы.</span>
</p>

<p>
	Теперь мы должны сказать утилите в секции "<strong>classes</strong>", какие классы нас интересуют в этих библиотеках. Здесь необходимо использовать полное название <strong>Java </strong>типов с учетом названия пакета:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_13" style="">
<span class="pln">    "classes": [
        "java.lang.Object",
        "java.lang.CharSequence",
        "java.lang.String",
        "java.lang.Class",
        "java.lang.Boolean",
        "java.lang.Number",

        // Можно использовать * на конце пакета, чтобы выбрать все классы в данном пакете
        "android.provider.*",

        "android.view.animation.Animation",
        "android.view.animation.Animation.AnimationListener",
        "android.view.animation.Animation.Description",

        // и тд</span></pre>

<p>
	По умолчанию шаблон включает в себя все классы из <strong>Android API</strong>, которые используются в <strong>FGX Native</strong>. Поэтому не удаляйте эти классы, если вы хотите получить заголовочные файлы, совместимые с уже существующими хедерами в <strong>FGX Native</strong>.
</p>

<p>
	Добавьте сюда те, которые вас интересуют.
</p>

<p style="margin-left: 40px;">
	<span style="color:#27ae60;"><strong>Поскольку в некоторых библиотеках могут быть 1000 классов. То обработка такого количества классов займет много времени. Помимо этого, вы получите гигантских размеров заголовочные файлы. Поэтому лучше добавлять только те классы, которые вам реально нужны для вызовов, а не все.</strong></span>
</p>

<p>
	<span style="font-size:20px;">3. Указываем правила генерации Delphi модулей.</span>
</p>

<p>
	После того, как мы перечислили интересуемые нас <strong>Java </strong>классы, нам остается только указать, в какие <strong>Delphi </strong>модули их следует поместить. Это делается через "<strong>output</strong>":
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_15" style="">
<span class="pln">"output": [
        {
            "name": "Android.Api.Text", // Название Делфи модуля Android.Api.Text.pas
            "uses": [ // Подключаемые Делфи модули в Android.Api.Text.pas
                "Android.Api.JavaTypes",
                "Android.Api.ActivityAndView"
            ],
            "classes": [ // Java классы, обертки над которыми будут добавлены в Android.Api.Text.pas
                "android.text.*"
            ],
            "exclude": [ // Опционально, можно исключить некоторые классы
                "android.text.method.*",
                "android.text.util.*",
                "android.text.ClipboardManager*"
            ]
        }
    ]</span></pre>

<p>
	<strong><span style="font-size:22px;">Генерация</span></strong>
</p>

<p>
	Поздравляю, теперь вы можете запустить утилиту и наблюдать, как она трудится формируя заголовочные файлы по вашим правилам.
</p>

<p>
	<img alt="2021-03-13_21-51-47.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2194" data-unique="dq0sjy0zw" style="height: auto;" width="938" src="https://forum.fgx-native.com/uploads/monthly_2021_03/2021-03-13_21-51-47.png.8be8db076cce48e1cb2588bed12ac658.png" loading="lazy" height="225.12"></p>

<p>
	Обратите внимание, что первый запуск занимает много времени, так как утилита генерирует сигнатуры <strong>Java </strong>классов (именно они используются для анализа структуры <strong>Java</strong> классов) и помещает их в каталог "<strong>signatureOutputDir</strong>". Однако, последующие запуски будут выполняться моментально, за счет того, что утилита не выполняет повторную генерацию сигнатур, если она уже есть. 
</p>

<p style="margin-left: 40px;">
	<strong><span style="color:#27ae60;">Не удаляйте файлы сигнатур, они помогут ускорить повторную генерацию заголовочных файлов.</span></strong>
</p>

<p>
	<strong><span style="font-size:22px;">Разбор пропущенных классы/методов/полей</span></strong>
</p>

<p>
	В процессе генерации утилита выполняет много сложной работы с анализом зависимостей, доступных типов и тд. Если какой-то из <strong>Java </strong>типов не указан в секции "<strong>classes"</strong>, то утилита пропустит все его использования. При этом она сообщит об этом через лог.
</p>

<p>
	<strong>Например</strong>: При генерации <strong>класса android.text.HTML</strong> были пропущены два метода <strong>fromHTML</strong> (они не попали в <strong>pas </strong>файлы), потому что не был указан тип <strong>android.text.Html$ImageGetter</strong>.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_18" style="">
<span class="pln">Skipped members of the Java type: android.text.Html
  Methods:
    - fromHtml(const AArg0: JString; const AArg1: Integer; const AArg2: JHtml_ImageGetter; const AArg3: JHtml_TagHandler): JSpanned; [android.text.Html$ImageGetter]
    - fromHtml(const AArg0: JString; const AArg1: JHtml_ImageGetter; const AArg2: JHtml_TagHandler): JSpanned; [android.text.Html$ImageGetter]</span></pre>

<p>
	Если вам нужны эти методы, то необходимо в секцию <strong>classes </strong>добавить этот тип:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_4899_25" style="">
<span class="pln">    "classes": [
        "android.text.Html.ImageGetter",</span></pre>

<p>
	Обратите внимание, что в <strong>Java </strong>"$" - это разделитель для вложенных классов. Однако в конфигурационном файле вместо него надо использовать "<strong>.</strong>".
</p>]]></description><guid isPermaLink="false">23</guid><pubDate>Sat, 13 Mar 2021 18:58:00 +0000</pubDate></item><item><title>&#x412;&#x438;&#x434;&#x435;&#x43E; &#x437;&#x430;&#x43F;&#x438;&#x441;&#x44C; &#x43F;&#x440;&#x43E;&#x431;&#x43D;&#x43E;&#x439; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x432;&#x43E;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x438; &#x43E;&#x442;&#x432;&#x435;&#x442;&#x43E;&#x432; &#x43F;&#x43E; FGX Native</title><link>https://forum.fgx-native.com/blogs/entry/22-%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-%D0%BF%D1%80%D0%BE%D0%B1%D0%BD%D0%BE%D0%B9-%D1%81%D0%B5%D1%81%D1%81%D0%B8%D0%B8-%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%B8-%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D0%BE%D0%B2-%D0%BF%D0%BE-fgx-native/</link><description><![CDATA[<p>
	Добрый день,
</p>

<p>
	Мы выложили запись прошедшего 18 февраля вебинара по теме "Пробная сессия вопросов и ответов по FGX Native". Видео доступно на нашем <a href="https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w" rel="external nofollow">YouTube канале</a>.
</p>

<p>
	На вебинаре обсуждались следующие темы:
</p>

<ol><li>
		 Android SDK/NDK;
	</li>
	<li>
		Сервисы локации;
	</li>
	<li>
		Асинхронная загрузка изображений в списках;
	</li>
	<li>
		Планы на ближайшие релизы.
	</li>
</ol><p>
	 
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="113" id="ips_uid_1503_6" src="https://www.youtube.com/embed/gUUyTqGxdZs?feature=oembed" width="200" loading="lazy"></iframe>
	</div>
</div>

<p>
	 
</p>]]></description><guid isPermaLink="false">22</guid><pubDate>Fri, 19 Feb 2021 12:18:00 +0000</pubDate></item><item><title>&#x41C;&#x438;&#x433;&#x440;&#x430;&#x446;&#x438;&#x44F; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F; &#x441;&#x442;&#x430;&#x440;&#x43E;&#x433;&#x43E; Android &#x43C;&#x43E;&#x441;&#x442;&#x430; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x44B;&#x439;</title><link>https://forum.fgx-native.com/blogs/entry/10-%D0%BC%D0%B8%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D1%81%D1%82%D0%B0%D1%80%D0%BE%D0%B3%D0%BE-android-%D0%BC%D0%BE%D1%81%D1%82%D0%B0-%D0%BD%D0%B0-%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9/</link><description><![CDATA[<p>
	Всем доброго дня!
</p>

<p>
	Как и обещал ранее, перед релизом 1.4.0.0 выкладываю инструкцию о миграции использования старого Android-Delphi моста на новый в 1.4.0.0. Это руководство актуально тем разработчикам, которые используют Android Api в своих проектах. В этой статье я рассмотрю только те аспекты в работе моста, которые изменились.
</p>

<p>
	По большей части изменения были необходимы только в свете поддержки RAD Studio 10.4, в которой была полностью удалена поддержка модели памяти ARC.
</p>

<p>
	<span style="font-size:18px;"><strong>1. Создание Java объекта:</strong></span>
</p>

<p>
	Было:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2624_5" style="">
<span class="pln">var
  Intent: TJIntent;

Intent := TJIntent.Create;</span></pre>

<p>
	Стало: 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2624_7" style="">
<span class="pln">var
  Intent: JIntent;

Intent := TJIntent.Create;</span></pre>

<p>
	Все объявления переменных, атрибутов и тд должны быть теперь именованы без префикса <strong>"T"</strong>. <strong>TJActivity</strong> -&gt; <strong>JActivity</strong>.
</p>

<p>
	<span style="font-size:18px;"><strong>2. Передача Java объектов через Java интерфейс:</strong></span>
</p>

<p>
	Было:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2546_6" style="">
<span class="pln">// Декларация метода. Принимает атрибут интерфейсного типа CharSequence.
TJTextView.setError(const AArg0: JCharSequence);

// Java cтрока TJString реализует интерфейс JCharSequence. Поэтому передача идет напрямую (в старой версии моста).
View.setError(StringToJString(Control.Error));</span></pre>

<p>
	Стало:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2546_8" style="">
<span class="pln">// Декларация метода. Принимает атрибут интерфейсного типа CharSequence.
TJTextView.setError(const AArg0: JCharSequence);

// Теперь обертка Java cтроки TJString НЕ реализует явно интерфейс JCharSequence. Поэтому необходима явная конвертация JString -&gt; JCharSequence
View.setError(TJCharSequence.Wrap(StringToJString(Control.Error)));

// Или можно воспользоваться хелпером из FGX.Helpers.Android.pas
View.setError(StringToJCharSequence(Control.Error));</span></pre>

<p>
	<span style="font-size:18px;"><strong>3. Работа с Java массивами:</strong></span>
</p>

<p>
	При создании экземпляра Java массива (<strong>TJavaArray&lt;T&gt;</strong>) вся работа теперь осуществляется через интерфейс <strong>IJavaArray&lt;T&gt;</strong>.
</p>

<p>
	Было:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8281_8" style="">
<span class="pln">var
  Points: TJavaArray</span><span class="tag">&lt;Single&gt;</span><span class="pln">;
 
Points := TJavaArray</span><span class="tag">&lt;Single&gt;</span><span class="pln">.Create(0);
FCanvas.drawLines(Points, FStroke);</span></pre>

<p>
	Стало:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_8281_6" style="">
<span class="pln">var
  Points: IJavaArray</span><span class="tag">&lt;Single&gt;</span><span class="pln">;
 
Points := TJavaArray</span><span class="tag">&lt;Single&gt;</span><span class="pln">.Create(0);
FCanvas.drawLines(Points, FStroke);</span></pre>

<p>
	<strong><span style="font-size:18px;">4. Работа с Java-листенерами:</span></strong>
</p>

<p>
	Если вы реализовывали свои листенеры через наследование класса <strong>Java.Bridge.TJavaLocal</strong>, то в 1.4.0.0 листенеры теперь поддерживают счетчик ссылок через <strong>Delphi IInterface</strong>. Это значит, что при создании листенера, его необходимо сохранять в переменную/поле интерфейсного типа, а не объектного.
</p>

<p>
	Было:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1203_7" style="">
<span class="pln">  TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener)
  private
    [Weak] FCamera: TfgAndroidCamera;
  public
    constructor Create(const ACamera: TfgAndroidCamera);
    { JCameraStateListener }
    procedure onClosed(const AArg0: JCameraDevice);
    procedure onDisconnected(const cameraDevice: JCameraDevice);
    procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer);
    procedure onOpened(const cameraDevice: JCameraDevice);
  end;

var
  FStateListener: TfgAndroidCameraStateListener

FStateListener := TfgAndroidCameraStateListener.Create(Self);
FStateCallback.setListener(FStateListener);</span></pre>

<p>
	Стало:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1203_9" style="">
<span class="pln">  TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener)
  private
    [Weak] FCamera: TfgAndroidCamera;
  public
    constructor Create(const ACamera: TfgAndroidCamera);
    { JCameraStateListener }
    procedure onClosed(const AArg0: JCameraDevice);
    procedure onDisconnected(const cameraDevice: JCameraDevice);
    procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer);
    procedure onOpened(const cameraDevice: JCameraDevice);
  end;

var
  FStateListener: JCameraStateListener

FStateListener := TfgAndroidCameraStateListener.Create(Self);
FStateCallback.setListener(FStateListener);</span></pre>

<p>
	В противном случае, экземпляр листенера <strong>FStateListener </strong>будет удален сразу же после вызова 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1203_12" style="">
<span class="pln">FStateCallback.setListener(FStateListener);</span></pre>

<p>
	Что в свою очередь приведет к последующим падения приложения. Так как сработает механизм подсчета ссылок Delphi интерфейсов. 
</p>

<p>
	<strong><span style="font-size:18px;">5. Конвертация string &lt;-&gt; JString:</span></strong>
</p>

<p>
	До RAD Studio 10.4 мобильные компиляторы поддерживали добавление операторов неявного преобразования. Это в свою очередь позволило нам реализовать автоматическую конвертацию "на лету" Delphi string &lt;-&gt; Java JString. В 10.4 эту возможность убрали вместе с ARC, так как неявное преобразование реализуется через ARC. Поэтому теперь нужно явно вызывать преобразование строк через <strong>StringToJString </strong>и <strong>JStringToString</strong>:
</p>

<p>
	Было:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7960_9" style="">
<span class="pln">TjUri.parse('tel:+');</span></pre>

<p>
	Стало:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7960_7" style="">
<span class="pln">uses
  FGX.Helpers.Android;

TJUri.parse(StringToJString('tel:+'))</span></pre>

<p>
	Это все изменения, которые необходимо сделать.
</p>]]></description><guid isPermaLink="false">10</guid><pubDate>Thu, 25 Jun 2020 23:42:00 +0000</pubDate></item><item><title>&#x412;&#x438;&#x434;&#x435;&#x43E; &#x423;&#x440;&#x43E;&#x43A; 1. &#x41D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430; &#x43E;&#x43A;&#x440;&#x443;&#x436;&#x435;&#x43D;&#x438;&#x44F;, Hello World &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x438; &#x43B;&#x43E;&#x433;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435;</title><link>https://forum.fgx-native.com/blogs/entry/14-%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-%D1%83%D1%80%D0%BE%D0%BA-1-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-hello-world-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8-%D0%BB%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/</link><description><![CDATA[<p>
	Мы стараемся делать так, чтобы <strong>FGX Native </strong>стала эффективным инструментом <span class="ipsEmoji">?</span> для разработчиков, приносила результаты и доставляла удовольствие от работы <span class="ipsEmoji">?</span>.
</p>

<p>
	Мы постоянно работаем над расширением возможностей и предоставляем новый функционал. Однако, с учетом молодости проекта <strong>FGX Native</strong> по нему не так много информации.
</p>

<p>
	Эффективность использования зависит от ваших умений и навыков. А для развития этих умений и навыков нужны обучающие материалы <span class="ipsEmoji">?‍?</span>, примеры правильного использования.
</p>

<p>
	Мы решили провести небольшой пробный эксперимент и для начала записать пару обучающих видео уроков по использованию <strong>FGX Native</strong>.
</p>

<p>
	Рад представить вам первый, самый базовый урок для начинающих о начале разработки мобильных приложений с FGX Native и Delphi. В уроке рассматривается:
</p>

<ol><li>
		Настройка рабочего окружения;
	</li>
	<li>
		Создание Hello World мобильного приложения;
	</li>
	<li>
		Запись и чтение логов в FGX Native.
	</li>
</ol><p>
	Следующий урок будет о системе выравнивания Flex в FGX Native. Рассмотрим типовые задачи и их решения. Сверстаем сложный макет приложения. Чтобы не пропустить, подписывайся на новый официальный канал FGX Native: <a href="https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w" ipsnoembed="true" rel="external nofollow">https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w</a> 
</p>

<p>
	Приятного обучения:
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="270" id="ips_uid_336_4" src="https://www.youtube.com/embed/8iuf87f4S8A?feature=oembed" width="480" loading="lazy"></iframe>
	</div>
</div>

<p>
	 
</p>]]></description><guid isPermaLink="false">14</guid><pubDate>Thu, 28 May 2020 21:00:00 +0000</pubDate></item><item><title>&#x410;&#x432;&#x442;&#x43E;&#x433;&#x435;&#x43D;&#x435;&#x440;&#x430;&#x446;&#x438;&#x44F; classes.dex</title><link>https://forum.fgx-native.com/blogs/entry/16-%D0%B0%D0%B2%D1%82%D0%BE%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F-classesdex/</link><description><![CDATA[<p>
	В обновлении <strong>1.1.6.0</strong> процесс сборки android приложения претерпел незаметное на первый взгляд, но очень важное для пользователей изменение, а именно,  добавлена автоматическая генерация файла <strong>classes.dex</strong>.
</p>

<pre class="ipsCode" id="ips_uid_4075_9">
classes.dex - обязательный для android приложения файл, содержащий все используемые в приложении Java библиотеки.</pre>

<p>
	Ранее конечное приложение собиралось с готовым <strong>classes.dex</strong> файлом поставляемым вместе с библиотекой FGX Native, что создавало для разработчиков некоторые проблемы при использовании сторонних <strong>jar </strong>библиотек. Процесс добавления был нетривиален и требовал глубокого погружения в документацию, процессы сборки и микширования <strong>classes.dex</strong>.
</p>

<p>
	Механизм автоматической генерации уже используется в <strong>FMX </strong>проектах, однако, по ряду причин и ограничений, накладываемых IDE, он не мог быть задействован для <strong>FGX Native</strong>.
</p>

<p>
	Мы пересмотрели пользовательский опыт и рады представить вам новый удобный диалог для управления <strong>jar</strong> библиотеками, используемыми в проекте.
</p>

<p>
	Вызвать диалог можно двумя способами:
</p>

<ol><li>
		Через главное меню: <em>Project -&gt; FGX Android Libraries</em>
	</li>
	<li>
		Через контекстное меню панели <em>Projects</em>. <em>Target Platforms -&gt; Android (32/64 bits) -&gt; Libraries -&gt; Setup Android Libraries</em>.
	</li>
</ol><p style="text-align: center;">
	<img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="2077" data-unique="zvq6fh0zj" style="height: auto;" width="813" src="https://forum.fgx-native.com/uploads/monthly_2021_02/image.png.ff2ef24d00653c77469cf8888aa1e9c3.png" loading="lazy" height="569.1"></p>

<p>
	Всё, что необходимо для включения в ваше приложение сторонней <strong>jar </strong>библиотеки — это добавить её в разделе «<em>Все модули</em>» или «<em>Пользовательские</em>».
</p>

<p>
	Для возврата списка библиотек к первоначальноиу состоянию воспользуйтесь кнопки «<em>По-умолчанию</em>».
</p>]]></description><guid isPermaLink="false">16</guid><pubDate>Mon, 04 May 2020 21:00:00 +0000</pubDate></item></channel></rss>
