Система для организации аренды велосипедов без базовых парковочных станций

Разработка аппаратно-программной системы для организации байкшеринга без базовых парковочных станций. Проектирование клиентского приложения для iOS, сервера на Spring Boot, аппаратного прототипа. Архитектурный подход, фреймворки, особенности реализации.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 04.12.2019
Размер файла 2,3 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Система для организации аренды велосипедов без базовых парковочных станций

Аннотация

байкшеринг клиентский приложение программный

Работа посвящена разработке аппаратно-программной системы для организации байкшеринга без базовых парковочных станций. Данная работа представляет собой клиентское приложение для iOS, сервер на Spring Boot и аппаратный прототип на Arduino. Система позволяет арендовать велосипед через мобильное приложение и после поездки оставить его в любом месте.

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

Ключевые слова - MVVM, iOS, Spring Boot, Bikesharing, Arduino

Введение

В современном мире каждый человек пытается обзавестись собственным имуществом. Успехом считается приобретение квартиры и машины. Последнее приводит к постоянным пробкам на дорогах, причём уже не только в больших городах. Общественный транспорт в часы пик тоже не всегда спасает из-за большого потока пассажиров. Решить эту проблему можно с помощью «-шеринг» модели. Сейчас в больших городах распространён в основном каршеринг. Суть заключается в том, что собственный автомобиль больше не нужен, а значит не нужно платить за парковку, заправлять и ремонтировать, нужно просто зарегистрироваться в приложении каршеринга и пользоваться общедоступными разбросанными по всему городу автомобилями, беря их в краткосрочную аренду, тем самым уменьшая количество машин на дорогах. Но автомобили - не единственное решение. В Китае, например, распространены велосипеды - байкшеринг. Крупнейшие китайские стартапы Ofo и Mobike вместе заработали более 2,2 миллионов долларов. [1]

Стоит обратить внимание на тот факт, что количество людей, использующих мобильные телефоны, постоянно растёт, а соответственно и количество пользователей мобильных приложений. В марте 2017 г. по статистике использования интернета совокупно на настольных ПК, ноутбуках, планшетах и смартфонах мобильная Android (37,13% рынка) впервые в истории обогнала Windows. На 3 месте находится iOS. [18] Не удивительно, что почти каждый сервис сейчас имеет собственное мобильное приложение. И соответственно каждый байкшеринг также должен иметь мобильное приложение.

Целью данной работы - повысить эффективность транспортных систем путём организации байкшеринга без базовых станций.

Для достижения цели потребуется решить следующие задачи:

1) Анализ существующих решений, предоставляющих услуги байкшеринга

2) Разработать требования к мобильному приложение и серверу, которые позволят арендовать велосипед

3) Проектирование архитектуры iOS приложения и сервиса

4) Разработать интерфейс мобильного приложения

5) Проектирование аппаратного прототипа системы

6) Реализовать iOS приложение на языке Swift и сервер на Spring

7) Тестирование

8) Написание документации

Определения

Доки - парковочные станции, куда ставится велосипед после аренды.

Бордерплейт-код - код, который не несёт в себе полезных функций и нужен только для поддержания архитектуры.

Биндинг - связывание.

Байкшеринг - аренда велосипедов.

Testflight - ресурс для загрузки бета-версий iOS-приложений

Глава 1. Анализ предметной области и обзор систем байкшеринга

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

1.1 Сравнительный анализ систем байкшеринга

Анализируемые системы: ofo, mobike, velobike, mobee, delisamokat. Последнее приложение предоставляет услуги по аренде самокатов, однако специфика самой системы похоже на аренду велосипедов. Первые 2 приложения - самые популярные в Китае. Проведя анализ их функций, предоставляемых данными программами, можно понять, реализации каких функций является необходимой для нашего приложения. Сравним основные плюсы и минуты конкурентов и нашего приложения.

Сравнительный анализ будет содержать в себе следующие критерии:

· Отсутствие парковочных станций

· Отсутствие специфичного рынка

· Отсутствие ограничивающих зоны, где можно оставить велосипед

· Велосипеды

· Автоматическая аренда (без участия человека)

Ofo

Mobike

Velobike

Mobee

Delisamokat

Наше приложение

Отсутствие доков

+

+

-

+

-

+

Отсутствие специфики

-

-

-

-

-

+

Велосипеды

+

+

+

+

-

+

Отсутствие специальных зон

+

+

-

-

-

+

Автоматическая аренда

+

+

+

+

-

+

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

Распространенный в Москве Велобайк использует парковочные станции - это специальные «базы», куда крепиться велосипед после аренды.

Рисунок 1. Парковочные станции Велобайк

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

У делисамокат самокаты вообще выдает человек из специальной машины.

Рисунок 2. Машина с самокатами делисамокат

1.2 Определение требований к разрабатываемой системе

Авторизация в приложении

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

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

Поиск и бронирование велосипедов

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

Аренда велосипедов

Чтобы начать аренду, пользователь должен дойти до велосипеда и просканировать QR-Code, расположенный на велосипеде, с помощью приложения. После успешного сканирования приложение запрашивает подтверждение у сервера и разблокирует замок через Bluetooth. После этого начинается аренда велосипеда (поездка).

Поездка и окончание аренды

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

Оплата

Для осуществления оплаты нужно решить некоторые юридические тонкости, поэтому в данном проекте реальной оплаты нет. В качестве теста показана демо-оплата с помощью Apple Pay.

Обеспечение безопасности работы системы

Для обеспечения безопасности велосипеда собирается аналитика. Например, если кто-то забрал заблокированный велосипед к себе домой, то им никто не сможет воспользоваться. Это отразиться в аналитике и послужит сигналом о краже. Также аналитика поможет для улучшения User Experience приложения.

Модель работы системы

Система состоит из 3 основных компонент: iOS-приложения, сервера и замка. Мобильное приложение подгружает данные сервера и отображает их пользователю. При начале аренды велосипеда iOS приложение через Bluetooth LE посылает сигнал на Arduino. Arduino разблокирует замок.

Выводы по главе

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

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

Глава 2. Проектирование платформы

В данной главе затрагиваются проблемы проектирования мобильного приложения и сервера. Сначала проводится анализ существующих паттернов проектирования для iOS и выбор основного паттерна для реализации. Затем рассказывается про проектирование сервера и общую схему работы велосипеда.

2.1 Обзор архитектурных подходов мобильного приложения

В iOS разработке на данный момент популярны 4 паттерна: MVC (Model View Controller), MVP (Model View Presenter), MVVM (Model View ViewModel) и VIPER (View Interactor Presenter Entity Router). Рассмотрим преимущества и недостатки каждого из них на основе следующих критериев:

1. Распределение ответственности. Является одним из принципов SOLID - буква S (Single Responsibility Principle). Идея заключается в том, что каждый метод/компонент должен выполнять только одну функцию. Если это не так, то следует разделить его на несколько частей. Это позволяет со временем не терять понимание полноты функционала, реализуемого классами и методами.

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

3. Скорость разработки. В современном мире скорость разработки является одним из главных факторов успеха разработки ПО. Если ПО пишется слишком долго оно уже успевает устареть и стать не нужным.

Model View Controller

MVC - классический подход к проектированию архитектуры. Apple по умолчанию предлагает именно этот подход к проектированию. [8]

Рисунок 3. Архитектура MVC

В MVC существуют 3 слоя:

1. Model - представляет сущности данных.

2. View - отвечает за отображение на экране и обработку действий пользователя

3. Controller - посредник между Model и View. С помощью него View узнает об изменениях в Model и наоборот.

Однако в реальности в iOS приложении средствами Apple можно реализовать только следующую схему, представленную на рисунке 2.

Рисунок 4. MVC от Apple [17]

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

Данный подход является очень простым в разработке, однако Controller и View являются сложнотестируемыми компонентами. При таком подходе почти нет распределения ответственности, так как Отображение и Контроллер фактически ответственны за одно и то же.

Model View Presenter

Рисунок 5. MVP [17]

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

Model View ViewModel

Наиболее современная архитектура из MV*. ViewModel вызывает изменения в Model и обновляется на основе этих изменений, а так как View с помощью биндингов привязано к ViewModel, то View тоже обновляется автоматически.

Рисунок 6. MVVM [17]

Биндинги осуществляются с помощью KVO или же с помощью реактивного программирования, с помощью таких фреймворков как ReactiveCocoa и RxSwift.

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

VIPER

VIPER - пример адаптации Clean Architecture [17] под iOS. Является примером максимального распределением ответственности среди всех рассматриваемых подходов к проектированию мобильных приложений.

Рисунок 7. VIPER

VIPER состоит из 5 модулей:

1. View - отображение элементов на экране. ViewController из MVC.

2. Presenter - независимый от интерфейса посредник, который отвечает за обновление отображения.

3. Router - компонент, отвечающий за переходы между экранами

4. Interactor - компонент, отвечающий за предоставления данных

5. Entity - компонент, в котором хранятся данные.

VIPER из-за своей распределённости обязанностей является наиболее тестируемым подходом, однако сложность написания и объём кода, требуемого для реализации данного подхода, становится фактором, негативно влияющим на выбор архитектуры приложения.

2.2 Обоснование выбора архитектуры мобильного приложения

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

Остается выбор между MVP и MVVM. Так как MVVM является наиболее современным подходом, учитывающим недостатки предыдущих, и требует меньшего написания кода в отличие от MVP, выбор был сделан в пользу него.

Для биндинга View к ViewModel используется фреймворк для реактивного программирования RxSwift.

2.3 Хранение данных в мобильном приложении

Для хранения данных в приложении используется стандартный фреймворк Core Data [4], который представляет собой удобную оболочку над SQLite базой данных. В качестве альтернативных решений можно рассмотреть использование SQLite напрямую и использование Realm, однако была выбрана Core Data, так как она поддерживает операции в нескольких контекстах, что положительно влияет на производительность. На рисунке представлена ER модель Core Data, используемая в приложении.

Рисунок 8. Архитектура модели в Core Data

Core Data поддерживает автоматическую миграцию версий, а также имеет автоматический кодогенератор [4].

2.4 Проектирование дизайна мобильного приложения

Перед началом разработки был спроектирован дизайн мобильного приложения в Sketch.

Рисунок 9. Дизайн мобильного приложения (Часть 1)

Приложение состоит из 3 основных экранов - Карта, История поездок и Аккаунт. При выборе велосипеда на карте появляется элемент с 2 кнопками - «Сканировать код» и «Построить маршрут» (экран “Tapped” на рисунке).

Рисунок 10. Дизайн мобильного приложения (Часть 2)

На рисунке показаны экраны сканирования QR-кода (“Scanning”), экран поездки (“Riding”), экран окончания поездки (Finish ride), и маршрут до велосипеда (“Route”).

Примерная последовательность действий такая:

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

2. При нажатии появится ближайший адрес к велосипеду и 2 кнопки: построить маршрут до велосипеда (при построении маршрута велосипед бронируется) или же сразу просканировать QR-код для начала аренды (каждый велосипед будет иметь qr code для его разблокировки), если пользователь уже у велосипеда.

3. Пользователь сканирует QR-код, расположенный на велосипеде для начала аренды.

4. После сканирование кода, начинается аренда велосипеда.

5. После завершения аренды пользователь видит основную информацию о прошедшей поездке.

2.5 Проектирование серверной части

Серверная часть состоит из модулей, построенных на архитектуре MVC. Для каждого модуля есть свой REST Controller, своя Model/Entity, которая также является таблицей в базе данных и View для отображения данных. Ниже представлен пример модуля Bike и архитектура базы данных с основными полями.

Рисунок 11. Модуль Bike

Рисунок 12. Архитектура базы данных

RestrictedZone представляет собой зоны, где нельзя оставлять велосипеды, например загородом. DBFile представляет собой файл (название, тип и сами данные), нужен для хранения сгенерированных QR-кодов. Transactions представляет собой данные о платежных транзакциях. Каждая Entity также имеет поля даты создания и даты обновления.

2.6 Панель администратора

На сервере также разработана панель администратора. Графические интерфейс реализован на Vaadin. А карта через Polymer component для Google Map.

Рисунок 13. Панель администратор

2.7 Общая схема взаимодействия системы

Система состоит из 3 главных компонент: Сервер, мобильное приложение и Arduino.

Сервер обрабатывает Rest API запросы, обращается к базе данных и отдает информацию обратно мобильному приложению.

Для открытия умного замка на велосипеде приложение посылает запрос на Bluetooth-модуль Arduino. Arduino считывает команду и подает ток на нужный модуль.

Рисунок 14. Общая схема взаимодействия

2.8 Умный замок

Рисунок 15. Схема умного замка

На рисунке представлена примерная схема подключения модулей к Arduino. На схеме отсутствуют резисторы, так как в реальной схеме использованы тройка-модули, в которые они уже встроены.

Схема состоит из:

1. Геркона, который нужен для идентификации состояния - закрыт замок или нет;

2. Соленоида, который подключен к силовому ключу для питания от батареек 12В

3. Bluetooth-модуля - BLE модуль для получения информации с телефона.

Выводы по главе

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

На основе полученных результатов начинается разработка программы.

Глава 3. Разработка платформы

В этой главе представлены и описаны инструменты и методы, использованные в процессе этапа реализации серверной и клиентской части системы.

3.1 Серверная часть

Для разработки сервера был выбран Spring Boot Framework. Spring - универсальный фреймворк с открытым исходным кодом для Java-платформы. Служит в основном для инверсии зависимостей. Но это не единственная его функция. Он состоит из множества структурных элементов, таких как Spring MVC, Spring Security и т.д. Spring Boot - упрощенная версия Spring.

Сделанный выбор обосновывается простотой данного фреймворка. Он был спроектирован так, чтобы разработчикам пришлось писать как можно меньше кода, а все настройки производились в property файле.

Для хранения данных была выбрана PostgreSQL база данных. Выбор обусловлен простой интеграцией со Spring и хостингами, такими как Heroku.

Для ORM используется библиотека Hibernate. Целью библиотеки является освобождение разработчика от значительного объёма сравнительно низкоуровневого программирования при работе в объектно-ориентированных средствах в реляционной базе данных. [6] Hibernate также довольно просто интегрируется с Spring и PostgreSQL - достаточно в property просто прописать нужный dialect.

Для автогенерации геттеров и сеттеров использован Project Lombok. [10] Она позволяет избавиться от бойлерплейт-кода, присущего Java в виде написание геттеров и сеттеров для каждого поля класса, заменив их одной аннотацией.

На сервере также предусмотрена панель администратора. Администратор может добавлять велосипеды, просматривать их на карте и смотреть данные в базе данных. Вход защищен с помощью Spring Security.

Для отображения данных на сервере используется Vaadin. Vaadin - свободно распространяемый фреймворк для создания RIA-веб-приложений. Одна из наиболее значимых функций - использование Java - как единственного языка программирования при создании веб-приложений и веб-контента. [15] Он позволяет генерировать web-страницы вообще без написания HTML. Vaadin поддерживает Polymer-компоненты. Один из таких использован для отображения Google Map. [5]

3.2 Клиентская часть

Для реализации клиентской части приложения выбрана интегрированная среда разработки Xcode и язык программирования Swift [12].

Сделанный выбор обосновывается тем, что Xcode это IDE, разработанная корпорацией Apple, которая поддерживает стабильность продукта на высоком уровне, часто обновляет его, а также активно развивает сообщество iOS и macOS разработчиков. Что касается языка программирования, выбор пал на Swift, а не на Objective-C, потому что можно выделить следующие преимущества ЯП Swift, а именно:

1. Swift легче поддерживать. В отличие от Objective-C, который основан на C, Swift отменяет требование двух файлов

2. Swift более читаемый. Синтаксис намного проще и требует намного меньше строк кода на одно и то же действие. Довольно много синтаксического сахара.

3. Полноценное взаимодействие с кодом, написанным на Objective-C

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

Для реализации iOS-приложения была выбрана SOA-архитектура:

Рисунок 16. SOA-архитектура мобильного приложения

Приложение разбито на 3 модуля: Core Layer, Service Layer и Presentation Layer. Core Layer является бинарным фреймворком и хранит в себе Core вещи, такие как Core Data Stack, который могут быть использованы в Extension. Service Layer - служит прослойкой между Presentation и Core. Он перенаправляет запросы к нужному Core сервису. Presentation Layer отображает данные. В Presentation Layer была реализована архитектура MVVM, причины выбора которой были описаны в предыдущей главе.

Каждый крупный модуль в Presentation Layer имеет следующие классы:

1. Assemble - собирает модуль, путем инверсии зависимостей

2. Router - отвечает за навигацию между котроллерами

3. Service - получает данные от Service Layer.

4. ViewModel - посредник между отображением и данными.

5. ViewController - отображает данные

Для биндинга данных был выбран RxSwift. RxSwift - Swift версия фреймворка Rx для парадигмы реактивного программирования. Основная суть в том, что разработчик ориентируется на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что нижележащая модель исполнения должна автоматически распространять изменения благодаря потоку данных.

Применительно к iOS такая парадигма позволяет без проблем синхронизировать закэшированные данные и полученные с сервера. Нужно просто сконкатенировать два Observable:

func getAllBikes() -> Observable<[BikeViewModel]> {

return Observable.concat([getBikesFromCoreData(), getBikesFromServer()])

}

Для отображения на экране используется RxCocoa. Нужно сбиндить UI элемент к Observable. Пример для таблицы:

viewModel.items.asObservable().bind(to: tableView.rx.items(cellIdentifier: "rideCell")) { row, ride, cell in

guard let cell = cell as? RideTableViewCell else { return }

cell.selectionStyle = .none

cell.startLabel.text = ride.startAddress

cell.endLabel.text = ride.endAddress

if let image = ride.imageURL {

cell.mapImageView.af_setImage(withURL: image)

}

cell.dateTimeLabel.text = ShortDateFormatter.string(from: ride.endTime!)

}.disposed(by: disposeBag)

Push уведомления

Поддержка push уведомлений на сервере реализована с помощью библиотеки Java Apple Push Notification Service Library.

Подписка на уведомления в мобильном приложении осуществляется по следующему алгоритму:

1. После авторизации приложении предлагает пользователь разрешить push уведомления

2. Если пользователь разрешил, то отправляется запрос на регистрацию в сервисе Apple, а затем POST запрос на сервер системы с полученным токеном после регистрации. Затем push-уведомления отправляются по этому токену.

Аналитика

Одним из способов обеспечения безопасности велосипедом может стать сбор аналитики. Например, с помощью неё можно понять, что один из велосипедов слишком долго не используют, значит с ним что-то не так, возможно стоит в недоступном месте. И в целом аналитика помогает улучшению UX.

Для сбора аналитики используются Firebase и Fabric.

Core Bluetooth

Для отправки запросов на Bluetooth модуль Arduino используется Core Bluetooth фреймворк. За это отвечает класс BluetoothManager.

Сначала ищутся перефирийные устройства с ID 0xFFE0 - идентификатор по умолчанию у модуля HM-10. При нахождении одного из таких устройств, идёт попытка подключения:

func centralManager(_central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

// Reject any where the value is above reasonable range

if (RSSI.intValue > -15) {

return;

}

print("Discovered %@ at %@", peripheral.name, RSSI);

data = nil

// Ok, it's in range - have we already seen it?

if (self.discoveredPeripheral != peripheral) {

// Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it

self.discoveredPeripheral = peripheral;

// And connect

print("Connecting to peripheral %@", peripheral);

self.centralManager.connect(peripheral, options: nil)

}

}

Затем идет подключение к Сервису и поиск Характеристик по определенному ID. После успешного поиска начинается обмен сообщениями. Сообщения от модуля обрабатываются в специальном методе делегата:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

if let error = error {

print("error update charsterics", error.localizedDescription)

return

}

let string = String(data: characteristic.value!, encoding: .utf8)

switch string {

case "CLOSED":

if lockState == .sendUnlock {

break

} else if lockState == .unlocked {

lockState = .locked

NotificationBanner.showSuccessBanner("Замок закрыт!")

peripheral.setNotifyValue(false, for: characteristic)

centralManager.cancelPeripheralConnection(peripheral)

}

case "OPENED":

if lockState == .sendUnlock {

lockState = .unlocked

NotificationBanner.showSuccessBanner("Замок открыт!")

} else if lockState == .locked {

NotificationBanner.showErrorBanner("Мошенничество!")

}

default:

break

}

self.data?.append(characteristic.value!)

print("Recieved: ", string)

}

Core Location и MapKit

Приложение определяет, где находится пользователь благодаря использованию Core Location и отображает это на карте. Используя MapKit можно отобразить метки на карте. Таким способом отображаются велосипеды. Для их показа задает широта, долгота и кастомное изображение, после чего маркер добавляется на карту.

В приложении также есть возможность построить маршрут до велосипеда. Это делается с помощью MKDirections и polyline.

Рисунок 17. Велосипед и маршрут до него на карте

При нажатии на велосипед высчитывается его примерный адрес:

func address(for location: Point, completion: @escaping(String?)->()) {

self.geocoder.reverseGeocodeLocation(CLLocation(latitude: location.latitude, longitude: location.longitude), preferredLocale: self.locale) { placemarks, error in

let address = placemarks?.first?.locality

DispatchQueue.main.async {

completion(address)

}

}

}

3.3 Внедрение зависимостей

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

На сервере для внедрения зависимостей используется Spring. Пример кода:

public class BikeController {

private final BikeRepo bikeRepo;

@Autowired

public BikeController(BikeRepo bikeRepo) {

this.bikeRepo = bikeRepo;

}

}

На клиента используется Swinject. Пример кода:

class RidesAssembly: Assembly {

func assemble(container: Container) {

container.register(RideListRouter.self) { (_: Resolver, viewController: UIViewController) in

return BaseRideListRouter(viewController: viewController)

}

container.register(RideListService.self) { resolver in

return BaseRideListService(coreDataManager: resolver.resolve(CoreDataManager.self)!, apiService: resolver.resolve(ApiService.self)!)

}

container.register(RideListViewModel.self) { (resolver: Resolver, viewController: UIViewController) in

return BaseRideListViewModel(service: resolver.resolve(RideListService.self)!, router: resolver.resolve(RideListRouter.self, argument: viewController)!)

}

container.storyboardInitCompleted(RidesViewController.self) { resolver, controller in

controller.viewModel = resolver.resolve(RideListViewModel.self, argument: controller as UIViewController)

}

}

}

3.4 Умный замок

Прототип умного замка для велосипеда построен на Arduino. Данный микроконтроллер лучше всего подходит для прототипирования, особенно для неопытных разработчиков. В качестве модулей были выбраны тройка-модули [14], так как в них уже интегрирована вся обвязка для безопасного подключения к Arduino. Они представляют собой “System-on-a-Chip”, что позволяет удобно подключать их к troyka-shield. [13] При прототипировании таким способ не нужно ничего паять.

В качестве Bluetooth модуля был выбран тройка-модуль на базе HM-10, который поддерживает Bluetooth Low Energy, что важно при подключении к устройствам на базе iOS.

Рисунок 18. Тройка-модуль с Bluetooth

В качестве отпирающего/запирающего механизма был выбран соленоид. Но он питается от 12В, а Arduino питается и выдает 5В. Для питания соленоида были куплены 8 батареек по 1,5 вольта, батарейный отсек и силовой ключ на базе Mosfet-транзистора для подключения.

Рисунок 19. Соленоид

К подвижной части замка прикреплен магнит, а на Arduino установлен Геркон через стягивающий тройка-модуль. Он фиксирует текущее положение магнита, идентифицирую тем самым состояние замка.

3.5 Клиент-серверное взаимодействие

Сервер и клиент общаются с помощью Rest API. Rest API на сервере реализовано с помощью Rest Controller.

На клиенте запросы посылаются через Alamofire. За работу с сервером отвечает класс ApiService. Он хранит конфигурации и реализует запросы для модулей, где не используется Rx. В модулях, где используется RxSwift, запросы происходят в Service классах с помощью RxAlamofire. Пример запроса:

private func getRidesFromServer() -> Observable<[RideViewModel]> {

let observable = apiService.sessionManager.value.rx.request(.get, ApiService.serverURL + "/api/rides/all", parameters: nil)

.data()

.flatMap { data -> Observable<[RideViewModel]> in

guard let rides = try? self.apiService.jsonDecoder.decode([RideViewModel].self, from: data) else {

return Observable.error(BSError.parseError)

}

return Observable.just(rides)

}

return observable.do(onNext: { viewModels in

self.coreDataManager.saveRide(viewModels: viewModels)

}).catchErrorJustReturn(coreDataManager.fetchRides().map({ $0.viewModel }))

}

После получения и обработки данных генерируется Observable, на который впоследствии подписываются View классы. С сервера приходит JSON, который парсится с помощью JSONDecoder в структуры *ViewModel. Параллельно происходит запись в Core Data с помощью Side Effect [11].

Обработка этого запроса на сервере:

@GetMapping("all")

public List<Ride> getRides(@RequestHeader(value = "BS-User") String userId) {

return rideRepo.findByUser(Long.parseLong(userId));

Идентификатор пользователя передается в каждом запросе в хедере запроса.

В некоторый модулях использование Rx избыточно, поэтому и запросы делаются с помощью простого Alamofire. Пример:

func payRequest(token: STPToken, amount: Double, completion: @escaping (Error?)->()) {

let headers: HTTPHeaders = [

"Content-Type" : "application/json",

"Accept": "application/json"

]

let body: [String : Any] = ["token": token.tokenId,

"cost": amount,

"description": "Поездка",

"currency": "RUB"

]

sessionManager.value.request(ApiService.serverURL + "/pay", method: .post, parameters: body, encoding: JSONEncoding.default, headers: headers).validate(validate).response(completionHandler: { response in

print(String(data: response.data!, encoding: .utf8))

completion(response.error)

})

}

3.6 Тестирование

Подробное описание процесса тестирование требований и полного тестирования находится в Приложении «Методика тестирования и испытания».

Для тестирования другими пользователями приложения было загружено в Testflight.

Выводы по главе

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

Заключение

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

Для достижения этого выполнены следующие задачи:

1. Проведен анализ предметной области и аналогов приложений для шеринга.

2. Разработаны функциональные требования к системе, описанные в Приложении «Техническое задание».

3. Проанализированы существующие подходы к архитектуре мобильных приложений и сервера и выбрана наиболее подходящая из них

4. Разработан дизайн мобильного приложения

5. Реализована серверная часть в соответствии с поставленными требованиями с Rest API и панелью администратора.

6. Реализовано мобильное приложение с возможностью поиска и аренды велосипедов.

7. Реализован прототип замка на Arduino

8. Компоненты объединены в одну систему: пользователь управляет системой через мобильное приложение, которое получает информацию с сервера через Rest API, и разблокирует замок, используя Bluetooth.

9. Разработана техническая документация

На момент написания выпускной квалификационной работы сервер с базой данных опубликован на хостинге Heroku, а мобильное приложение в TestFlight. Дальнейшее развитие включает разработку промышленной версии замка на базе печатной платы, разработку Android-приложения и поиск инвестора/владельца велосипедов для реализации проекта в городах.

Источники

1. "China's bicycle-sharing giants are still trying to make money", The Economist, 2018. [Online]. Available: https://www.economist.com/business/2017/11/25/chinas-bicycle-sharing-giants-are-still-trying-to-make-money. [Accessed: 2- Nov- 2018].

2. Apple Documentation, developer.apple.com, 2018. [Online]. Available: https://developer.apple.com/. [Accessed: 02- Nov- 2018].

3. Arduino, Arduino.cc, 2018. [Online]. Available: https://www.arduino.cc/. [Accessed: 02- Nov- 2018].

4. Core Data [Электронный ресурс] / Apple. Режим доступа: https://developer.apple.com/documentation/coredata/, свободный. (дата обращения: 05.02.19).

5. Google map web components [Электронный ресурс] / webcomponents. Режим доступа: https://www.webcomponents.org/element/GoogleWebComponents/google-map/elements/google-map-poly, свободный. (дата обращения: 15.04.19).

6. Hibernate Documentation [Электронный ресурс] / Hibernate. Режим доступа: https://hibernate.org/, свободный. (дата обращения: 05.04.19).

7. Mobike | Smart Bike Share, Mobike.com, 2018. [Online]. Available: https://mobike.com/global/. [Accessed: 22- Nov- 2018].

8. Model-View-Controller [Электронный ресурс] / Apple. Режим доступа: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html, свободный. (дата обращения: 02.02.19).

9. ofo, Ofo.com, 2018. [Online]. Available: https://www.ofo.com/. [Accessed: 22- Nov- 2018].

10. Project Lombok Documentation [Электронный ресурс] / Project Lombok. Режим доступа: https://projectlombok.orgсвободный. (дата обращения: 05.04.19).

11. Side effect [Электронный ресурс] / Introduction to Rx. Режим доступа: https://introtorx.com/Content/v1.0.10621.0/09_SideEffects.htmlсвободный. (дата обращения: 14.02.19).

12. Swift [Электронный ресурс] / Apple. Режим доступа: https://apple.com/ru/swift/, свободный. (дата обращения: 01.02.19).

13. Troyka slot shield V2 [Электронный ресурс] / Амперка. Режим доступа: https:// amperka.ru/product/arduino-troyka-slot-shield?utm_source=man&utm_campaign=troyka-gps-glonass&utm_medium=wikiсвободный. (дата обращения: 05.05.19).

14. Troyka-модули [Электронный ресурс] / Амперка. Режим доступа: https://wiki.amperka.ru/troyka-modules/, свободный. (дата обращения: 05.05.19).

15. Vaadin [Электронный ресурс] / Vaadin. Режим доступа: https://vaadin.comсвободный. (дата обращения: 05.04.19).

16. Velobike, 2018. [Online]. Available: https://velobike.ru. [Accessed: 22- Oct- 2018].

17. Архитектурные паттерны в iOS [Электронный ресурс] / Habr. Режим доступа: https://habr.com/ru/company/badoo/blog/281162/, свободный. (дата обращения: 05.02.19).

18. Операционные системы (мировой рынок) [Электронный ресурс] / Tadviser. Режим доступа: http://www.tadviser.ru/index.php/Статья:Операционные_Системы_(мировой_рынок), свободный. (дата обращения: 02.02.19).

Размещено на Allbest.ru

...

Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.