Все ленты — последние статьи

Разработка кроссплатформенных мобильных приложений в Delphi #2 (скрины на хабре)

Разработка кроссплатформенных мобильных приложений в Delphi #2

В предыдущей части цикла мы сделали обзор основных возможностей новой RAD Studio XE5. Сегодня же перейдем к практике. Прежде всего, давайте определимся с задачей.

Постановка задачи



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

 

Пересчет количества требуемых продуктов.

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

Таймер.

Если вы новичок в кулинарии, то, вам следует использовать рецепты, в которых четко указано время той или иной операции. И таймер на планшете, телефоне или нетбуке вполне может стать удобной заменой кухонному таймеру.
Часто бывает, что несколько операций выполняются параллельно. Каждая операция может иметь свой «таймер».
При этом нас интересует, как «настольная», так и мобильная реализация приложения. Мобильное приложение будет использоваться в качестве пособия для визуализации рецепта и сопровождения процесса подготовки. Настольная версия может быть использована в более расширенном функционале для, например, формирования новых рецептов.



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

Данное приложение мы реализуем для Windows и для Android. Затем на основе единой базы исходных кодов мы сможем выполнить портацию приложения на MacOS и iOS.

Выбор средств разработки



Прежде чем приступить непосредственно к разработке, давайте определимся с инструментарием. Разумеется, что данные, которые будут использоваться в приложении, целесообразнее всего хранить в базе данных.

Для чистоты эксперимента в качестве СУБД используем SQLite. Эта СУБД обладает рядом преимуществ, среди которых скорость работы, простота использования, экономичность в отношении ресурсов. Она идеально подходит для решения несложных задач, а кроме того, Android имеет встроенную поддержку SQLite.

В дальнейшем мы рассмотрим, каким образом можно перевести приложение на использования СУБД InterBase и покажем все преимущества «родного» решения от Embarcadero.

Вместе с приложением мы будем распространять уже готовую СУБД, созданную отдельно. Такой подход обусловлен спецификой задачи.

Конечно же, нам понадобиться Delphi XE5. Для создания Windows приложения в принципе мы могли бы ограничиться Professional редакциях. Но для т.н. мобильной разработки нам понадобиться как минимум Enterprise редакция продукта. В качестве альтернативы можно воспользоваться пакетом Mobile Add-On Pack for Delphi XE5 Professional.

Для работы с SQLite в Windows нам понадобится скачать с официального сайта библиотеку sqlite-dll-win32-x86-3080100.zip. Проще всего поместить данную библиотеку в одну из системных папок (например, Windows/SYSTEM32).
В настоящий момент существует довольно большое количество бесплатных средств администрирования баз данных SQLite. Вы вполне можете воспользоваться одним из них.

Доступ к базе данных из приложения мы будем осуществлять с помощью библиотеки FireDAC.

FireDAC — это универсальная библиотека доступа к данным, предназначенная для разработки приложений, подключаемых к различным базам данных. С помощью FireDAC можно разрабатывать, как VCL, так и FireMonkey приложения. Библиотека поддерживает следующие СУБД: InterBase, SQLite, MySQL, SQL Server, Oracle, PostgreSQL, DB2, SQL Anywhere, Advantage DB, Firebird, Access, Informix. Однако, на данном этапе, в мобильных приложениях «напрямую» (без использования технологии DataSnap) с помощью FireDAC можно подключиться только к SQLite и InterBase.

Создание базы данных



Процесс разработки мы начнем с создания структуры базы данных. Логическая модель ее приведена на диаграмме.

Данная диаграмма получена с помощью еще одного инструмента от компании Embarcadero Technologies — ER/Studio. Developer редакция этого продукта доступна пользователям RAD Studio Architect. В рамках настоящей публикации мы не станем детально останавливаться на описании ER/Studio. Этот мощный инструмент вполне заслуживает того, что бы посвятить ему отдельный материал.



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

В таблице tblFoodstuff мы будем хранить список всех возможных продуктов. В таблице tblUnit – список единиц измерения (грамм, ложка, стакан и т.д.). Таблица tblRecipe содержит список рецептов. В таблицах tblIngredientes и tblAction содержатся перечень ингредиентов (с указанием количества в поле qty) и действий (с указанием времени и описаниями), соответственно.

Для создания SQLite базы вы можете просто воспользоваться приведенным ниже скриптом.

CREATE TABLE [tblAction] ( [Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [IdRc] INTEGER NOT NULL, [Sec] INTEGER NULL, [DescriptionShort] VARCHAR(128) NOT NULL, [DescriptionExtendent] TEXT NOT NULL ); CREATE TABLE [tblFoodstuff] ( [Id] INTEGER PRIMARY KEY AUTOINCREMENT NULL, [Abbr] VARCHAR(10) NULL, [Title] VARCHAR(50) NULL ); CREATE TABLE [tblIngredientes] ( [Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [IdCB] INTEGER NOT NULL, [IdFS] INTEGER NOT NULL, [IdUnit] INTEGER NOT NULL, [qty] INTEGER NULL ); CREATE TABLE [tblRecipe] ( [Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [Title] VARCHAR(150) NOT NULL ); CREATE TABLE [tblUnit] ( [Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [UnitName] VARCHAR(25) NOT NULL, [Abbr] VARCHAR(7) NOT NULL ); CREATE INDEX [IDX_TBLACTION_Recipe] ON [tblAction]( [IdRc] ASC ); CREATE INDEX [IDX_TBLINGREDIENTES_] ON [tblIngredientes]( [IdCB] ASC ); CREATE INDEX [idxFoodStuff] ON [tblIngredientes]( [IdFS] ASC ); CREATE INDEX [idxRecipe] ON [tblIngredientes]( [IdCB] ASC ); CREATE INDEX [idxUnit] ON [tblIngredientes]( [IdUnit] ASC ); 

 

Создание Windows приложения



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

IDE Delphi предоставляет несколько шаблонов новых приложений. В данном случае нас интересует FireMonkey Desktop Application.



После выбора соответствующего пункта меню на экран будет выведен дополнительный диалог, в котором будет предложено выбрать тип нового FireMonkey приложения — HD (High Definition) или 3D.



Переименуем главную форму приложения (в инспекторе объектов меняем свойство Name) и сохраним вновь созданный проект. Добавим в проект новый Data Module (меню File| Other ветка Delphi Files), переименуем и сохраним его.



Таким образом, мы создали новый проект и подготовились непосредственно к разработке.

Настройка FireDAC соединения


habrahabr.ru/topic/edit/200490/#
Первое, что нам необходимо сделать — настроить подключение к базе данных. В FireMonkey данная процедура существенно не отличается от VCL.
Поместим в DataModule компоненты TFDConnection, TFDGUIxWaitCursor и TFDPhysSQLiteDriverLink. В Object Inspector изменим значение свойства LoginPrompt компонента TFDConnection:

LoginPrompt = False

Двойной щелчок по компоненту на форме вызовет диалог настройки подключения.



В качестве Driver ID в нашем случае следует указать SQLite, а также в качестве значения параметра Database указать путь к файлу базы данных. Проверить правильность настроек можно с помощью кнопки Test.

Сразу же создадим функцию, отвечающую за подключение к БД в Run Time.

function TDM.ConnectToDB: Boolean; begin try FDConnection1.Connected := True; except end; Result:= FDConnection1.Connected; end; 



Для того, что бы данную функцию можно было вызвать из главного модуля, вынесем ее заголовок в секцию public.

Главная форма приложения



Для того, что бы данную функцию можно было вызвать из главного модуля, вынесем ее заголовок в секцию public.

На главную форму приложения последовательно поместим компоненты TGroupBox, TTabControl и TSplitter. Настроим для каждого из них свойство Alighn (alLeft, alLeft и alClient, соответственно). На левую панель помещаем два компонента — TlistBox и TBindNavigator. Размещаем их как показано на рисунке. Двойным щелчком мыши вызовем дизайнер пунктов компонента TTabControl, и создадим два пункта.

В левом части нашего приложения будет отображаться список рецептов. На вкладках в правой части — список ингредиентов блюда (с указанием количества) и непосредственно, сам рецепт, состоящий из определенного списка действий.

Подключение данных



Как мы уже говорили, в FireMonkey нет специальных компонентов отображения данных. Вместо этого используется механизм связывания LiveBinding. Давайте посмотрим, как он работает. Подключим список рецептов к компоненту TListBox на главной форме. Прежде всего, нужно создать набор данных для работы со списком рецептов. В модуле данных используем компонент TFDTable. Настроим его свойства следующим образом:


В код нашей функции ConnectToDB добавим вызов метода открытия набора данных.

FDTRecipe.Open; 



Для того, что бы установить соединение с базой в режиме Run Time следует добавить вызов функции ConnectToDB. Можно привязать его к событию OnCreate модуля данных.

procedure TDM.DataModuleCreate(Sender: TObject); begin DM.ConnectToDB; end; 



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

Организуем вывод данных из таблицы TRecipe в список на главной форме. Для этого, прежде всего, добавим модуль данных в секцию Uses модуля главной формы программы.

interface uses uDM, System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 



В редакторе формы вызовем контекстное меню и выберем пункт Bind Visually. В нижней части экрана откроется LiveBinding Designer. В нем в виде элементов диаграммы представлены объекты и их основные свойства. Простым перетаскиванием свяжем свойства трех объектов так, как это показано на рисунке.



Собственно, это все, что нужно для отображения данных из таблицы рецептов (т.е. списка названий рецептов). Если мы сейчас запустим программу, она покажет список, но он будет пустым, и нам следует позаботиться о том, как добавлять рецепты.

Создадим новую FireMonkey HD форму. Настроим ее свойства следующим образом:

Name = fAddRecipe BorderStyle = bsToolWindow Position = poMainFormCenter

Подключим модуль данных и поместим на форме компонент TEdit и две кнопки. В LiveBinding Designer свяжем свойство Text компонента TEdit с полем Title набора данных.



Сохраним новую форум и удалим ее из списка автоматически создаваемых форм (меню Project|Options вкладка Forms).

Для главной формы приложения создадим метод:

 procedure TfMain.RecipeAfterInsert(DataSet: TDataSet); var fAddRecipe: TfAddRecipe; begin try fAddRecipe:= TfAddRecipe.Create(Application); fAddRecipe.ShowModal; if fAddRecipe.ModalResult = mrOk then begin if DataSet.State in [dsInsert, dsEdit] then DataSet.Post; end else begin if DataSet.State in [dsInsert, dsEdit] then DataSet.Cancel; end; finally FreeAndNil(fAddRecipe); end; end; 



При запуске программы определим событие AfterInsert для набора данных с рецептами.

procedure TfMain.FormShow(Sender: TObject); begin DM.FDTRecipe.AfterInsert:= RecipeAfterInsert; end; 



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

В этой части цикла мы создали простейшее FireMonkey приложение для Windows. Научились устанавливать соединение с базой данных при помощи пакета FireDAC и рассмотрели простейший пример использования LiveBinding.

В следующей, возможно самой интересной, части цикла мы создадим первое Android приложение.