Создаем оффлайновые Web-приложения для мобильных устройств на базе HTML5

Создание приложений, способных работать на различных операционных системах и разных мобильных устройствах, может быть непростой задачей. Высокий спрос на «умные» мобильные приложения требует высокопроизводительных аппаратных средств. Одним из решений в такой ситуации является создание Web-приложений, так как они могут выполняться на мобильных устройствах, основанных на различных платформах. Вместо закрытых технологий (таких как Objective-C и Cocoa для iPhone) можно использовать повсеместно поддерживаемые Web-технологии. Фактически можно обойтись всего одной версией приложения. Основная часть аппаратных ресурсов для таких приложений обеспечивается серверами. В данной статье мы рассмотрим применение Web-программирования для создания приложений для мобильных устройств на примере простого приложения, основанного на стандарте HTML5.

Дитмар Крюгер, ИТ-архитектор, IBM

Photo of Dietmar KruegerДитмар Крюгер работает в группе Application Innovation Services – сервисном подразделении IBM Global Business Services. Он разрабатывает объектно-ориентированное ПО на протяжении 17 лет. Дитмар увлекается гибкими технологиями разработки ПО, легковесными архитектурами и языками программирования с динамической типизацией.



09.02.2012

Введение

Web-приложения, разрабатываемые для мобильных устройств, становятся все более популярными. Однако нестабильность доступа к сетям является серьезным препятствием для использования Web-технологий как части облачной инфраструктуры. Традиционное Web-приложение просто не работает при отсутствии доступа к сети. Одним из решений этой проблемы является использование двух возможностей стандарта HTML5 (см. Ресурсы):

  • Оффлайновые Web-приложения
  • Хранение данных в базе данных на стороне клиента

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

В этой статье мы познакомимся с техническими деталями типового Web-приложения. Мы продемонстрируем технологию HTML5 на примере прототипа простого приложения для управления имуществом.

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

Обзор приложения

На рисунке 1 показаны основные компоненты архитектуры нашего примера приложения.

Рисунок 1. Основные компоненты оффлайнового Web-приложения
A diagram showing a user with an arrow to a box labeled 'HTML.' The 'HTML' box is pointing to 'CSS,' 'Manifest,' 'JavaScript,' and 'DB' boxes. The 'HTML' and 'JavaScript' boxes also point to the 'Server,' and the 'JavaScript' box also points to the 'DB' box.
HTML-страница
HTML-страница является основой приложения, она выполняет роль модели. Она содержит в себе отображаемые данные и (используемую по умолчанию) информацию для вывода страницы на экран. HTML-элементы страницы организованы в иерархию дерева объектной модели HTML-документа (Document Object Model или DOM). Инициируемые пользователем события приводят к выполнению традиционного цикла запрос-ответ, включающего в себя загрузку страницы и выполнение связанных с ней JavaScript-функций.

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

JavaScript
В блоке JavaScript содержатся управляющие функции приложения. HTML-элементы связываются с JavaScript-функциями посредством обработчиков событий. Код JavaScript имеет доступ к DOM-дереву HTML-элементов приложения, содержащему все элементы пользовательского интерфейса, и может использовать их как источник данных для вычислений. Результаты обработки могут быть представлены пользователю посредством изменений в HTML-странице.
Каскадная таблица стилей
В каскадной таблице стилей (Cascading Style Sheet, CSS) описывается, как HTML-страница отображается в браузере. Для простоты решения мы опустим задачу создания представления. На данном этапе HTML-элементы будут отображаться в соответствии с поведением, применяемым по умолчанию.

Для мобильных устройств существуют различные JavaScript/CSS библиотеки и инфраструктуры, позволяющие создать характерное для платформы оформление (например, iUi для iPhone). С более подробной информацией можно ознакомиться в разделе Ресурсы. Хотя применение таких библиотек необходимо для повышения привлекательности приложения для пользователя, этот подход имеет недостаток – зависимость от платформы.

База данных
В стандарте HTML5 было введено хранение данных в локальной базе данных. Она реализована в текущей версии браузера Safari от Apple®.®. В нем имеется встроенная база данных SQLite, к которой можно обращаться из JavaScript посредством SQL-запросов. В этой базе данных хранится бизнес-информация модели приложения.
Манифест
Файл манифеста – это обязательный компонент оффлайнового Web-приложения, представляющий собой дескриптор развертывания. В нем просто перечислены все файлы, которые нужно загрузить.

Пример приложения

В этом разделе мы представим наш пример приложения. Оно называется MyHomeStuff (мои домашние вещи). Это простое приложение для управления имуществом, которое позволяет отслеживать принадлежащие вам вещи. На рисунке 2 показано, как это приложение выглядит на iPhone.

Рисунок 2. Внешний вид приложения на iPhone
A screen shot of the 'MyHomeStuff' application on the iPhone. There are three bold headings in the view, with information under each. The headings are 'Overview,' 'Details,' and 'Status.'

Для простоты в приложении не реализована синхронизация данных с сервером. На рисунке 3 показано, как выглядит приложение MyHomeStuff в Web-браузере устройства Palm Pre.

Рисунок 3. Внешний вид приложения на Palm Pre
Same sceen shot as the previous image, but in a Palm Pre Web browser.

В списке в верхней части экрана перечислены все внесенные в приложение предметы (книги, компьютеры и т.д.).

Когда пользователь выбирает элемент из списка, в середине формы отображается подробная информация об этом элементе (идентификационный номер, количество, название). Информацию о выбранном элементе можно изменить, нажав кнопку Update. Также выбранный элемент можно удалить, нажав кнопку Delete. Новые элементы можно создавать, вводя в форме название элемента и количество и нажимая кнопку Create.

В нижней части экрана отображается статус приложения.

Код HTML

HTML-страница содержит декларации, метатеги для оптимизации отображения на мобильных устройствах, ссылки на внешние файлы (манифест, сценарии JavaScript, css) и HTML-элементы, формирующие базовую структуру приложения. В листинге 1 показан код.

Листинг 1. HTML-код
                <!DOCTYPE HTML>
                <html manifest="MyHomeStuff.manifest">
                <head>
                <meta name="viewport" content="width=device-width; 
                initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
                <title>MyHomeStuff</title>
                <script type="text/javascript" src="MyHomeStuff.js" ></script>
                </head>
                <body onload="onInit()">
                <h3>Overview</h3>
        <ul id="itemData" ></ul>
    <h3>Details</h3>
        <form name="itemForm">
            <label for="id">Id: </label>
            <input type="text" name="id" id="id" size=2 disabled="true"/>
            <label for="amount">Amount: </label>
            <input type="text" name="amount" id="amount" size = 3/>
            <label for="name">Name: </label>
            <input type="text" name="name" id="name" size=16 /> <br>
            <br>
            <input type="button" name="create" value="create"
                onclick="onCreate()" />
            <input type="button" name="update" value="update"
                onclick="onUpdate()" />
            <input type="button" name="delete" value="delete"
        </form>
    <h4>Status</h4>
        <div id="status"></div>
   </body>
</html>

В атрибутах обработки событий HTML-элементов указываются JavaScript-функции, которые следует выполнить при загрузке страницы (onload) и нажатии на элемент-кнопку (onclick).

HTML-страница оффлайнового Web-приложения начинается с тега <!DOCTYPE HTML>. Файл манифеста указывается с помощью атрибута тега <html manifest="MyHomeStuff.manifest">.

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

Листинг 2. Файл манифеста
CACHE MANIFEST

MyHomeStuff.js

Код JavaScript

Код JavaScript состоит из трех основных блоков:

  • функции инициализации
  • функции работы с базой данных (crud – создание (create), чтение (read), обновление (update), удаление (delete) элементов) и функции обновления представления
  • небольшие прикладные функции

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

Листинг 3. JavaScript-код для инициализации
function onInit(){
    try {
        if (!window.openDatabase) {
            updateStatus("Error: DB not supported");
        }
        else {
            initDB();
            createTables();
            queryAndUpdateOverview();
        }
    } 
    catch (e) {
        if (e == 2) {
            updateStatus("Error: Invalid database version.");
        }
        else {
            updateStatus("Error: Unknown error " + e + ".");
        }
        return;
    }
}

function initDB(){
    var shortName = 'stuffDB';
    var version = '1.0';
    var displayName = 'MyStuffDB';
    var maxSize = 65536; // in bytes
    localDB = window.openDatabase(shortName, version, displayName, maxSize);
}

Рассмотрим показанный выше код:

  • В функции onInit сначала проверяется существование обязательной функции openDatabase, отсутствие которой сигнализирует о том, что браузер не поддерживает локальную базу данных.
  • В функции initDB открывается база данных браузера HTML5.
  • После успешного открытия базы данных выполняется код SQL DDL, создающий таблицы базы данных. В заключение вызываются функции, которые запрашивают существующие записи и заполняют HTML-страницу данными.

Каждая JavaScript-функция из второго блока состоит из двух частей: логики доступа к базе данных и логики представления. Такое объединение логики характерно для архитектуры Model 1 (см. Ресурсы), которая является самым удобным способом разработки простых Web-приложений. Для реальных задач лучше подходит архитектура MVC с четким разделением логики модели (Model), представления (View) и контроллеров (Controller).

Для построения списка объектов используется функция queryAndUpdate, которая вызывается из обработчиков событий. В листинге 4 показан ее код.

Листинг 4. JavaScript-код для построения списка
function queryAndUpdateOverview(){

    //удаляем строки старой таблицы
    var dataRows = document.getElementById("itemData").getElementsByClassName("data");
    while (dataRows.length > 0) {
        row = dataRows[0];
        document.getElementById("itemData").removeChild(row);
    };

    //читаем данные из базы данных и создаем новые строки таблицы
    var query = "SELECT * FROM items;";
    try {
        localDB.transaction(function(transaction){
        
            transaction.executeSql(query, [], function(transaction, results){
                for (var i = 0; i < results.rows.length; i++) {
                
                    var row = results.rows.item(i);
                    var li = document.createElement("li");
                    li.setAttribute("id", row['id']);
                    li.setAttribute("class", "data");
                    li.setAttribute("onclick", "onSelect(this)");
                    
                    var liText =
                        document.createTextNode(row['amount'] + " x "+ row['name']);
                    li.appendChild(liText);
                    
                    document.getElementById("itemData").appendChild(li);
                }
            }, function(transaction, error){
                updateStatus("Error: " + error.code + "<br>Message: " + error.message);
            });
        });
    } 
    catch (e) {
        updateStatus("Error: Unable to select data from the db " + e + ".");
    }
}

В показанном выше коде выполняется следующее:

  • Из DOM-дерева удаляются старые данные.
  • Выполняется запрос для получения всех данных.
  • Для каждого полученного из базы данных элемента создается HTML-элемент, который добавляется в результирующий список.
  • К каждому элементу списка добавляется обработчик события onSelect, который будет отвечать на щелчок мыши по этому элементу.

В функциях этого блока также содержатся обработчики событий для элементов с панели кнопок: onUpdate, onDelete, onCreate и onSelect. В листинге 5 показан код функции onUpdate (функции onCreate и onDelete имеют похожую структуру и поэтому здесь не показаны; ссылка на полный исходный код примера приложения приведена ниже в таблице Загрузка).

Листинг 5. JavaScript-код для обновления записи
function onUpdate(){
    var id = document.itemForm.id.value;
    var amount = document.itemForm.amount.value;
    var name = document.itemForm.name.value;
    if (amount == "" || name == "") {
        updateStatus("'Amount' and 'Name' are required fields!");
    }
    else {
        var query = "update items set amount=?, name=? where id=?;";
        try {
            localDB.transaction(function(transaction){
                transaction.executeSql(query, [amount, name, id],
                function(transaction, results){
                    if (!results.rowsAffected) {
                        updateStatus("Error: No rows affected");
                    }
                    else {
                        updateForm("", "", "");
                        updateStatus("Updated rows:"
                            + results.rowsAffected);
                        queryAndUpdateOverview();
                    }
                }, errorHandler);
            });
        } 
        catch (e) {
            updateStatus("Error: Unable to perform an UPDATE " + e + ".");
        }
    }
}

В приведенном выше коде делается следующее:

  • Считываются и проверяются значения полей формы.
  • Если значения полей корректны, выполняется запрос для обновления данных.
  • Результат запроса показывается на обновленной HTML-странице.

Функция onSelect вызывается, когда пользователь выбирает какой-либо элемент списка. При этом информация о выбранном элементе помещается в форму. Этот код показан в листинге 6.

Листинг 6. JavaScript-код для выбора элемента из списка
function onSelect(htmlLIElement){
    var id = htmlLIElement.getAttribute("id");
    query = "SELECT * FROM items where id=?;";
    try {
        localDB.transaction(function(transaction){
        
            transaction.executeSql(query, [id], function(transaction, results){
            
                var row = results.rows.item(0);
                
                updateForm(row['id'], row['amount'], row['name']);
                
            }, function(transaction, error){
                updateStatus("Error: " + error.code + "<br>Message: " + error.message);
            });
        });
    } 
    catch (e) {
        updateStatus("Error: Unable to select data from the db " + e + ".");
    }
}

В приведенном выше коде делается следующее:

  • Определяется идентификатор выбранного элемента.
  • Выполняется запрос select.
  • Вызывается функция, помещающая в форму прочитанные значения.

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

Листинг 7. Код JavaScript-обработчиков
errorHandler = function(transaction, error){
    updateStatus("Error: " + error.message);
    return true;
}

nullDataHandler = function(transaction, results){
}

Чтобы избежать избыточности, мы сделали функции для заполнения полей формы (updateForm) и обновления статуса (updateStatus), которые показаны ниже.

Листинг 8. Прикладные функции JavaScript
function updateForm(id, amount, name){
    document.itemForm.id.value = id;
    document.itemForm.amount.value = amount;
    document.itemForm.name.value = name;
}

function updateStatus(status){
    document.getElementById('status').innerHTML = status;
}

Разворачиваем приложение

Для проверки работы нашего приложения на поддерживающих HTML5 мобильных устройствах мы использовали iPhone 3GS и Palm Pre. Также подойдет браузер Safari на обычном компьютере.

Загрузите файлы приложения по ссылке из таблицы Загрузка и разместите их на HTTP-сервере. HTTP-сервер нужно настроить так, чтобы он отдавал файл манифеста с Mime-типом text/cache-manifest. Откройте приложение на iPhone, сохраните для него закладку и переключитесь в оффлайновый режим («В самолете»). После этого приложение можно открыть с помощью закладки, и оно будет работать без доступа к сети.

Заключение

В этой статье мы рассмотрели технический аспект оффлайновых Web-приложений. Мы продемонстрировали технологию HTML5 на примере простого приложения управления имуществом, которое может работать в локальном режиме, используя локальную базу данных.


Загрузка

ОписаниеИмяРазмер
Исходный код примера для этой статьиOfflineWebAppSrc.zip3 KБ

Ресурсы

  • Познакомьтесь с оригиналом статьи: Create offline Web applications on mobile devices with HTML5 (developerWorks, май 2010 г.).
  • В руководстве Safari Client-Side Storage and Offline Applications Programming Guide (Apple Inc., 20 января 2010 г.) подробно рассказывается о поддержке в HTML5 баз данных, с которыми можно работать с помощью JavaScript.
  • В статье ABI Research: Cloud computing will transform mobile apps" (Dusan Belic, 2009 г.) рассматриваются Web-технологии как основная модель приложений для мобильных устройств, требующая только одной версии приложения.
  • "HTML 5 - A vocabulary and associated APIs for HTML and XHTML" (W3C Working Draft, 4 марта 2010 г.) - исчерпывающий источник информации об HTML5.
  • iUi: iPhone User Interface Framework - узнайте больше о разработке Web-приложений для устройств класса iPhone. iUi - это инфраструктура для разработки сложных Web-приложений для iPhone других подобных ему мобильных устройств, состоящая из JavaScript-библиотеки, CSS-таблиц и изображений.
  • Mobile app dev trends: Making life easier for developers (John K. Waters, июль 2009 г.) - читайте дискуссию о современных тенденциях в Web-разработке для мобильных устройств.
  • Узнайте больше о Model 1 - модели проектирования Web-приложений на Java. В Model 1 запрос посылается к JSP-странице или сервлету, которые и выполняют всю работу: обрабатывают запрос, проверяют данные, выполняют бизнес-логику и генерируют ответ.

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, SOA и web-сервисы
ArticleID=792560
ArticleTitle=Создаем оффлайновые Web-приложения для мобильных устройств на базе HTML5
publish-date=02092012