Бывает что есть сайт, но пользоваться им с мобильного телефона не очень удобно и было бы замечательно иметь отдельное приложение для него. Любители веб разработки легко смогут это сделать использую phoneGap. Под катом речь пойдет про сервис отслеживания почтовых отправлений, которым я часто пользуюсь и написанный для него демонстрационный клиент с базовым функционалом: авторизация, получение списка треков и описания к ним и возможность добавить новый трек. Я не связывался с разработчиком по этому поводу и очень надеюсь что он на меня не обидится за наглость, за копание в JavaScript коде и за то что в приложении не будет показана реклама. Так же прошу простить за костыльность и велосипедность кода, воспринимайте его как пример.Статья подразумевает, что вы сами сможете разобраться как работает сайт, информация с которого будет отображаться в приложении.
Те кто читали прошлую статью об авторизации через некоторые сайты уже знаю что в phoneGap есть замечательная штука inAppBrowser, которая не только открывает сайт внутри приложения, но и позволяет внедрить в него свой JavaScript код и поменять стили, что пригодится для форм авторизации.
На её основе, по образу и подобию авторизации на хабре был написан вот такой код:
var plugin_www_post_tracker_ru = {
wwwref: false,
authOk: false,
auth: function (force) {
if (!window.localStorage.getItem("plugin_www_post_tracker_ru_PHPSESSID") || force) { //если нет данных об авторизации или принудительная авторизация
var authURL="http://post-tracker.ru/login.php";
this.wwwref = window.open(encodeURI(authURL), '_blank', 'location=no'); // открываем сайт внутри приложения
this.wwwref.addEventListener('loadstop', this.auth_jsinjection); // по завершении загрузки делаем инъекцию в код
} else {
plugin_www_post_tracker_ru.authOk=true;
}
},
auth_event_url: function (url) {
var tmp=url_parser.get_args_cookie(url); // парсин ответов с куками
if (tmp['PHPSESSID'] && tmp['userid'] && tmp['securehash']) { // если все нужные куки есть, то видимо авторизировалис
plugin_www_post_tracker_ru.wwwref.close(); // закроем браузер и сохраним полученные параметры
window.localStorage.setItem("plugin_www_post_tracker_ru_PHPSESSID", tmp['PHPSESSID']);
window.localStorage.setItem("plugin_www_post_tracker_ru_userid", tmp['userid']);
window.localStorage.setItem("plugin_www_post_tracker_ru_securehash", tmp['securehash']);
plugin_www_post_tracker_ru.authOk=true;
перейдем тут на получение контента
}
},
auth_cssinjection: function(){
plugin_www_post_tracker_ru.wwwref.insertCSS({code:".topline {display:none} .top {display:none} .logo {display:none} .menu {display:none} .counters {display:none} .bottom {display:none} .links {display:none} @-viewport {width: device-width; zoom: 1;"},function(){});
},
auth_jsinjection: function () {
plugin_www_post_tracker_ru.auth_cssinjection(); // вставляем CSS код в форму авторизации, для скрытия лишних блоков
plugin_www_post_tracker_ru.wwwref.executeScript({ // JS код для получения куков
code: "document.cookie;"
}, function(arg) {
plugin_www_post_tracker_ru.auth_event_url(arg);
});
}
}
Для получения контента будем использовать небольшую AJAX библиотеку, способную делать POST и GET запросы, которая умеет вставлять cookie и отдающая полученный результат в callback функцию (основа взята из miniajax):
AJAX
var ajax = {
init: function(){
return new XMLHttpRequest();
},
send: function(url,method,args,cookies,async,_callback){
var q=ajax.init();
q.open(method,url,async);
q.onreadystatechange=function(){
if(this.readyState==4 && this.status==200) {
_callback(this.responseText);
}
};
if (cookies) {
q.setRequestHeader('Cookie',cookies);
}
if(method=='POST') {
q.setRequestHeader('Content-type','application/x-www-form-urlencoded');
q.send(args);
} else {
q.send(null);
}
}
}
Для получения контента делаем GET запрос на страничку post-tracker.ru/my/ при этом, если в ответе в одном из блоков мы встретим строку
Войдите или Зарегистрируйтесь, то нас явно разлогинили и придется пройти процедуру еще раз: get_content: function (async) { // делам запрос на страницу с трек кодами
var cookies="PHPSESSID="+window.localStorage.getItem("plugin_www_post_tracker_ru_PHPSESSID")+"; userid="+window.localStorage.getItem("plugin_www_post_tracker_ru_userid")+"; securehash="+window.localStorage.getItem("plugin_www_post_tracker_ru_securehash"); // формируем cookie
plugin_www_post_tracker_ru.dataReady=false;
ajax.send("http://post-tracker.ru/my/",'GET',null,cookies,async,this._parse_content); // делаем ajax запрос и посылаем его содержимое для распарсивания
},
_parse_content: function (data) {
var wrapper=document.createElement('div'); // заворачиваем html код внутрь объекта, чтобы удобнее с ним работать
wrapper.innerHTML=data;
plugin_www_post_tracker_ru._get_inside_data(wrapper,'trackcode,date,status,comment'); // и отправляем его на получение данных о треккоде, даты последнего изменения, статусе и описании посылки
},
_get_inside_data: function (wrapper,types) {
var tmp=wrapper.getElementsByClassName('login')[0].innerHTML; // на всякий случай получаем содежимое div блока login
if (tmp=='<a href="/login.php">Войдите</a> или <a href="/register.php">Зарегистрируйтесь</a>') { // если там такое, то придется авторизироватья
plugin_www_post_tracker_ru.auth(true);
} else { // а иначе продолжаем
plugin_www_post_tracker_ru.default_folder=wrapper.getElementsByTagName('input')[0].value; // получи ID стандартной папки с кодами, чтобы в дальнейшем можно было добавлять туда новые коды отправлений
var types=types.split(",");
for (var typeid in types) { // разбираем html-ку по блокам с заданными типами
var tmp=wrapper.getElementsByClassName(types[typeid]);
var id=0;
for (var i in tmp) {
if (tmp[i].innerHTML) {
if (!plugin_www_post_tracker_ru.postdata[id]) plugin_www_post_tracker_ru.postdata[id]=new Array();
plugin_www_post_tracker_ru.postdata[id][(types[typeid])]=tmp[i].innerHTML.replace(/(\r\n|\n|\r)/gm,"").replace(/<\/?[^>]+>/gmi,"").replace(/^\s+|\s+$/gm,""); // убираем все ненужности в виде переносов строки, html кода для оформления и лишние пробелы
id++;
}
}
}
plugin_www_post_tracker_ru.dataReady=true;
show_list(); // даем команду на отображение полученных данных
}
},
get_list: function () { // это будет запрошено функцией show_list() для "красоты" оформления
var tmp=new Array();
for (var i in plugin_www_post_tracker_ru.postdata) {
tmp[i]="<b>"+plugin_www_post_tracker_ru.postdata[i]['trackcode']+"</b> "+plugin_www_post_tracker_ru.postdata[i]['comment']+"<br/>"+plugin_www_post_tracker_ru.postdata[i]['date']+" "+plugin_www_post_tracker_ru.postdata[i]['status'];
}
return tmp;
}
show_list() в данном коде добавит блоки с подготовленной html-кой внутри div-а со скроллером (кстати рекомендую Overthrow и крайне не рекомендую iscroll-4 по причине ужасной скорости работы).Настала пора добавить возможность отправки новых кодов для отслеживания, но сперва добавим действие на кнопку MENU вашего Android смартфона. Делается это с помощью события menubutton. К которому мы привяжем появления блока с кнопкой «Добавить трек код», которая, при нажатии, начнет процесс.
put_trackCode: function(){ // то что будет выполнятя после нажатия на кнопку "Добавить трек код"
var trackCode = prompt("Введите трек код"); // запросим у пользователя сам треккод
if (trackCode) {
this._put_trackCode_getPath(trackCode); // запросим у сайта направление для этого кода (например из Китая в Россию), внимание тут снова не используем асинхронный запрос
if (plugin_www_post_tracker_ru.default_path) { // если получили направление, добавим описание
var comment = prompt("комментарий");
if (comment) {
this._put_trackCode(trackCode,comment); // и отправим эти данные на сайт
}
} else {
alert("Не правильный трек код");
}
} else {
menuButtonHide(); // если пользователь не захотел вводить, то не забудем скрыть блок с менюшкой
}
},
_put_trackCode_getPath: function (trackCode) { // запрашиваем направление
var cookies="PHPSESSID="+window.localStorage.getItem("plugin_www_post_tracker_ru_PHPSESSID")+"; userid="+window.localStorage.getItem("plugin_www_post_tracker_ru_userid")+"; securehash="+window.localStorage.getItem("plugin_www_post_tracker_ru_securehash");
var data="act=getPathForm&trackcode="+encodeURIComponent(trackCode);
ajax.send("http://post-tracker.ru/ajax/userTrackcodes.php",'POST',data,cookies,false,this._put_trackCode_getPath_result);
},
_put_trackCode_getPath_result: function (data){
var wrapper=document.createElement('div'); // заворачиваем ответ, представляющий собой html
wrapper.innerHTML=data;
var tmp=wrapper.getElementsByTagName('input'); // смотрим есть ли в ответе input
if (tmp.length>0) {
plugin_www_post_tracker_ru.default_path=tmp[0].value; // если есть, то значение в нем нам очень пригодится
}else{
plugin_www_post_tracker_ru.default_path=false;
}
},
_put_trackCode: function (trackCode,comment){ // отправляем треко код и комментарий к нему, снова не асинхронно
var cookies="PHPSESSID="+window.localStorage.getItem("plugin_www_post_tracker_ru_PHPSESSID")+"; userid="+window.localStorage.getItem("plugin_www_post_tracker_ru_userid")+"; securehash="+window.localStorage.getItem("plugin_www_post_tracker_ru_securehash");
var data="act=addTrackcodeAction&folderid="+plugin_www_post_tracker_ru.default_folder+"&trackcode="+encodeURIComponent(trackCode)+"&path="+plugin_www_post_tracker_ru.default_path+"&comment="+encodeURIComponent(comment);
ajax.send("http://post-tracker.ru/ajax/userTrackcodes.php",'POST',data,cookies,false,this._put_trackCode_result);
},
_put_trackCode_result: function(data){ // данные отправились
menuButtonHide(); // скрываем меню
plugin_www_post_tracker_ru.get_content(true); // и снова запрашиваем содержимое страницы с кодами посылок
}
Что бы еще можно было бы добавить к приложение, чтобы потренироваться с phoneGap? В первую очередь не помешает локализация, чтобы в коде не хранился текст и для разных стран не выводился только русский язык. Так же не помешает отрабатывать некоторые состояния, например пропажу интернет соединения или нажатие на кнопку «назад».В плане самого сервиса отслеживания, стоило бы добавит рекламу, на которую содержится ресурс, а так же увеличить функционал, добавив создание папок, автоматическую проверку с оповещениями и
Исходный код проекта и собранное приложение для тестов и экспериментов заинтересованных лиц. А так же гитхаб для менее унылых форков github.com/SovGVD/PhoneGap-post-tracker.ru
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Продолжать ли писать о phoneGap и эксперименты с ним?
82.65%Да, вполне интересно на что сгодится html/css/js для мобильных приложений667
17.35%Нет, писать что-то на веб технологиях для телефонов — безумие140
Проголосовали 807 пользователей. Воздержались 147 пользователей.
