Говоря о разработке и внедрении гибридной технологии
предисловие
Говоря о разработке и внедрении гибридной технологии
Говоря о разработке и внедрении гибридной технологии
Говоря о конструкции и реализации технологии Hybrid, третья пуля — посадка
С ростом волны мобильных приложений различные приложения появляются бесконечным потоком, а быстрое расширение бизнеса повысило требования команды к эффективности разработки.В настоящее время кажется, что стоимость разработки приложения с использованием IOS и Andriod немного слишком высок, а H5 является недорогим, высокоэффективным, кросс-платформенным. Такие функции были немедленно использованы для формирования новой модели разработки: гибридного приложения.
В качестве гибридного режима разработки нижний уровень гибридного приложения опирается на контейнер (UIWebview), предоставляемый Native, а верхний уровень использует Html, Css и JS для развития бизнеса. Нижний уровень прозрачен, а верхний уровень диверсифицирован. Этот сценарий очень благоприятен. для внешнего вмешательства и очень подходит для быстрого бизнеса. Повторяйте, поэтому гибрид в огне.
Изначально я думал, что раз уж все знают об этой модели развития, то Гибрид не стоит обсуждать, но меня удивило, что многие до сих пор не знакомы с Гибридной моделью, которая очень распространена в городах второго эшелона. представить гибрид с другой стороны, надеясь помочь вам с правильным техническим выбором.
История гибрида
Изначально все приложения Ctrip были нативными, а на сайт H5 приходилась лишь малая часть его трафика.На тот момент в Native было 200 человек, в то время как на H5 в соевый соус играло всего около 5 человек, а команда wireless пришел позже с очень сильной исполнительной силой. Сильный лидер на стороне сервера, чтобы понять интерфейсную разработку, он фактически использовал jQuery Mobile для разработки первой версии программы. Хотя план был быстро отменен, команда H5 начала усердно работать и за короткий промежуток времени догнать Native.
Внезапно в один прекрасный день пришли коллеги из andriod и сказали нам, что в andriod есть метод максимального ограничения дерева, возможно, некоторые страницы нуждаются в том, чтобы мы встроили страницы H5, поэтому команды Native и H5 framework взяли на себя инициативу в создании первого гибридного проекта, а Ctrip появился впервые Набор кодов совместим с трехконтактным корпусом. Эффективность разработки велика, и команда попробовала сладость, поэтому последующие каналы в основном начали гибридную разработку, К тому времени, когда я ушел, весь механизм был очень зрелым, и во фронтенде были сотни человек.
воспроизведение сцены
У Wolf Factory есть три основных приложения для трафика: мобильный телефон Baidu, карты Baidu и приложение Nuomi.Когда они недавно подключились к Nuomi, они обнаружили, что они также продвигают продвижение, связанное с гибридной платформой, упаковывая статические ресурсы в Native, а Native предоставляет js для вызов нативных приложений.Возможности, с точки зрения производства и разработки, делают хорошую работу, но есть два недостатка:
① Размер приложения увеличится, когда все ресурсы будут упакованы в Naive.Даже при нарастающем механизме этого не избежатьРасширение APP, потому что в настоящее время подключено меньше каналов, канал 500K не чувствуется, как только платформа будет повернута, размер основного APP резко увеличится.
② Команда клиентской платформы Nuomi инкапсулирует возможности нативной стороны, но не предоставляет вспомогательную интерфейсную платформу, и это решение является неполным. У многих предприятий уже есть сайты H5, и им приходится разрабатывать отдельную программу, чтобы получить к ним доступ; и даже если это новый бизнес-доступ, они столкнутся с ограничением, заключающимся в том, что встроенные ресурсы должны быть статическими, а результирующие проекты не имеют SEO, если делать упор на SEO Его все равно нужно дорабатывать заново, что проблематично с инженерной точки зрения.
Тем не менее, с точки зрения доступности продукта и производства, общее направление гибридизации клейкого риса очень оптимистично, и некоторые достижения действительно были достигнуты.Многие каналы были подключены за короткий период времени.С продвижением может быть возможно следующее год. Сформируйте большую гибридную платформу. Но поскольку я также испытал структуру продвижения, когда я услышал, как они обманули меня и сказали, что производительность будет улучшена на 70%, что в основном то же самое, что и в Native, я не знаю, почему я рассмеялся...
Суммировать
Если вы все еще не знаете, почему вам следует использовать гибридную технологию после прочтения вышеприведенных историй, позвольте мне сделать здесь краткое изложение:
Hybrid开发效率高、跨平台、低层本 Hybrid从业务开发上讲,没有版本问题,有BUG能及时修复
У гибрида есть свои недостатки, опыт гибрида определенно не так хорош, как у натива, поэтому у него есть свои сценарии, но дляГибрид должен быть лучшим выбором для команд, которым нужно быстро пробовать и ошибаться, чтобы быстро занять рынок.После того, как команда выживет, им все еще нужно создавать нативные приложения с лучшим опытом..
Ну а так много бесполезного выше.Цель сегодняшнего дня - познакомить вас с дизайном Hybrid.Если вы внимательно прочитаете эту статью, она может быть вам полезна в следующих аспектах:
① Каковы соответствующие задачи Native и Front-end в Hybrid
② Как разработать интерактивный интерфейс Hybrid
③ Как спроектировать заголовок гибридного
④ Как спроектировать структуру каталогов Hybrid и как реализовать инкрементный механизм
⑤Стратегия кэширования ресурсов, проблема с белым экраном...
Статья представляет собой некоторый мой личный опыт разработки, надеюсь, она будет вам полезна, и я надеюсь, что выМного поддержки для обсуждения, указывая на то, что текстнедостаточный и представить некоторые из вашихпредложение.
Затем код, связанный с Android в тексте, предоставлен моим коллегой Мингюэ. Здесь я хотел бы поблагодарить моего одноклассника Мингюэ за их поддержку. Отсканируйте QR-код здесь, чтобы загрузить приложение для тестирования:
QR-код Android-приложения:
Кодовый адрес:
Нативное и внешнее разделение труда
Прежде чем проектировать гибридную архитектуру, необходимо разграничить границы между Native и интерфейсом. Прежде всего, Native обеспечивает хост-среду. Необходимо разумно использовать возможности, предоставляемые Native. Для достижения общего гибрида Платформенная архитектура, с точки зрения внешнего интерфейса, я думаю, что следующие основные вопросы дизайна необходимо учитывать.
Интерактивный дизайн
Первый вопрос, который следует учитывать при проектировании гибридной архитектуры, — это то, как спроектировать взаимодействие с внешним интерфейсом.Если этот дизайн не является хорошим, он окажет глубокое влияние на последующую разработку и обслуживание внешнего интерфейса, и это влияние часто бывает необратимым. поэтому необходимо, чтобы внешний интерфейс хорошо работал с Native, чтобы обеспечить общие интерфейсы, такие как:
① Компоненты NativeUI, компоненты заголовков, компоненты сообщений
② Интерфейс для чтения адресной книги, информации о системе и устройстве
③ H5 и Native переходят друг к другу, например, как перейти на Native-страницу в H5, как открыть новое веб-представление для H5 для анимации и перейти на другую страницу H5.
Механизм доступа к ресурсам
Native сначала необходимо рассмотреть, как получить доступ к ресурсам H5, чтобы можно было получить доступ как к внутренним ресурсам Native в виде файлов, так и к онлайн-ресурсам можно было получить доступ в виде URL-адреса; необходимо предоставить механизм постепенной замены для переднего плана. -конечные ресурсы, чтобы избавиться от проблемы итеративного выпуска приложений. Не позволяйте пользователям обновлять приложение. Это будет включать стратегию хранения статических ресурсов в приложении, разработку стратегии обновления, и, если это сложно, это также потребует поддержки на стороне сервера.
Дизайн информации об учетной записи
Система учетных записей важна, и ее нельзя избежать.Native должен разработать хороший механизм аутентификации безопасности, чтобы гарантировать, что эта часть бизнеса разработчиков достаточно прозрачна и открыта для информации об учетной записи.
Гибридная разработка и отладка
Дизайн функций - это не конец. Нативные и передние части должны обсуждать набор моделей, которые можно разработать и отладить. В противном случае многие работы по развитию бизнеса будет трудно продолжать. Многие статьи были приняты, и эта статья не будет повторить их.
Что касается дизайна связи, дизайна параллелизма, обработки исключений, мониторинга журналов имодуль безопасностиПоскольку это не та область, которой я занимаюсь, я не буду обращать на это внимание (на самом деле, я хочу уделить ей пристальное внимание), а то, что нужно сделать переднему концу, — это инкапсулировать различные возможности, предоставляемые Native. Общая архитектура выглядит следующим образом:
В реальном развитии бизнеса Native не только уделит внимание модулю входа в систему, но и инкапсулирует важные модули, такие как оплата, которая зависит от бизнеса.
Гибридный дизайн взаимодействия
Взаимодействие Hybrid — это не что иное, как Native, вызывающий JS-метод интерфейсной страницы, или интерфейсная страница, вызывающая интерфейс, предоставляемый Native через JS.Мостом между двумя взаимодействиями является Webview:
Само приложение может настроить схему URL-адреса и зарегистрировать настроенный URL-адрес в диспетчерском центре, например.
- ctrip://wireless Откройте приложение Ctrip
- weixin:// Открыть WeChat
Наша связь между JS и Native обычно заключается в создании таких URL-адресов, которые будут захвачены и обработаны Native. Позже есть другие способы вызова Native из внешнего интерфейса, но мы можем сделать базовую инкапсуляцию, чтобы сделать ее прозрачной, поэтому основное внимание уделяется о том, как спроектировать взаимодействие между интерфейсом и нативом.
JS to Native
Native будет предоставлять некоторые API в каждой версии, а соответствующая группа фреймворков инкапсулирует их во внешнем интерфейсе, чтобы выпустить бизнес-интерфейс. Например, внешний интерфейс клейкого риса выглядит так:
1 BNJS.http.get();//向业务服务器拿请求据【1.0】 1.3版本接口有扩展 2 BNJS.http.post();//向业务服务器提交数据【1.0】 3 BNJS.http.sign();//计算签名【1.0】 4 BNJS.http.getNA();//向NA服务器拿请求据【1.0】 1.3版本接口有扩展 5 BNJS.http.postNA();//向NA服务器提交数据【1.0】 6 BNJS.http.getCatgData();//从Native本地获取筛选数据【1.1】
1 BNJSReady(function(){ 2 BNJS.http.post({ 3 url : 'http://cp01-testing-tuan02.cp01.baidu.com:8087/naserver/user/feedback', 4 params : { 5 msg : '测试post', 6 contact : '18721687903' 7 }, 8 onSuccess : function(res){ 9 alert('发送post请求成功!'); 10 }, 11 onFail : function(res){ 12 alert('发送post请求失败!'); 13 } 14 }); 15 });
Платформа интерфейса определяет глобальную переменную BNJS как объект, с которым Native взаимодействует с интерфейсом.Пока представлена библиотека JS, предоставляемая Nuomi, и в контейнере Webview, инкапсулированном Nuomi, интерфейс будет иметь возможность звонить Native Я размышляю о дизайне Nuomi Это связано с тем, что сторонним командам удобно получать доступ и использовать его, а мобильный телефон Baidu имеет легкую структуру приложений, которая также идет по этому пути:
clouda.mbaas.account //释放了clouda全局变量
Это делается с учетом того, что,Натив сам по себе уже очень стабилен, добавлено мало новых функций, иначе вы столкнетесь с конфузом в случае прямого подключения, потому что веб-сайт всегда актуален, а нативные возможности, которые не предусмотрены, будут вызываться в некоторых младших версиях контейнеров и будет сообщено об ошибке.
Взаимодействие в стиле API
У нас нет возможности узнать, как сделать нижний уровень Shoubai и Nuomi, но мы обнаружили, что способ вызова интерфейса Native API очень похож на интерфейс, предоставляемый сервером, когда мы используем AJAX для вызова:
Здесь интерфейс аналогичной тонкой открытой платформы определяется так:
фансервис(Руководство по доступу для начинающих) | ||
---|---|---|
читать интерфейс | получить сообщение | Получать личные сообщения пользователей, подписываться, отписываться, @ и другие интерфейсы сообщений |
написать интерфейс | отправлять сообщения | Интерфейс ответа на личное сообщение пользователю |
Сгенерировать QR-код с параметрами | Создать интерфейс QR-кода с параметрами |
Все, что нам нужно сделать, это создать ajax-запрос одним из способов:
https://api.weibo.com/2/statuses/public_timeline.json
Поэтому, когда я разрабатывал гибридную модель взаимодействия, я проектировал ее в единицах интерфейсов.Например, общее взаимодействие для получения адресной книги выглядит следующим образом:
соглашение о формате
Первым шагом во взаимодействии является разработка формата данных, который делится на формат данных запроса и формат данных ответа.Модель запроса для ссылки на ajax, вероятно, выглядит следующим образом:
$.ajax(options) ⇒ XMLHttpRequest type (默认值:"GET") HTTP的请求方法(“GET”, “POST”, or other)。 url (默认值:当前url) 请求的url地址。 data (默认值:none) 请求中包含的数据,对于GET请求来说,这是包含查询字符串的url地址,如果是包含的是object的话,$.param会将其转化成string。
Итак, модель запроса, которую я согласовал с Native, выглядит следующим образом:
requestHybrid({ //创建一个新的webview对话框窗口 tagname: 'hybridapi', //请求参数,会被Native使用 param: {}, //Native处理成功后回调前端的方法 callback: function (data) { } });
Выполнение этого метода сформирует URL-адрес, например:
hybridschema://hybridapi?callback=hybrid_1446276509894¶m=%7B%22data1%22%3A1%2C%22data2%22%3A2%7D
Здесь следует упомянуть, что после установки приложения схема будет зарегистрирована на мобильном телефоне. Например, Taobao — это taobao://. В Native будет процесс для мониторинга всех запросов schema://, отправленных Webview, а затем распределите их обработчику hybridapi «контроллера». При обработке собственного контроллера потребуются параметры, предоставленные param (encoded). После обработки он будет нести данные для получения обратного вызова (hybrid_1446276509894) в Webview объект окна и вызовите его
Соглашение о формате для возврата данных:
{ data: {}, errno: 0, msg: "success" }
Настоящие данные находятся в объекте данных. Если errno не равно 0, вам нужно запросить msg. Вот пример, если код ошибки 1 означает, что для использования приложения необходимо обновить интерфейс:
{ data: {}, errno: 1, msg: "APP版本过低,请升级APP版本" }
Код
Вот простая реализация кода, реальный код изменится в приложении:
1 window.Hybrid = window.Hybrid || {}; 2 var bridgePostMsg = function (url) { 3 if ($.os.ios) { 4 window.location = url; 5 } else { 6 var ifr = $('<iframe style="display: none;" src="' + url + '"/>'); 7 $('body').append(ifr); 8 setTimeout(function () { 9 ifr.remove(); 10 }, 1000) 11 } 12 }; 13 var _getHybridUrl = function (params) { 14 var k, paramStr = '', url = 'scheme://'; 15 url += params.tagname + '?t=' + new Date().getTime(); //时间戳,防止url不起效 16 if (params.callback) { 17 url += '&callback=' + params.callback; 18 delete params.callback; 19 } 20 if (params.param) { 21 paramStr = typeof params.param == 'object' ? JSON.stringify(params.param) : params.param; 22 url += '¶m=' + encodeURIComponent(paramStr); 23 } 24 return url; 25 }; 26 var requestHybrid = function (params) { 27 //生成唯一执行函数,执行后销毁 28 var tt = (new Date().getTime()); 29 var t = 'hybrid_' + tt; 30 var tmpFn; 31 32 //处理有回调的情况 33 if (params.callback) { 34 tmpFn = params.callback; 35 params.callback = t; 36 window.Hybrid[t] = function (data) { 37 tmpFn(data); 38 delete window.Hybrid[t]; 39 } 40 } 41 bridgePostMsg(_getHybridUrl(params)); 42 }; 43 //获取版本信息,约定APP的navigator.userAgent版本包含版本信息:scheme/xx.xx.xx 44 var getHybridInfo = function () { 45 var platform_version = {}; 46 var na = navigator.userAgent; 47 var info = na.match(/scheme\/\d\.\d\.\d/); 48 49 if (info && info[0]) { 50 info = info[0].split('/'); 51 if (info && info.length == 2) { 52 platform_version.platform = info[0]; 53 platform_version.version = info[1]; 54 } 55 } 56 return platform_version; 57 };
Поскольку Native является нижним уровнем для H5, платформа и нижний уровень обычно не обращают внимания на бизнес-реализацию, поэтому существует несколько сценариев, в которых Native вызывает H5 в реальном бизнесе, поэтому здесь это не касается.
Общий интерактивный API
Хороший дизайн взаимодействия — первый шаг к успеху, и некоторые API обязательно будут использоваться в реальном развитии бизнеса.
Прыгать
Jump — это один из API, который должен использовать Hybrid.Для интерфейса есть следующие переходы:
① Перейти по странице, ничего общего с гибридом
② H5 переходит к собственному интерфейсу
③ Недавно открытый веб-просмотр H5 переходит на страницу H5, как правило, для переключения анимации страницы.
Если вы хотите использовать анимацию, есть два вида вперед и назад в зависимости от бизнеса, вперед и назад, поэтому соглашение выглядит следующим образом: во-первых, H5 переходит на определенную страницу Native.
1 //H5跳Native页面 2 //=>baidubus://forward?t=1446297487682¶m=%7B%22topage%22%3A%22home%22%2C%22type%22%3A%22h2n%22%2C%22data2%22%3A2%7D 3 requestHybrid({ 4 tagname: 'forward', 5 param: { 6 //要去到的页面 7 topage: 'home', 8 //跳转方式,H5跳Native 9 type: 'native', 10 //其它参数 11 data2: 2 12 } 13 });
Например, если вы хотите перейти на определенную страницу отеля Native на странице Ctrip H5, вы можете сделать это:
1 //=>schema://forward?t=1446297653344¶m=%7B%22topage%22%3A%22hotel%2Fdetail%20%20%22%2C%22type%22%3A%22h2n%22%2C%22id%22%3A20151031%7D 2 requestHybrid({ 3 tagname: 'forward', 4 param: { 5 //要去到的页面 6 topage: 'hotel/detail', 7 //跳转方式,H5跳Native 8 type: 'native', 9 //其它参数 10 id: 20151031 11 } 12 });
Например, способ перейти на страницу H5, открыв новый веб-просмотр в H5, может быть таким:
1 requestHybrid({ 2 tagname: 'forward', 3 param: { 4 //要去到的页面,首先找到hotel频道,然后定位到detail模块 5 topage: 'hotel/detail ', 6 //跳转方式,H5新开Webview跳转,最后装载H5页面 7 type: 'webview', 8 //其它参数 9 id: 20151031 10 } 11 });
Back совместим с forward. У нас даже есть параметр animattype для определения эффекта анимации при переключении страниц. В реальном использовании мы можем инкапсулировать глобальный метод и опустить детали тэга. В настоящее время он похож на интерфейс, выпущенный Нуоми.
Дизайн компонента заголовка
Сначала я действительно сопротивлялся использованию компонентов пользовательского интерфейса, предоставляемых Native, особенно заголовка, потому что после платформизации Native был очень осторожен с каждым изменением, и реакция была очень медленной, но по двум основным факторам я в основном отказался от сопротивления:
① Это делают другие основные контейнеры, такие как WeChat, мобильный Baidu, Ctrip.
② Если нет заголовка, после сбоя сети и появления белого экрана приложение перейдет в состояние приостановленной анимации, что неприемлемо, и общее решение слишком бизнес-решение.
PS: Когда Native приостанавливает Native, если нет ответа в течение 300 мс, загрузочный компонент необходимо экспортировать, чтобы избежать белого экрана.
Поскольку на сайте H5 уже есть компонент «Заголовок», стоящий на уровне внешнего интерфейса, необходимо убедиться, что бизнес-код непротиворечив, а все различия должны быть прозрачны на уровне структуры. Заголовок должен следовать:
① Компонент заголовка H5 использует тот же интерфейс уровня вызова, что и компонент заголовка, предоставляемый Native.
② Интерфейсный уровень инфраструктуры определяет, следует ли использовать компонент заголовка H5 или собственный компонент заголовка в соответствии со средой.
Вообще говоря, компонент заголовка должен выполнять следующие функции:
① Левая и правая стороны заголовка могут быть настроены и отображаться в виде текста или значков (здесь заголовок требуется для реализации основных значков, а значки также могут контролироваться бизнесом), а его обратный вызов необходимо контролировать.
② Заголовок заголовка может быть установлен на один заголовок или основной заголовок, тип субтитров, а также могут быть настроены левый и правый значок (значок расположен по центру)
③ Удовлетворить некоторым специальным конфигурациям, таким как заголовок класса тега
Поэтому с внешней стороны заголовок используется следующим образом (тэг не может повторяться):
1 //Native以及前端框架会对特殊tagname的标识做默认回调,如果未注册callback,或者点击回调callback无返回则执行默认方法 2 // back前端默认执行History.back,如果不可后退则回到指定URL,Native如果检测到不可后退则返回Naive大首页 3 // home前端默认返回指定URL,Native默认返回大首页 4 this.header.set({ 5 left: [ 6 { 7 //如果出现value字段,则默认不使用icon 8 tagname: 'back', 9 value: '回退', 10 //如果设置了lefticon或者righticon,则显示icon 11 //native会提供常用图标icon映射,如果找不到,便会去当前业务频道专用目录获取图标 12 lefticon: 'back', 13 callback: function () { } 14 } 15 ], 16 right: [ 17 { 18 //默认icon为tagname,这里为icon 19 tagname: 'search', 20 callback: function () { } 21 }, 22 //自定义图标 23 { 24 tagname: 'me', 25 //会去hotel频道存储静态header图标资源目录搜寻该图标,没有便使用默认图标 26 icon: 'hotel/me.png', 27 callback: function () { } 28 } 29 ], 30 title: 'title', 31 //显示主标题,子标题的场景 32 title: ['title', 'subtitle'], 33 34 //定制化title 35 title: { 36 value: 'title', 37 //标题右边图标 38 righticon: 'down', //也可以设置lefticon 39 //标题类型,默认为空,设置的话需要特殊处理 40 //type: 'tabs', 41 //点击标题时的回调,默认为空 42 callback: function () { } 43 } 44 });
Поскольку в левой части заголовка обычно есть только одна кнопка, ее объект может иметь следующую форму:
1 this.header.set({ 2 back: function () { }, 3 title: '' 4 }); 5 //语法糖=> 6 this.header.set({ 7 left: [{ 8 tagname: 'back', 9 callback: function(){} 10 }], 11 title: '', 12 });
Чтобы завершить реализацию Native-стороны, сюда добавятся два новых интерфейса, регистрирующие события с Native и отменяющие регистрацию событий:
1 var registerHybridCallback = function (ns, name, callback) { 2 if(!window.Hybrid[ns]) window.Hybrid[ns] = {}; 3 window.Hybrid[ns][name] = callback; 4 }; 5 6 var unRegisterHybridCallback = function (ns) { 7 if(!window.Hybrid[ns]) return; 8 delete window.Hybrid[ns]; 9 };
Реализация компонента Native Header:
1 define([], function () { 2 'use strict'; 3 4 return _.inherit({ 5 6 propertys: function () { 7 8 this.left = []; 9 this.right = []; 10 this.title = {}; 11 this.view = null; 12 13 this.hybridEventFlag = 'Header_Event'; 14 15 }, 16 17 //全部更新 18 set: function (opts) { 19 if (!opts) return; 20 21 var left = []; 22 var right = []; 23 var title = {}; 24 var tmp = {}; 25 26 //语法糖适配 27 if (opts.back) { 28 tmp = { tagname: 'back' }; 29 if (typeof opts.back == 'string') tmp.value = opts.back; 30 else if (typeof opts.back == 'function') tmp.callback = opts.back; 31 else if (typeof opts.back == 'object') _.extend(tmp, opts.back); 32 left.push(tmp); 33 } else { 34 if (opts.left) left = opts.left; 35 } 36 37 //右边按钮必须保持数据一致性 38 if (typeof opts.right == 'object' && opts.right.length) right = opts.right 39 40 if (typeof opts.title == 'string') { 41 title.title = opts.title; 42 } else if (_.isArray(opts.title) && opts.title.length > 1) { 43 title.title = opts.title[0]; 44 title.subtitle = opts.title[1]; 45 } else if (typeof opts.title == 'object') { 46 _.extend(title, opts.title); 47 } 48 49 this.left = left; 50 this.right = right; 51 this.title = title; 52 this.view = opts.view; 53 54 this.registerEvents(); 55 56 _.requestHybrid({ 57 tagname: 'updateheader', 58 param: { 59 left: this.left, 60 right: this.right, 61 title: this.title 62 } 63 }); 64 65 }, 66 67 //注册事件,将事件存于本地 68 registerEvents: function () { 69 _.unRegisterHybridCallback(this.hybridEventFlag); 70 this._addEvent(this.left); 71 this._addEvent(this.right); 72 this._addEvent(this.title); 73 }, 74 75 _addEvent: function (data) { 76 if (!_.isArray(data)) data = [data]; 77 var i, len, tmp, fn, tagname; 78 var t = 'header_' + (new Date().getTime()); 79 80 for (i = 0, len = data.length; i < len; i++) { 81 tmp = data[i]; 82 tagname = tmp.tagname || ''; 83 if (tmp.callback) { 84 fn = $.proxy(tmp.callback, this.view); 85 tmp.callback = t; 86 _.registerHeaderCallback(this.hybridEventFlag, t + '_' + tagname, fn); 87 } 88 } 89 }, 90 91 //显示header 92 show: function () { 93 _.requestHybrid({ 94 tagname: 'showheader' 95 }); 96 }, 97 98 //隐藏header 99 hide: function () { 100 _.requestHybrid({ 101 tagname: 'hideheader', 102 param: { 103 animate: true 104 } 105 }); 106 }, 107 108 //只更新title,不重置事件,不对header其它地方造成变化,仅仅最简单的header能如此操作 109 update: function (title) { 110 _.requestHybrid({ 111 tagname: 'updateheadertitle', 112 param: { 113 title: 'aaaaa' 114 } 115 }); 116 }, 117 118 initialize: function () { 119 this.propertys(); 120 } 121 }); 122 123 });
класс запроса
Хотя запросы get могут использовать jsonp для обхода междоменных проблем, почтовые запросы являются настоящим камнем преткновения. В целях безопасности сервер установит cors только для нескольких доменных имен. Встроенные статические ресурсы Hybrid считываются файлом. В этом сценарии он использовать cors непросто, поэтому каждый запрос необходимо отправлять через слой прокси в Native.
Этот сценарий использования согласуется с компонентом Header. Интерфейсный уровень инфраструктуры должен быть прозрачен для бизнеса. Фактически, бизнесу не нужно заботиться о том, отправляется ли запрос браузером или Native:
1 HybridGet = function (url, param, callback) { 2 }; 3 HybridPost = function (url, param, callback) { 4 };
В реальном бизнес-сценарии он будет инкапсулирован в модуль запроса данных, адаптирован на нижнем уровне, с использованием запроса ajax под сайтом H5 и с использованием прокси-сервера для отправки, когда натив встроен.Соглашение с нативом:
1 requestHybrid({ 2 tagname: 'ajax', 3 param: { 4 url: 'hotel/detail', 5 param: {}, 6 //默认为get 7 type: 'post' 8 }, 9 //响应后的回调 10 callback: function (data) { } 11 });
Общие компоненты NativeUI
Наконец, Native предоставит несколько часто используемых пользовательских интерфейсов на уровне Native, таких как загрузка уровня загрузки, например окно всплывающего сообщения:
1 var HybridUI = {}; 2 HybridUI.showLoading(); 3 //=> 4 requestHybrid({ 5 tagname: 'showLoading' 6 }); 7 8 HybridUI.showToast({ 9 title: '111', 10 //几秒后自动关闭提示框,-1需要点击才会关闭 11 hidesec: 3, 12 //弹出层关闭时的回调 13 callback: function () { } 14 }); 15 //=> 16 requestHybrid({ 17 tagname: 'showToast', 18 param: { 19 title: '111', 20 hidesec: 3, 21 callback: function () { } 22 } 23 });
Нативный пользовательский интерфейс нелегко открыть для пользовательского интерфейса переднего плана, поэтому в реальном процессе разработки бизнеса обычно используются только несколько критических нативных пользовательских интерфейсов.
Дизайн системы учета
В соответствии с приведенным выше дизайном мы согласны с тем, что в гибридной системе есть два способа отправки запросов:
① Если это веб-просмотр для доступа к онлайн-сайту, напрямую используйте традиционный ajax для отправки
② Если собственный ресурс читается в виде файла, запрос отправляется собственным агентом.
Поскольку для статических html-ресурсов нет проблем с аутентификацией, реальную проверку авторизации необходимо получить, запросив ответ API сервера и передав код ошибки.Это большая разница между динамическим языком и статическим языком в качестве страницы входа.
Доступ к веб-странице, независимо от того, зарегистрирована ли учетная запись или нет, определяется наличием у нее файла cookie с секретным ключом (действительность секретного ключа в настоящее время не может быть гарантирована), поскольку Native не обращает внимания на бизнес-реализация, и каждый load может быть успешным входом в систему.Результат возвращается, поэтому вам нужно обратить внимание на изменение файла cookie секретного ключа после каждой загрузки, чтобы добиться согласованности данных состояния входа.
Если вы получаете доступ к встроенным ресурсам в виде файла, поскольку контроллер запросов API является Native, работа по аутентификации полностью выполняется Native.Если доступ к интерфейсу не выполнен, появится окно входа на собственном уровне, чтобы помочь войти , Каждый раз, когда вы получаете доступ к веб-просмотру, учетная запись будет Информация загружается в веб-просмотр. Здесь есть противоречие. Время исходного заполнения в веб-просмотре связано с тем, что может случиться так, что веб-страница вышла из системы, поэтому логика тут такая:
① завершение загрузки веб-просмотра
② Native определяет, содержит ли веб-просмотр информацию о файлах cookie учетной записи.
③ Если он не включен, файл cookie будет имплантирован. Если он включен, будет определено, совпадает ли он с информацией об учетной записи Native. Если он отличается, он заменит себя.
④ Если обнаружено, что вы перешли на страницу отмены учетной записи, вам необходимо очистить информацию о своей учетной записи.
Если логин не унифицирован, появится описанная выше сложная логика, поэтому на самом деле мы закроем интерфейс входа.
Упрощенный интерфейс аккаунта
Уровень платформы считает, что вышеуказанные операции слишком сложны, поэтому обязательно, чтобы для входа и выхода в контейнере Hybrid можно было использовать только собственный интерфейс, а интерфейсная структура адаптирована внизу, чтобы обеспечить прозрачность бизнес верхнего уровня, который будет намного проще:
① Используйте собственный прокси-сервер в качестве интерфейса запроса. Если вы не войдете в систему, собственный слой напрямую вызовет окно входа в систему.
② Метод прямого подключения использует интерфейс запроса ajax.Если нет логина, окно входа будет вызвано внизу (требуется поддержка фреймворка)
Простая реализация интерфейса входа и выхода:
1 /* 2 无论成功与否皆会关闭登录框 3 参数包括: 4 success 登录成功的回调 5 error 登录失败的回调 6 url 如果没有设置success,或者success执行后没有返回true,则默认跳往此url 7 */ 8 HybridUI.Login = function (opts) { 9 }; 10 //=> 11 requestHybrid({ 12 tagname: 'login', 13 param: { 14 success: function () { }, 15 error: function () { }, 16 url: '...' 17 } 18 }); 19 //与登录接口一致,参数一致 20 HybridUI.logout = function () { 21 };
Получение информации об учетной записи
При реальном развитии бизнеса возникает множество потребностей для определения того, вошел ли пользователь в систему и для получения основной информации о пользователе, поэтому необходимо обеспечить унификацию гибридной модели разработки и модели разработки H5, иначе много ненужного суждения должны быть сделаны в бизнес-коде.Внешняя структура будет инкапсулировать пользовательский модуль, а основные интерфейсы включают:
1 var User = {}; 2 User.isLogin = function () { }; 3 User.getInfo = function () { };
Базовая реализация этого кода делится на интерфейсную реализацию, нативную реализацию, в первую очередь, интерфейсный подход:
Когда передняя страница загружается, будет сделан асинхронный запрос для запроса данных, связанных с пользователем.Если он вошел в систему, данные могут быть получены и сохранены в локальном хранилище.ЗдесьНе должен получать доступ к конфиденциальной информации
Если интерфейс использует localstorage, необходимо рассмотреть возможность использования переменных памяти для замены реализации localstorage в крайних случаях, иначе он будет непригоден для использования, а последующий доступ будет использовать данные в localstorage как основу для суждения, В следующих случаях необходимо очистить данные учетной записи localstorage:
① Выход из системы
② Интерфейс доступа подсказывает, что вам необходимо войти в систему.
③ Вызов интерфейса входа
Этот режим в основном используется в одностраничных приложениях. Неодностраничные приложения обычно сначала очищают информацию об учетной записи, а затем извлекают ее асинхронно при каждом обновлении страницы. Однако, если текущей странице необходимо немедленно оценить данные для входа пользователя, это ненадежно; в контейнере Hybrid посередине, поскольку Native сам сохраняет информацию о пользователе, инкапсулированный интерфейс можно получить напрямую из Native, что более надежно.
Ресурсы для гибрида
Структура каталогов
Поскольку гибридная технология хранит статические ресурсы в Native, требуется проектирование каталогов.После предыдущего опыта структура каталогов обычно делится на два уровня каталогов:
Если у нас есть два канала отель и рейс, то структура каталога будет такой:
1 webapp //根目录 2 ├─flight 3 ├─hotel //酒店频道 4 │ │ index.html //业务入口html资源,如果不是单页应用会有多个入口 5 │ │ main.js //业务所有js资源打包 6 │ │ 7 │ └─static //静态样式资源 8 │ ├─css 9 │ ├─hybrid //存储业务定制化类Native Header图标 10 │ └─images 11 ├─libs 12 │ libs.js //框架所有js资源打包 13 │ 14 └─static 15 ├─css 16 └─images
Правило параметра toppage в первоначально разработанном прямом переходе: канал/конкретная страница => канал/страница, а остальные ресурсы будут выведены через входной файл index.html.
Инкрементный механизм
Истинные инкрементальные механизмы должны соответствовать серверной стороне, я здесь только краткое описание, исходная конечная версия будет поддерживать таблицу сопоставления:
Эта таблица сопоставления создается сервером каждый раз, когда выпускается большая версия приложения.Если каналу отеля необходимо выполнить дополнительный онлайн-релиз, он упакует файловый каталог, соответствующий онлайн-каталогу, и опубликует его на платформе выпуска, он сформирует файл в базе данных.
channel | ver | md5 |
flight | 1.0.0 | 1245355335 |
hotel | 1.0.1 | 455ettdggd |
Когда приложение запускается, приложение считывает информацию о версии.Обнаружено, что номер локальной версии отеля меньше, чем у онлайн-версии, и оно загружает zip-файл, соответствующий md5, затем распаковывает его и заменяет весь файл отеля.На этом инкремент заканчивается,т.к. все файлы версии не будут повторяться.При откате АРР можно вернуться к любой версии,которую хотите,а так же можно делать исправления ошибок к любой версии.
Эпилог
Код на гитхабе будет пополняться.Сейчас интерфейс и так не очень красивый.Пожалуйста, потерпите меня.Вот некоторые рендеры:
Гибридное решение — это артефакт для быстрой итерации проектов и быстрого завоевания рынка.Я надеюсь, что эта статья может помочь друзьям, которые готовы связаться с Hybrid technology, и еще раз благодарю Mingyue за сотрудничество.
- 1 Говоря о дизайне гибридной технологии...
- 2 предисловие
- 3 Нативное и внешнее разделение труда
- 4 Гибридный дизайн взаимодействия
- 4.1 JS to Native
- 4.2 Взаимодействие в стиле API
- 4.3 соглашение о формате
- 4.4 Общий интерактивный API
- 4.4.1 Прыгать
- 4.4.2 Дизайн компонента заголовка
- 4.4.3 класс запроса
- 4.4.4 Общие компоненты NativeUI
- 5 Дизайн системы учета
- 6 Ресурсы для гибрида
- 6.0.5 Структура каталогов
- 6.0.6 Инкрементный механизм
- 7 Эпилог