Легкий спосіб писати iOS додатки на вебі

  Всім привіт. Не так давно Габріель подарував нам гру 2048 . Це той самий дивний випадок, коли клон гри стає більш популярний, ніж оригінал. Чи не мала частина успіху Габріеля — відкритий код і, вуаля, MIT ліцензія. Набравши трохи більше 20к очок, захотілося поділитися результатом з друзями, окрім як зробити скріншот не вийшло. Глянув аппстора на наявність клона з геймцентром або чимось подібним — порожньо. І тут подумав, чому б ні?
Забігаючи вперед, на створення програми та всіх «ніштяк» до нього пішло 4 дні. На виході універсальний код, який від частини працює і в вебі і легко портується на ІОС / андроїд. Однак, давайте по порядку.
 
 
 
Як ви вже зрозуміли, мова піде про розробку нативних додатків на веб технологіях. Для тих, хто в танку, працює все досить просто. Створюється проект з нативними SDK, мета якого — розмістити на весь екран WebView і відкрити конкретний html в ньому. Тобто виходить, що всі додаток зводиться до браузеру з зашитою адресним рядком. Можна довго сперечатися, добре це чи погано. У мережі кучіща холіваров з цього приводу, хтось віддає перевагу html5, хтось нативний код. Я пишу і так і так, але тут, маючи исходники 2048 саме на вебі, було б нерозумно переписувати все на нативний objc. Та й потім, якщо мова йде про невеликий додатку, основне завдання якого — фронтенд + робота з сервером, знову ж нерозумно городити objc, коли можна обійтися html5.
Скажімо так, wunderlist прекрасно працює на веб технологіях. Як і офіційний gmail клієнт.
 
Наша команда на основному робочому місці робить b2b проекти. Це такі проекти, де при мінімальній відвідуваності робиться хороша ебіда. Так і у нас, мінімальні значення уникав на добу. Тому ми можемо «грати» технологіями. Поки деякі верстають під ie8, своїм клієнтам ми сказали, що тільки firefox або chrome, і вони беззастережно поставили співробітникам ці браузери. Тому ми досить давно юзаем всякі html5 штуки і радіємо. Однак, коли в голову прийшла ідея зробити такий проект, я навіть не уявляв, наскільки це буде цікаво і ново, не дивлячись на те, що в загальному я знав і частково застосовував майже всі технології, описані нижче.
Почнемо з оточення, далі пройдемося по технологіям і обговоримо помилки, зробимо висновки.
 
 image
 
 

1. Оточення.

Отцем WebView для мобільників, безсумнівно, є phoneGap . Він не погано документований (чого там документувати то?) І досить простий. Що ж він робить? Як і інші фреймворки, що дозволяють робити нативні додатки на базі веб технологій, phonegap проштовхує нативні можливості в JS код і назад. Тобто ви пишіть як писали раніше, адаптуєте дизайн під мобільний пристрій + маєте JS виклики, що дозволяють працювати з камерою, нотіфікейшенамі, контактами, СМС та іншим. Список можливостей і платформ доступний на спецсторінку . Побудований він на базі Cordova .
Так само советаю подивитися в бік Sencha , хлопці пішли трохи далі і дають можливість не просто отримати доступ до нативним фішках телефонів / планшетів через JS, але так само дають нативні UI. Тобто роблячи один додаток, виглядати воно буде як нативне і в Андройде і в ios `е. Однак, сенча це extjs з усіма витікаючими. Це як з кінзою, є люди, які без розуму від неї і люди, які її терпіти не можуть) Однак для загального ознайомлення я раджу подивитися і її.
Так само я б хотів детальніше зупинитися на Cordova . Фонгеп, це більше оточення. Там є платна підтримка, хмарні сервіси для генерації додатків ітд ітп. Cordova ж це платформа. Безпосередньо нативні модулі та JS обв'язка.
 
В даному випадку, ми не будемо використовувати нічого з вищезгаданого. По-перше, хотілося спробувати зробити все з нуля. Для себе я вирішив, подальші програми лише Cordova, ідеальне співвідношення гнучкості та швидкості. По-друге, у мене не вийшло швидко розібратися з оточенням фонгепа або Кордови. Не кажучи вже про Сенча. Всі вони пропонували робити програми з вшитими html, а ми зараз розглянемо ситуацію, коли код лежить на зовнішньому сервері.
Чому саме зовнішній сервер? Мені хотілося зробити додаток, який я б зміг оновлювати не тоді, коли його промодеріруют в appstore (зазвичай займає тиждень), а тоді, коли я знаходжу в ньому баги. Давайте по порядку.
 
 
1.1 TopCoat
У мережі багато фреймворків для створення мобільних UI, у тому числі з аля-нативними UI. Вже говорили про Сенча, так само варто звернути увагу на PhoneJS , JQ Mobile , Intel AF і багато інших. Гугл підкаже)
В даному випадку я вибрав topcoat. Я вже зустрічався з ним на іншому проекті і мені він дуже сподобався. По-перше, це не погані кастомниє UI, які відмінно виглядають і на андроиде і в Іосе. По-друге, топкоат дуже простий, звідси гнучкий. Після Bootstrap було трохи не звично, з причини відсутності сітки, напірмер, ітп. Але до цього швидко звикаєш)
Топкоат має гілку з іконками icomatic, що не рекомендую. Font Awesome кращий.
 
 
1.2 iScroll
Безсумнівно, свайпи і скролинг — візитна картка мобільних рішень. iScroll дає дуже близький до нативному скролинг. У мережі поширена iScroll4 не менше, аніж остання iScroll5. Відповідно, нова більш просунута і безбажная. На оффсайте багато прикладів, загалом все зрозуміло.
 
 
1.3 Zepto
Заміна jQuery, більш швидкі селектори і для мобільних додатків саме воно. У великих проектах ми юзаем jQuery за величезного числа полігонів, тут же нам потрібні тільки селектори)
 
 
1.4 Lodash
Просто допоміжна надбудова над JS. Ми часто юзаем backbonejs в проектах, lodash там дефакто обов'язковий. Ну і на практиці він ні скільки не повільніше нативного коду. Часом швидше.
 
 
1.5 Moment
Робота з датами / часом в JS. Без коментарів, без цієї бібліотеки головного болю було б в рази більше.
 
Я не став використовувати Backbone у проекті, хоча він тут дуже навіть проситься. Знову ж, економимо на сірниках. Бекбоном зручний і незамінний в більш-менш складних додатках, однак тут він ні до чого. Принаймні мені так здавалося)
Не можу не відзначити rad-js , це кастомниє backbone об'єкти, заточені під розробку мобільних додатків. Приємна штука, але досить мудрі. Так само дуже шкода, що RAD в чому використовується старий код. Наприклад, чіпляє старий iScroll і undercore, замість lodash. Знову ж, в даному проекті її використання здалося зайвим.
З оточенням розібралися. У нас немає MVC або подібного фреймворка, весь функціонал додатка кладеться в простій js об'єкт. Ми маємо готовий css фреймворк і необхідний набір JS бібліотек для швидкої розробки.
 
 image
 
 

2. Технології

Дивно, як за останні 2 роки зросли технології і браузери. 2 роки тому я вибирав між веб технологіями та нативним кодом. Під великий проект я вибрав нативний код. І на той момет це було вірним рішенням. Зараз, по хорошому, переписати все на веб і розвивати далі веб. Але вже шкода, тисячі рядків нативного obj-c, будь він не ладен. Про яву мовчу.
 
 
2.1 LocalStorage
Ну тут все зрозуміло, сховище. 5 метрів більш ніж, тим більше, що нам він потрібен під текст / js-об'єкти. Ті, хто працював хоч раз з мемкешом / редисом, буде щасливий. Якщо 5 метрів недостатньо, можна зробити обв'язку через нативний UserData, наприклад. У мережі багато рішень. Хтось пропонує кеш складати в файли, хтось через UserData, хтось рекомендує WebSQL, що, до речі, теж зручно. Нам вистачить localStorage.
 
 
2.2 AppCache
Мабуть, тільки завдяки цій технології ми і робимо додаток з зовнішнім кодом. Ще раз, наш додаток хоститься не в локальних html файлах, а на віддаленому сервері. Логічно, що якщо у вас в телефоні в даний момент немає інтернету, зовнішні сайти не відкриються. Тут то нас і врятує appCache. Про <a href="http://habrahabr.ru/search/?q=application+cache"> Application cache вийшло багато статей, хто не стикався з цією технологією, раджу ознайомитися. Сенс досить простий. За допомогою спеціального manifest файлу, ми вказуємо браузеру всі файли, що потрібно розмістити в кеш. Привабливість у тому, що розміщення в кеші файли будуть працювати, навіть якщо в пристрої немає інтернету. Логіка роботи аппкеша в додатку проста.
Клієнт перший раз запускає програму, вона підсмоктує контент в webview, webview кешує додаток. Далі при кожному запуску програми, перевіряється зміна manifest файлу. Якщо він змінився — кеш повністю перезаписується. Якщо змін не було, робота триває. Відповідно, якщо у користувача немає інтернету, просто чіпляється кеш без оновлень.
Таким чином ми можемо робити не просто нативні додатки на базі веб технологій, а й розміщувати безпосередньо код у себе на сервері. Для чого це потрібно я писав вище — моментальний багфикс і швидке публікування нових фішок.
 
 
2.3 CSS3
Ну і, звичайно, нерозумно ігнорувати всі можливості вебкіта. Взагалі, роблячи на вебі мобільний додаток варто завжди пам'ятати, що ми робимо його під один-два браузера, які супер сучасні і частіше підтримують нові технології, ніж ігнорують їх. Тобто буде хорошим тоном використовувати flexbox, вільно юзати анімацію і забути про pngfix)
У цьому додатку майже вся анімація зроблена на базі css3. По-перше, це простіше і швидше, ніж писати кілометри JS коду. По-друге, працює понад швидко завдяки апаратному прискоренню, яке можна включити до Вебком для анімації.
 
Мабуть, цього вистачить) Далі, треба підготувати проект в XCode.
Як уже говорив, все досить просто, нам потрібен тільки UIWebView на весь екран і нічого більше. До проекту я підключив JSONKit , т.к. він швидше нативного парсера + VK-SDK, Facebook-SDK для інтеграції з соц.сетях. Звичайно, можна було зробити інтеграцію на вебі, однак для привабливості я хотів зробити нативну підтримку vk + facebook. Не варто забувати про можливості ios sdk. Тобто веб технології це круто і потужно, але є завдання, які краще реалізовувати нативної. Інтеграція з соц.сетях — одна з таких завдань, як мені здається.
Все, що нам залишається — налагодити зв'язок між нашим html кодом та програмою. Тут теж все досить просто. WebView, що ми розмістили, потрібно сделегіровать в наш контролер.
Повідомлення з програми в веб все дуже просто, з будь-якого місця смикаємо:
 
[webView stringByEvaluatingJavaScriptFromString:@"alert(123);"]

Повідомлення з веба в додаток працюють таким чином. Проделегірованний WebView сніфает всі переходи, ми можемо робити потрібні нам посилання і перехоплювати їх у методі shouldStartLoadWithRequest:
 
<button ontouchend="window.location='vk:auth';"></button>

 
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSMutableURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    
    NSString *requestString = [[request URL] absoluteString];
    if ([requestString isEqualToString:@"vk:auth"]) {
        [VKSdk authorize:@[VK_PER_FRIENDS, VK_PER_WALL] revokeAccess:YES forceOAuth:YES inApp:YES display:VK_DISPLAY_IOS];
        return NO;
    }
}

Відповідно, якщо ми перехопили потрібний нам адресу, не забуваємо робити return NO, інакше веб версія спробує таки перейти на адресу vk: auth.
Ось загалом і все, у нас є веб морда, яка вміє жорстко кешована і працювати в офлайні і спілкуватися з нативним додатком. Що ще потрібно для щастя? )
 
 

Помилки і замітки на майбутнє

У наступній стаття я опишу, як використовувати Cordova із зовнішнім кодом. Безсумнівно, помилкою # 1 було рішення писати свою оболонку на xcode. Але знову ж, завданням було вивчити процес, щоб розуміти всю таємницю. Тому це не зовсім помилка. Я не рекомендую використовувати свої оболонки, хіба що для ознайомлення. У будь-яких інших проектах немає нічого краще, ніж Cordova. А все, що вона не вміє, можна реалізувати у вигляді плагінів для неї.
Так само ігнорування backbone було помилкою. Додаток вже починає розростатися, Дольни доробка була б набагато простіше і зрозуміліше, якби відразу був би використаний mvc фреймворк типу backbone.
Крім іншого, я жорстко лоханулся з налаштуванням NSURLRequest. Це об'єкт запиту для WebView, який, власне, і відкриває потрібний нам урл. Один з параметрів якого cachePolicy, куди потрібно передавати політику кешування. Скажімо, ви можете використовувати стандартну політику (приблизно відповідає браузерної), або, наприклад, вказати, що запит взагалі ніколи не повинен кешована або навпаки, братися тільки з кешу незалежно від заголовків. Прочитавши про прапор NSURLRequestReloadIgnoringLocalAndRemoteCacheData, вирішив використовувати саме його. Додаток працювало очевидно, його я і залишив. І тільки потім виявилося, що даний прапор не реалізований в ios sdk)))
 
Що стосується самої гри, на момент відправки бінарники на модерацію, в аппсторе не було жодної гри 2048. На момент публікації їх було більше 60. Спочатку я вмонтував у html код мобільний adsense. Однак перед самою публікацією я його прибрав і зробив додаток платним, тому що всі ці 60 + ігор були безкоштовні з рекламою всередині. Ніби як якийсь кастом) метод заміни змінної. Варто розуміти, що у мене немає завдання заробити на цій грі, проте підтримувати її безкоштовно сенсу теж немає. Основна відмінність від конкурентів — інтеграція не з GameCenter, а з соцмережами. Мені особисто цікавіше подивитися кого я обігнав серед своїх друзів під вконтакте, ніж у незаповненому профілі GameCenter. Ну і простіше стежити за «хакерами», тому база у себе на сервері. Якщо подібні штуки здадуться групі користувачів цікавіше і народ буде не проти витратити 33 рубля за гру, її можна розвивати і далі. Були ідеї будувати глобальні рейтинги, хто більше набирає. Наприклад, чоловіки чи жінки, дорослі або підлітки. МГУ або МДІМВ ітп. Всі ці дані збираються з соцмереж.
 
У кожному разі, це лише «проба пера». Найбільше геморою я заробив прорисовуючи іконки в різних розмірах. Всього 18 іконок різних розмірів + 13 стартових скроневої.
  
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.