Спасибо за замечание! Оно справедливое, об этом нельзя забывать. Это одна из причин, почему мы решили выработать для себя стратегию по использованию WebView.
Мы это отметили как плюс, так как для большинства изолированных фичей поддержка со стороны натива не должна оказаться дорогой. Но согласен, что бывают и обратные случаи, если, например, говорить про фичу, которая попадает под один или особенно несколько пунктов раздела "Когда НЕ стоит использовать WebView", то на разработка нативной части может потребоваться значительное время, и выигрыша в скорости уже не будет.
Добавлю, что наши продакты самостоятельно не принимают решения реализовывать фичу с помощью WebView или нет. Все же выбор технологии исходя из требований - это больше ответственность разработки. Продакт может предложить такую идею, но решение будет приниматься совместно с лидом команды разработки. Истина рождается в диалоге )
Однако там не plain-текст, там ссылки с переходами. Гиперссылки внутри TextView вполне реализуемы, но они бы все равно привели к открытию WebView, мы решили не усложнять.
Да, мы решали вопрос аутентификации в рамках реализации механизма проброса данных. Расскажу поподробнее про принцип работы используемых нами механизмов.
Проброс данных из WebView в нативный код у нас происходит с помощью отправки JavaScript сообщений (событий). Нативный код подписывается на вызов определенных, заранее известных сообщений. Соответственно, у сообщения есть name и body. О формате body мы договорились всеми платформами, чтобы можно было передавать параметры, остановились на формате json.
Пробросить же данные из нативного кода внутрь WebView можно с помощью cookie при создании экземпляра, и мы пользуемся этим механизмом, чтобы передать параметры для отдельных экранов.
Аутентификация же у нас для безопасности проходит в несколько этапов. Позитивный сценарий выглядит следующим образом:
При переходе на экран WebView из нативного кода мы отправляем на наш сервер запрос на получение токена авторизации для WebView, передав в параметрах ссылку, которую хотим открыть. Запрос с нативной стороны, поэтому токен аутентификации передается в заголовке. Точно также, как у нас происходит с любым другим запросом.
На стороне бэкенда создается быстро протухающий токен для WebView, который подписывается данными о пользователе и ссылкой, которую мы хотим для него открыть. Эти данные в ответе не отправляются, передается только токен.
Получив ответ от бэкенда, мобильное приложение открывает в созданном экземпляре WebView определенный URL, в параметрах которого добавляем токен, переданный в этом ответе.
При загрузке этого URL бэкенд проверяет валидность токена и получает через него пользовательские данные.
Далее на бэкенде генерируется cookie на этого пользователя и происходит ответ 302 редиректом уже на ту ссылку, которую мы хотели открыть изначально, проставив нужные cookies. Финиш! )
Насчет кроссплатформенных технологий: недавно мы попробовали Flutter. Он неплохо себя показал, и теперь используется в нашем проекте наряду с нативом и WebView. Его UI действительно намного ближе к нативу, чем у WebView. Однако для нас они не взаимозаменяемы, так как у WebView перед Flutter’ом есть то же преимущество, что и перед нативом: 2. Синхронный Update на пользователей. Отказаться от нативной разработки мы тоже не планируем, но масштабируем Flutter в нашем проекте под определенные фичи.
Вы задали очень хороший вопрос. Его подробности тянут на отдельную статью, подобную этой. Надеюсь, в ближайшем будущем мы с вами поделимся и этим опытом, там много интересного )
Что касается «Не работает офлайн режим». Разумеется, технически WebView может открыть страницу как на удаленном сайте, так и если она находится локально. Я вкладывал в этот пункт несколько иной смысл. В контексте нашего клиент-серверного приложения и запросов бизнеса требовался гибкий инструмент, способный к максимально быстрым изменениям и экспериментам, не упираясь в релизный цикл мобильных приложений. Если же мы зашьем Web-страницу в исходники, то не получим одного из самых главных для нас преимуществ от WebView - синхронный Update на пользователей. Если мы зашивать не будем, то в любом случае возвращаемся к вопросу загрузки необходимых данных. Если закэшировать скаченную страницу и работать только с закэшированной версией, то можем попасть в ситуацию, когда нужные нам изменения не доедут до клиента.
Спасибо за это замечание, я немного поменял формулировку в статье, чтобы стало прозрачнее.
Теперь о проблемах с локальным хранением данных. Да, у WebView есть свое хранилище, как я и писал, однако его не стоит рассматриваться как надежное - это зависит от поведения операционной системы. Чтобы не быть голословным, рассмотрим iOS. У пользователя iOS нет возможности самостоятельно очистить данные приложения, если только эта функция не будет специально реализована самим разработчиком данного приложения. Пользователь может только удалить приложение целиком или сгрузить (близкая операция, но с сохранением данных). В iOS все типы хранилищ WebView располагаются в папке Library/WebKit внутри директории приложения, и эти данные могут быть автоматически очищены операционной системой, если пользователь не будет взаимодействовать с сайтом на протяжении 7 дней. Это справедливо как для браузера, так и для WebView внутри нативного приложения. Подробнее можно почитать на официальном сайте WebKit: https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/. Это поведение не 15-летней давности, это iOS 13, которая вышла всего 3 года назад, и это актуально сейчас для iOS 16. С нативным хранилищем Library/Application Support такого не произойдет.
Это ограничение. Для многих фичей такое поведение хранилище вполне подходит, но для части это может оказаться критичным, так что не стоит игнорировать. Если у хотя бы одной платформы iOS или Android появляются критичные для фичи ограничения, мы не станем реализовывать фичу с помощью WebView, потому что в этом случае для нас уже не будет выигрыша от WebView.
Я намеренно не указывал такие технические детали в статье, постарался коротко передать суть. Если бы в ней были детали про iOS и про Android, то она получилась бы слишком длинной, и никто бы не дочитал до конца )
В данной статье мы рассказываем про персонально нашу стратегию, на которую повлияли много факторов. Мы понимаем, что подошло нам, не обязательно подойдет всем )
В данный момент мы не используем паттерн Робот. Мы не выносим действия в отдельные объекты, по сути у нас эту функцию выполняют extension'ы PageObject'ов.
Паттерн хороший, но в данной статье мы хотели поделиться частью того, что используем сами. Статья и так получилась довольно длинная )
Спасибо за замечание! Оно справедливое, об этом нельзя забывать. Это одна из причин, почему мы решили выработать для себя стратегию по использованию WebView.
Мы это отметили как плюс, так как для большинства изолированных фичей поддержка со стороны натива не должна оказаться дорогой. Но согласен, что бывают и обратные случаи, если, например, говорить про фичу, которая попадает под один или особенно несколько пунктов раздела "Когда НЕ стоит использовать WebView", то на разработка нативной части может потребоваться значительное время, и выигрыша в скорости уже не будет.
Добавлю, что наши продакты самостоятельно не принимают решения реализовывать фичу с помощью WebView или нет. Все же выбор технологии исходя из требований - это больше ответственность разработки. Продакт может предложить такую идею, но решение будет приниматься совместно с лидом команды разработки. Истина рождается в диалоге )
На скриншоте да, выглядит как TextView )
Однако там не plain-текст, там ссылки с переходами. Гиперссылки внутри TextView вполне реализуемы, но они бы все равно привели к открытию WebView, мы решили не усложнять.
Добрый день!
Да, мы решали вопрос аутентификации в рамках реализации механизма проброса данных. Расскажу поподробнее про принцип работы используемых нами механизмов.
Проброс данных из WebView в нативный код у нас происходит с помощью отправки JavaScript сообщений (событий). Нативный код подписывается на вызов определенных, заранее известных сообщений. Соответственно, у сообщения есть name и body. О формате body мы договорились всеми платформами, чтобы можно было передавать параметры, остановились на формате json.
Пробросить же данные из нативного кода внутрь WebView можно с помощью cookie при создании экземпляра, и мы пользуемся этим механизмом, чтобы передать параметры для отдельных экранов.
Аутентификация же у нас для безопасности проходит в несколько этапов. Позитивный сценарий выглядит следующим образом:
При переходе на экран WebView из нативного кода мы отправляем на наш сервер запрос на получение токена авторизации для WebView, передав в параметрах ссылку, которую хотим открыть. Запрос с нативной стороны, поэтому токен аутентификации передается в заголовке. Точно также, как у нас происходит с любым другим запросом.
На стороне бэкенда создается быстро протухающий токен для WebView, который подписывается данными о пользователе и ссылкой, которую мы хотим для него открыть. Эти данные в ответе не отправляются, передается только токен.
Получив ответ от бэкенда, мобильное приложение открывает в созданном экземпляре WebView определенный URL, в параметрах которого добавляем токен, переданный в этом ответе.
При загрузке этого URL бэкенд проверяет валидность токена и получает через него пользовательские данные.
Далее на бэкенде генерируется cookie на этого пользователя и происходит ответ 302 редиректом уже на ту ссылку, которую мы хотели открыть изначально, проставив нужные cookies. Финиш! )
Спасибо за комментарий!
Насчет кроссплатформенных технологий: недавно мы попробовали Flutter. Он неплохо себя показал, и теперь используется в нашем проекте наряду с нативом и WebView. Его UI действительно намного ближе к нативу, чем у WebView. Однако для нас они не взаимозаменяемы, так как у WebView перед Flutter’ом есть то же преимущество, что и перед нативом: 2. Синхронный Update на пользователей. Отказаться от нативной разработки мы тоже не планируем, но масштабируем Flutter в нашем проекте под определенные фичи.
Вы задали очень хороший вопрос. Его подробности тянут на отдельную статью, подобную этой. Надеюсь, в ближайшем будущем мы с вами поделимся и этим опытом, там много интересного )
Позвольте я объясню по порядку.
Что касается «Не работает офлайн режим». Разумеется, технически WebView может открыть страницу как на удаленном сайте, так и если она находится локально. Я вкладывал в этот пункт несколько иной смысл. В контексте нашего клиент-серверного приложения и запросов бизнеса требовался гибкий инструмент, способный к максимально быстрым изменениям и экспериментам, не упираясь в релизный цикл мобильных приложений. Если же мы зашьем Web-страницу в исходники, то не получим одного из самых главных для нас преимуществ от WebView - синхронный Update на пользователей. Если мы зашивать не будем, то в любом случае возвращаемся к вопросу загрузки необходимых данных. Если закэшировать скаченную страницу и работать только с закэшированной версией, то можем попасть в ситуацию, когда нужные нам изменения не доедут до клиента.
Спасибо за это замечание, я немного поменял формулировку в статье, чтобы стало прозрачнее.
Теперь о проблемах с локальным хранением данных. Да, у WebView есть свое хранилище, как я и писал, однако его не стоит рассматриваться как надежное - это зависит от поведения операционной системы. Чтобы не быть голословным, рассмотрим iOS. У пользователя iOS нет возможности самостоятельно очистить данные приложения, если только эта функция не будет специально реализована самим разработчиком данного приложения. Пользователь может только удалить приложение целиком или сгрузить (близкая операция, но с сохранением данных). В iOS все типы хранилищ WebView располагаются в папке Library/WebKit внутри директории приложения, и эти данные могут быть автоматически очищены операционной системой, если пользователь не будет взаимодействовать с сайтом на протяжении 7 дней. Это справедливо как для браузера, так и для WebView внутри нативного приложения. Подробнее можно почитать на официальном сайте WebKit: https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/. Это поведение не 15-летней давности, это iOS 13, которая вышла всего 3 года назад, и это актуально сейчас для iOS 16. С нативным хранилищем Library/Application Support такого не произойдет.
Это ограничение. Для многих фичей такое поведение хранилище вполне подходит, но для части это может оказаться критичным, так что не стоит игнорировать. Если у хотя бы одной платформы iOS или Android появляются критичные для фичи ограничения, мы не станем реализовывать фичу с помощью WebView, потому что в этом случае для нас уже не будет выигрыша от WebView.
Я намеренно не указывал такие технические детали в статье, постарался коротко передать суть. Если бы в ней были детали про iOS и про Android, то она получилась бы слишком длинной, и никто бы не дочитал до конца )
В данной статье мы рассказываем про персонально нашу стратегию, на которую повлияли много факторов. Мы понимаем, что подошло нам, не обязательно подойдет всем )
Здравствуйте!
Большое вам спасибо за комментарий и за то, что указали на ошибку! Вы были абсолютно правы, я ее исправил.
Очень рад, что статья вам понравилась )
Спасибо за комментарий!
В данный момент мы не используем паттерн Робот. Мы не выносим действия в отдельные объекты, по сути у нас эту функцию выполняют extension'ы PageObject'ов.
Паттерн хороший, но в данной статье мы хотели поделиться частью того, что используем сами. Статья и так получилась довольно длинная )