Pull to refresh
75.24
NFCKEY
умные замки с новым, инновационным подходом

Наш опыт Android- и iOS-разработки в проекте

Level of difficultyEasy
Reading time14 min
Views1.8K

Посмотрим на текущую ситуацию с разработчиками Android- и iOS‑приложений. Обсудим варианты разработки мобильных приложений. Разберемся, как мы в стартапе NFCKEY работаем в этом направлении. Затронем особенности, которые возникают в связи с условиями стартапа и IoT‑тематикой проекта. Ответим на вопрос: «Сложно ли переучиться и пойти в сферу мобильной разработки?».

Статья специально написана простым языком, где многие вещи объясняются на пальцах, чтобы материал был понятен для всех и давал представление о сфере в целом, а не только о тонкостях разработки.

Главная задача статьи — объяснить для начинающих ключевые особенности мобильной разработки, а для людей, имеющих опыт — поделиться сложностями перехода в сферу мобильных устройств и возможными направлениями в ней. На примере функций нашего приложения продемонстрируем, какие задачи решаются в мобильной разработке.

Кто мы и что мы

Мы уже не первый раз пишем статьи, так что подробно про наш проект и команду можете прочитать здесь. Если вкратце — мы создаем умные замки с новым подходом.

В этой же статье разберем наш подход к мобильной разработке на Android и iOS, а в следующей статье, которая выйдет на следующей неделе, — серверный API. Поделимся особенностями, которые возникают в связи с условиями стартапа и тематикой проекта, а также поговорим о принятых нами решениях при разработке.

Часть материала будет написана самими разработчиками, чтобы более точно передать сложности и пути их решения. Все это позволит окунуться в процесс более глубоко.

Давайте с ними познакомимся:

Сергей — iOS‑разработчик. Веселый, со своими особенностями работы, но со строгим подходом к коду. Он, кстати, до нашего проекта имел совсем небольшой опыт работы с iOS, поэтому его видение и опыт будет крайне ценен для новичков, которые думают пойти в эту сферу.

Никита — Android‑разработчик. Пессимист, который практически никогда не пропускает дедлайны. Он, как и Сережа, тоже не имел огромного опыта за плечами в мобильной разработке, но освоился и выполняет даже крайне сложные задачи на ура.

У обоих ребят до этого был опыт разработки около двух лет на C‑подобных языках.

Зачем нужно приложение

Мобильное приложение — это ваш ключ к клиенту. Именно оно может стать одним из ваших основных преимуществ в сравнении с аналогами. Мы, например, ставим большой акцент на UX/UI и уже реализовали большое количество функций, способных раскрыть весь потенциал умного замка. О том, какой конкретно функционал мы разрабатываем и зачем он нужен, мы пишем в нашем ТГ‑канале по ходу его тестирования и доработки, а также зачастую советуемся с нашими читателями.

Кстати, если вы хотите привнести в проект свое видение, мы создали небольшой опрос, от результатов которого будем отталкиваться при разработке и в продвижении.

Разработать мобильное приложение — непростая задача, к которой можно подойти по‑разному:

1. Кроссплатформенная разработка. Flutter и React Native для бизнеса является самым простым способом разработать приложение сразу на обе платформы. В РФ особенно сейчас популярен React Native для мобильной разработки. Так как он основан на JavaScript, условному веб‑разработчику втянуться и в мобильную разработку не составит больших усилий. По этой причине и людей найти на такую позицию будет значительно проще.

2. Нативная разработка под каждую платформу отдельно. Для этого нужны отдельные разработчики на Android и iOS, но это дает полный контроль над всеми функциями и средствами разработки. На Android разработку человека найти намного проще, так как зачастую в ней используется Java или Kotlin, которые многие знают, отчего и людей способных с этим работать достаточно много. С iOS ситуация же обратная. Хоть у Swift и есть некие сходства с C‑подобными языками, по сути многие вещи нужно будет изучать с нуля, отчего хороших разработчиков крайне мало. Проблема осложняется тем, что разработка будет наиболее продуктивной и удобной с XCode — интегрированной средой разработки, доступной только для операционной системы macOS. Как вы можете догадаться — позволить себе подобное устройство от Apple может не каждый. А пробовать реализовать подобное через виртуальную машину — сомнительная затея.

Обсуждать плюсы и минусы можно долго, вникая в каждый самый незначительный факт, но все всегда сводится к скорости и стоимости разработки. И здесь понятное дело, что кроссплатформенная разработка выигрывает. Но почему у нас в таком случае все разрабатывается нативно?

На самом деле все до банального просто, а повлияло на это 2 фактора:

  1. Исторический фактор. Так сложилось, что при организации команды мы быстро нашли и Android, и iOS разработчика, а вот выйти на разработчика Flutter/React Native долгое время не удавалось.

  2. Безопасность и надежность. В случае нашей разработки мы задействуем модуль NFC в телефоне. Здесь необходима безопасность и прямой контроль работы смартфона в этот момент. Из‑за чего «на всякий пожарный» была выбрана именно нативная разработка, так как, например, у iPhone работа с этим модулем крайне закрытая. Опасаясь проблем на начальном этапе был сделан именно такой выбор.

Android разработка и ее особенности

Далее Никита:

«Я начал работу над проектом с построения xml‑макетов, основанных на предоставленном дизайне в Figma. Этот этап стал для меня по сути новым опытом, поскольку до этого момента полноценно я не работал над созданием frontend для мобильных приложений, а специализировался backend‑разработкой на Java. Работа с XML представила собой некоторый вызов, ведь сформировавшаяся привычка была к совершенно другим задачам.

Осознавая, что мобильные устройства обладают широким спектром размеров экранов, разрешений и плотностей пикселей, мы приняли решение с самого начала заложить в проект адаптивные макеты. Что по сути является единственным верным решением при разработке. Отсутствие адаптивной верстки может привести к тому, что даже идеально воспроизведенные в XML макеты могут значительно отличаться в визуальном представлении на разных телефонах.

В качестве примера адаптивной верстки могу привести работу с карточками. Для формирования этих карточек я использовал ViewPager2 и создал шаблон CardView, который подходил бы под разные данные. На этих карточках располагалось несколько строк с указанием количества или отсутствия/наличия. Для решения я изначально скрывал некоторые строки и при необходимости показывал их, устанавливая visible через адаптер. После настройки этой части я понял, что на устройствах с небольшим экраном карточки не помещаются и закрывают собой остальной контент на экране. Для этого я настроил гайдлайны для ViewPager. После этого оказалось, что если строк на карточке много, а экран маленький весь контент не помещался.

Решением стало использование кастомного MaxHeightScrollView, т.к. установить максимальную высоту для ScrollView почему‑то нельзя. В таком случае не была интуитивно понятна возможность прокрутки. Исправил я эту ситуацию добавлением градиентов в верхней и нижней части ScrollView. Начальный и конечный цвета градиента задавал в формате #AARRGGBB, где AA обозначает альфа‑канал (уровень прозрачности), а RRGGBB — значение цвета в формате RGB. В адаптере проверял, помещается ли содержимое ScrollView полностью в видимую область без необходимости прокрутки. Если прокрутка не требуется, градиенты делаются невидимыми. Для динамического изменения видимости градиентов установил слушатель прокрутки. Верхний градиент становится видимым, как только пользователь начинает прокрутку вниз (scrollY > 0). Видимость нижнего контролируется через проверку возможности дальнейшей вертикальной прокрутки с помощью canScrollVertically(1).

holder.topGradient.setVisibility(scrollY == 0 ? View.INVISIBLE : View.VISIBLE);

holder.bottomGradient.setVisibility(holder.scrollView.canScrollVertically(1) ? View.VISIBLE : View.INVISIBLE);
Результат (на первом скрине приложение специально запущено на устройстве с маленьким экраном)

Возможно, такое решение покажется кому‑нибудь полезным :) Буду рад увидеть более практичные варианты реализации в комментариях.

Сейчас наше приложение написано на Java. До начала работы над этим проектом я имел серьезный опыт работы именно с Java. А с Kotlin опыта работы не было, из‑за чего и был сделан изначальный выбор в сторону Java, так как проекту нужно было быстро начать разработку, чтобы MVP можно было показать экспертам на конкурсах и инвесторам.

Kotlin, как минимум, предлагает более современный синтаксис по сравнению с Java, что упрощает чтение и написание кода. Также Kotlin обладает множеством современных функций, таких как корутины для асинхронного программирования, которых нет в Java. Кроме того, в некоторых случаях Java может быть медленнее Kotlin. Учитывая плюсы последнего, в ближайшее время моя задача заняться переносом проекта полностью на него, даже если это займет много времени.

Работа с API в Android

В разработке мобильных приложений взаимодействие с API играет ключевую роль, позволяя приложениям обмениваться данными в реальном времени. Для успешной интеграции и эффективного общения с сервером, я выбрал Retrofit в сочетании с OkHttpClient, обеспечив тем самым мощный и гибкий механизм для работы с сетью.

Retrofit выделяется своим высоким уровнем абстракции, предоставляя удобный интерфейс для отправки HTTP‑запросов и обработки ответов. Это значительно упрощает разработку, позволяя определять сетевые запросы с помощью аннотаций и автоматически преобразовывать JSON‑ответы в Java‑объекты. OkHttpClient же служит надежной основой для Retrofit, предлагая расширенные возможности для настройки запросов, кэширования и повторных попыток.

Разберем и другие доступные варианты. Например, Volley от Google предлагает удобные инструменты для выполнения сетевых запросов и обработки изображений, оптимизированных для быстрого и эффективного взаимодействия с сервером. Однако Volley может быть не лучшим выбором для работы с большими объемами данных. Для приложений на Kotlin есть Ktor, представляющий собой современную асинхронную библиотеку, специально созданную для Kotlin. Ktor идеально подходит для асинхронного программирования с использованием корутин и позволяет легко настраивать клиентские и серверные части приложения, благодаря своей модульности и легковесности.

Для минимизации рисков, связанных с внутренними угрозами, важно тщательно управлять правами доступа к системам и данным. Пользователи должны иметь только те права доступа, которые необходимы им для выполнения их функций, исключая доступ к критически важным системам без необходимости.»

Никита достаточно быстро обучился мобильной разработке, благодаря уже имеющимся знаниям и опыту. Так что, если вы хотите переучиться на мобильную разработку, но не имеете большого опыта именно в разработке для Android — можно спокойно попробовать себя. Процесс переобучения несложен.

Но важно отталкиваться от ваших уже имеющихся знаний. Возможно, проще будет пойти в кроссплатформенную разработку, где вакансий будет явно больше.

Если же вы только на пути выбора направления, то Android разработка принципиально ничем не сложнее чем любая другая. Есть свои тонкости и сложности, как и везде.

Разработка на iOS и её особенности

Далее Сергей:

«В iOS‑разработку я попал достаточно спонтанно, поэтому пришлось учиться новому на ходу. Я еще не успел стать гуру Swift‑приложений, поэтому пишу лишь о своём опыте, который накопился за это время, и о котором есть, что рассказать.

На данный момент существуют два основных framework»а для разработки пользовательских интерфейсов: UIKit и SwiftUI.

UIKit — проверен временем, хорошо изучен.
SwiftUI — напротив, новый и изучен далеко не так хорошо =D.

Существует и различие между подходами к разработке. Подробнее вы можете почитать, например, здесь.

Даже передовой Яндекс рекомендует для стажёров знание именно UIKit, а не SwiftUI.

Это не значит, что SwiftUI плох, а скорее говорит о его распространенности в РФ. Но, например, в западных компаниях он уже применяется.

Основная идея при выборе была в ускорении разработки и делегирования некоторых функций непосредственно машине, чтобы лишний раз не прописывать какие‑то шаблонные вещи. Порог входа в SwiftUI ниже, а первые результаты появятся раньше, поэтому его и выбрал. Так что для начинающего это более простой вариант из нативной разработки для iOS, но и вакансий здесь будет меньше в России.

Сразу в бой

За первые дни разработки был почти полностью сделан рабочий UI первого приложения‑прототипа. Если разбивать дизайн по слоям и искать в них соответствия по горизонтали или вертикали, то работа очень простая и быстрая. Что надо сделать горизонтально — пишем в VStack, что вертикально — в HStack. Иногда необходимо это комбинировать.

В SwiftUI огромное количество заранее предусмотренных шаблонов:

  • список с полосой прокрутки,

  • ссылки с переходами на другие окна,

  • различные действия по нажатию, которые используются в стандартных приложениях Apple. Они очень просты в использовании и органично встраиваются в приложение.

Swift крайне быстрый. ОЧЕНЬ приятно смотреть, как твое приложение абсолютно без тормозов и лагов буквально летает. Все менюшки открываются мгновенно, а плавные анимации переходов радуют глаз.

Но потом началось написание логики…

Постоянные вопросы к GPT с её часто рандомными ответами, видео на ютубе и просмотр репозиториев состоявшихся программистов — это похоже на лотерею в моей ситуации. Иногда ты абсолютно сходу находишь нужный подход/инструменты, а иногда даже не знаешь, как сгенерировать запрос. Спросить, как будет лучше поступить в той или иной ситуации, мне опять же было не у кого, так как разработчиков на SwiftUI кот наплакал.

Ещё портит, что сама Apple не комментирует то, как правильнее проектировать приложение. Например, для UIKit идеально подходит паттерн MVVM. Использовать MVVM в SwiftUI часто кажется излишним и хочется выкинуть промежуточное звено в взаимоотношении Модели и Вьюшки, придерживаясь чего‑то похожего на MV‑паттерн.
Возможно, более опытные люди определились для себя с этим вопросом, поэтому буду ждать комментариев по этому поводу.

Иногда хочется быстро сделать какой‑то прототип функционала, чтобы проверить, как он будет выглядеть и работать. Например, отображение информации о пользователе. Сначала на одном экране, потом на другом. Или проверить, что информация, изменившаяся на одном экране, поменяется на другом. Придя из мира С++, я думал, что здесь есть какой‑то аналог глобальной переменной. Ну просто создадим себе что‑то такое глобальное для теста, а потом уже сделаем что‑то умнее :)

В SwiftUI нельзя просто так сделать себе глобальную переменную. Здесь есть понятие property‑wrapper. Это модификатор переменной, который говорит, что у неё есть какое‑то предназначение. Например, @State отслеживает любое изменение переменной. State‑переменной описывается некоторое состояние экрана в моменте (подробнее можно изучить здесь).

Так вот, чтобы сделать аналог глобальной переменной для нескольких экранов, мы должны воспользоваться паттерном «наблюдатель», но с «костылем».

Мы создадим класс с возможностью быть обозреваемым, потом создадим сам элемент в каком‑то верхнем экране, а потом уже кинем экземпляр в дочерний экран.

class UserProgress: ObservableObject {
    @Published var score = 0
}

struct InnerView: View {
    @ObservedObject var progress: UserProgress

    var body: some View {
        Button("Increase Score") {
            progress.score += 1
        }
    }
}

struct ContentView: View {
    @StateObject var progress = UserProgress()

    var body: some View {
        VStack {
            Text("Your score is \(progress.score)")
            InnerView(progress: progress)
        }
    }
}

Пример взят отсюда, можете изучить подробнее.

Работа с API

Опишу кратко и по делу:
С одной стороны, из коробки мы получаем механизм кодировки и декодировки данных в/из JSON и других форматов, встроенные функции отправки запросов и проверки на ошибки выполнения.

Очень ли это помогает? — Да.

Сколько нервных клеток ты потратишь, пока разберешься во всех тонкостях? — Много.

Итог

Оглядываясь назад, стал бы я сейчас учиться использовать SwiftUI, или всё‑таки UIKit лучше? — Всё же встал бы на сторону SwiftUI.

UIKit, как мне кажется, требует гораздо больших усилий для начала работы, а в нашем проекте это играет ключевую роль. Несмотря на минусы, которые я описал выше, SwiftUI очень мощный инструмент, но при этом достаточно капризный. Его скорость не может не радовать — инженеры Apple проделали огромную работу по оптимизации. В силу недостаточно большого опыта, я не чувствую некоторые моменты, из‑за которых и стреляю по привычке себе в ногу.

При этом важно понимать, что UIKit в России популярнее и многие компании разрабатывают именно на нем. Если вы хотите выбрать направление нативной разработки iOS для больших компаний, думаю, все же выбор UIKit будет более удачным решением.»

Интересная фишка и ее разработка

Пример того, как наш подход позволил реализовать для сферы что‑то новое:

«В нашем приложении вы можете контролировать сразу практически неограниченное количество замков с их группировкой и настройкой. После того, как вы добавите второй или следующий по счету замок в ваш аккаунт, он сразу появится на главном экране. При этом будет возможность выбрать один из них по умолчанию — он будет использоваться сразу, как только вы откроете приложение. Допустим, у вас есть квартира и дача. Данная функция сделана как раз для того, чтобы вам, имея несколько замков, не приходилось постоянно делать одно дополнительное нажатие для выбора замка, который хотите открыть.

Если же вы пользуетесь своими замками одинаково часто, тогда вы можете не выбирать замок по умолчанию. В таком случае запоминаться будет последний использованный замок, а в нужный момент вы можете одним нажатием изменить его на другой. Это сделано также для уменьшения лишних нажатий для открытия.

При этом вы можете удобно и дистанционно управлять своими замками. В меню «Доступ» вы можете выбрать нужный замок и изменить настройки доступа к нему. Кроме того, здесь же можно будет посмотреть историю посещений.

Причем, если вам дали доступ к любому замку нашей компании, он появится у вас в приложении. То есть, поставив замок всем своим родным, физические ключи исчезнут из вашей жизни.

Также для упрощения работы с несколькими замками вы можете разделить их на группы. Все ключи от дверей могут находиться в вашем телефоне, и не нужно будет думать, какой ключ от какого замка — это будет интуитивно понятно. Подобная функция, например, арендодателям позволит управлять сразу несколькими квартирами без дополнительных «костылей» или неудобств.»

На первый взгляд задача не кажется такой объемной, но чтобы ее реализовать, нужно было составить ТЗ по необходимому функционалу, продумать UX/UI, спроектировать базу данных серверной части для четкого контроля доступов с учетом иерархии ролей, и только после этого уже комплексно реализовать и протестировать весь оставшийся функционал.

И все подобные сложные функции — это большая работа далеко не одного человека, но выстроенная система помогает это делать оптимизировано и быстро. А плоды, в свою очередь, не могут не радовать нас, когда мы сравниваем наш продукт с аналогами на рынке.

Так что мобильная разработка в сфере IoT — это не шаблонные приложения, имеющие пару функций, а крайне интересная и напряженная работа со своими тонкостями. По крайней мере у нас.

Вывод

Кратко изложу итоги, к которым мы сами пришли с командой, пройдя уже довольно серьезный путь и уже готовясь к публикации приложений:

  1. Мобильная разработка — это непросто, но и не так сложно, как может показаться на первый взгляд. При этом имейте в виду, что рынок разработчиков в РФ крайне скудный в этом направлении. Толковый разработчик либо очень дорогой, либо уже занят. И это касается как нативной разработки, так и кроссплатформенной (хотя и React Native сейчас активно развивается).

  2. IoT — быстроразвивающаяся сфера, которая скоро станет окружать не только любителей умной техники. Она будет повсеместно развита в любых местах, как общественных, так и в личном жилье. Умные лампочки, шторы, чайники и, конечно, замки — все это уже начинает входить в быт у многих людей. Продажи умной колонки от Яндекс пробили отметку в 7 млн. штук. И чем больше развивается данная сфера, тем больше она усложняется в разработке и требует больше специалистов.

И самое важное, конечно, это организация четкой логической цепочки разработки. Именно правильно поставленная цель и грамотные люди, которые ее понимают, могут создавать поистине выдающийся продукт.

Секрет успеха — в постоянстве цели.
Бенджамин Дизраэли

Only registered users can participate in poll. Log in, please.
Являетесь ли вы мобильным разработчиком?
50% Да12
50% Нет12
24 users voted. 5 users abstained.
Tags:
Hubs:
Total votes 5: ↑3 and ↓2+4
Comments29

Articles

Information

Website
nfckey.tech
Registered
Founded
2023
Employees
2–10 employees
Location
Россия
Representative
Иван