Это может быть просто еще один пост на Medium о переписывании приложения на React Native, но я здесь, чтобы добавить очень честный инди-взгляд на успехи, неудачи и реалии использования RN в качестве единой платформы для разработки приложений для iOS и Android.

TL; DR - RN однажды почти дожил до цели «написать, развернуть повсюду», но не без некоторых реальных проблем, которые необходимо решить, особенно на платформе Android. Могу ли я использовать RN в моем следующем проекте… абсолютно… ну, может быть.

Сначала немного предыстории. Я написал оригинальный MobiLinc для iOS еще в 2009 году, а за ним последовала версия Android в 2010 году. MobiLinc - это приложение для домашней автоматизации для популярного контроллера ISY-994i от Universal Devices. С помощью MobiLinc пользователи управляют своими светильниками INSTEON и Z-Wave, термостатами, поливом, гаражными воротами и т. Д. То, что началось как хобби в 2009 году, я смог оставить свою постоянную работу в 2011 году, чтобы полностью посвятить себя разработке приложений MobiLinc. . Мне повезло, что 8 лет спустя я все еще независим, продолжая продвигать MobiLinc в своих интересах и в интересах своего сообщества.

MobiLinc - не первая и не последняя жертва неравномерного распределения доходов от приложений.

И мои личные интересы, и клиентская база склоняются к iOS. Когда мой разработчик Android (справедливо) не мог оправдать затраты времени на продолжение разработки порта MobiLinc для Android, когда доход не покрывал его расходы, моя версия Android отставала от версии для iOS. С точки зрения бизнеса, это всего лишь звонок по необработанным цифрам, но он не очень понравился моим пользователям Android или кроссплатформенным пользователям. MobiLinc - не первая и не последняя жертва неравномерного распределения доходов от приложений.

Любое приложение, которое существует уже 10 лет, нуждается в новом слое краски. Вопрос был в том, пересматриваете ли вы существующее приложение или начинаете заново? И что мне делать с моей отстающей версией Android?

Чуть больше года назад я решил полностью переработать MobiLinc и переписать его на React Native, упростить ценообразование до трехуровневой модели подписки на приложения и назвать ее MobiLinc X. Основная цель, которую я преследовал при переписывании, заключалась в том, чтобы поддерживать единую базу кода для iOS и Android. Предлагать приложение для моих пользователей Android имеет реальную ценность, но только в том случае, если я смогу повторно использовать большую часть кода, использованного для создания версии iOS. Отдельные базы кода просто не имели финансового смысла для моего рынка.

Мне слишком комфортно перезагружаться, удалять все пакеты npm и чистить все, когда все остальное терпит неудачу.

Большую часть 2018 года я готовил серверную часть к переписыванию, а также выполнял итерации дизайна для нового приложения MobiLinc, MobiLinc X. В октябре 2018 года я начал поддерживать базовый проект MobiLinc X. Будучи новичком в RN, я потратил пару недель экспериментов с платформой и игры с разными стеками RN.

Одна вещь, которую я быстро понял, - это RN в конце 2018 года, хотя он прошел долгий путь, он все еще похож на Дикий Запад. Инструмент работает и выходит из строя по непонятной причине. Мне слишком комфортно перезагружаться, удалять все пакеты npm и чистить все, когда все остальное терпит неудачу. Кроме того, вы можете на раннем этапе принимать дизайнерские решения, которые заставят вас слишком много писать и думать о коде котла.

Будучи чувствительным к тому, сколько символов мне в конечном итоге нужно было ввести как инди-разработчик, я выбрал хорошо спроектированные компоненты стека RN с открытым исходным кодом от WIX. А именно remx для управления состоянием и React Native Navigation V2.





Горячая перезагрузка - это темная магия, и я не могу ее использовать.

В октябре 2018 года я обнаружил, что базовые компоненты, которые я хотел использовать от WIX, похоже, лучше всего работают с RN 0.56, который был почти актуальным в то время. К ноябрю я закончил разработку MobiLinc X, используя iOS в качестве основной платформы разработки. Я обнаружил, что попытки поддерживать Android в рабочем состоянии и работать одновременно с iOS просто убивают мою продуктивность из-за этих случайных проблем, когда RN просто не развертывается и не отлаживается время от времени на iOS и Android. Любая из этих проблем может помешать мне разобраться во второй половине дня. Итак, это была iOS, и я заставлю Android работать, как только приложение будет «готово» для iOS.

Я скажу, что раз уж мои инструменты хорошо работали вместе, горячая перезагрузка - это темная магия, и я не могу ее использовать. Возвращаться к XCode или Android Studio для выполнения нативной работы кажется древним. Кто хочет подождать 10 минут сборки, чтобы протестировать новое изменение маржи на 2 пункта? Не этот парень. Возможность писать код UI RN и видеть его обновление в реальном времени на устройстве или симуляторе - это нереальный и замечательный опыт. Прирост производительности не похож ни на что другое, что я когда-либо испытывал за свою карьеру. В последний раз я чувствовал это, когда обнаружил обещания в JS и начал неукоснительно использовать их в разработке для iOS. До свидания, ад!

В любом случае, я отвлекся. Я закончил MobiLinc X в конце января 2019 года для iOS, и пришло время запустить сборку Android и протестировать / исправить для Android. Вот тогда все стало по-настоящему интересно.

AsyncStorage прямо сломан на Android.

Android обрабатывает макеты пользовательского интерфейса в основном одинаково, но я обнаружил странные случаи, когда flex работает по-другому, а SafeAreaView просто не работает и близко к тому, как он работает на iOS. Иногда мне нужно было обернуть списки в ScrollView на Android, чтобы макет отображался правильно. Но настоящим ударом был AsyncStorage.

AsyncStorage - это RN-модуль, который предоставляет вашему RN-коду базовый вариант локального хранения ключей / значений. AsyncStorage отлично работает в симуляторе iOS и на всех устройствах iOS. Он прямо сломан на Android 7+. Что происходит на устройствах Android 7+, вызовы в AsyncStorage просто не возвращаются. Обещания не разрешаются, и приложение RN зависает.



Копаясь в этом, команда RN знала об этой проблеме уже несколько лет, и она еще не исправлена. Уж точно не в 0.56. Я слышал, что теперь это поддерживается отдельно в 0.59, но на самом деле не с нетерпением жду проблем с обновлением RN. Я понимаю, что команда RN прислушивается к отзывам в этой области и вносит улучшения в процесс обновления и процесс обновления, начиная с версии 0.59, и это отличная новость, если вы сможете добраться до 0.59.

Если вы зашли так далеко, я слышу вас сейчас: «Просто выберите один из многих пакетов ключ / значение с открытым исходным кодом для Android». Что ж, вы были бы правы, за исключением того, что мой бэкэнд и MobiLinc X используют платформу Parse с открытым исходным кодом для облачной синхронизации всех данных в реальном времени. Parse использует AsyncStorage на мобильных устройствах и не может быть изменен. Я был на распутье. Если бы я не смог найти обходной путь для Android AsyncStorage, синтаксический анализ не работал бы, и я не смог бы развернуть его на Android.

После множества тупиков я закончил тем, что написал новый модуль Java, который соответствует API AsyncStorage, и включил этот модуль в RN для использования вместо Android RN AsyncStorage. Этого не было на моей доске видений… но мне очень повезло, что я нашел путь через это. Я понятия не имею, что делают другие, чтобы обойти эту проблему. Я чувствовал себя одиноким волком, пытающимся найти свой путь через это.

Хорошей новостью было то, что все усилия по установке и запуску версии Android, включая добавление подписок в приложении и незапланированное исправление AsyncStorage для Android, заняли около 14 дней. Оглядываясь назад на это время, я могу сказать, что это отличный уровень усилий, чтобы получить мой порт Android, идентичный iOS. Однако, когда я был в центре всего этого, и не было похоже, что у меня есть совместимое решение для хранения данных для Android, это было довольно мрачно.

Оба приложения были одобрены и поступили в App Store в конце февраля 2019 года.





Все должны просто перейти на RN? Это действительно зависит.

В целом переход на RN был хорошим опытом для этого инди-разработчика, но не обошелся без некоторой боли. Я не мог разработать или поддерживать две отдельные 100% нативные и отдельные базы кода для iOS / Android. Наличие RN для повторного использования, по существу, 98% моего кода / усилий было критичным для удовлетворения моих ресурсов разработки и времени.

Мог бы я снова использовать RN? В этом случае да. Для будущего проекта? Я бы определенно по умолчанию выбрал RN, чтобы узнать, поддержит ли RN потребности проекта. Все должны просто перейти на RN? Это действительно зависит. Я не уверен, что средним и крупным компаниям, которые могут позволить себе нативных разработчиков, следует использовать RN. Инструмент - настоящий кошмар для одного человека. Не говоря уже о попытках заставить целую команду заставить все свои инструменты работать и поддерживать разработку. Может быть, когда-нибудь это будет иметь смысл, но для этого нужно много работать с инструментами.

Я думаю, что если я сделаю еще одно приложение RN для себя или клиента, сохраняя все это в RN и JavaScript, как я сделал с MobiLinc X, будет более разумным шагом. Попытка выполнить кросс-RN / JS и нативную разработку в одном приложении будет довольно сложно управлять и поддерживать продуктивность для команды любого размера. Для этого могут быть веские причины, например, специальные ресурсы и таланты, но это не будет моим первым выбором.

А теперь перейдем к обновлению до 0.59 и хукам!