Разработка приложений

Курсовая работа

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

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

В настоящее время существует два языка программирования, которые используются для разработки приложений на данной платформе: Objective-C и Swift. Возможно использование и других языков, на которых можно вести р а з р а б от ку п од д а н н у ю п л ат ф о рм у, н о в с е о н и п р ед п ол а г а ют кроссплаформенность, которая напрямую не поддерживается компанией Apple, разработавшей мобильную операционную систему iOS. Практическая часть курсовой работы написана на языке Swift, вышедшем в 2014 году, как замена Objective-C. Надо отметить, что разработка на Objective-C все еще возможна и в некоторых случаях более предпочтительна, чем на вышедшем ему на замену Swift.

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

U3

В целях написания написания приложения, позволяющего добавлять заведения общественного питания на карту, была выбрана архитектура VIPER, картографический сервис Google Maps, облачные технологии Firebase, фреймворк Core Data.

U4

1 Описание основных компонент, составляющих приложение на

платфоме iOS

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

25 стр., 12274 слов

Создание мобильного приложения для организации

... приложение запущено. мобильный информационный интерфейс Пользовательский интерфейс приложения должен быть нативным для платформы Android и соответствовать основным рекомендациям по разработке приложений ... задачей. Целью данной дипломной работы является создание мобильного приложения для организации информационного обмена ... средствах таких как Яндекс. Карты, Google Maps и другие; - добавления ...

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

Модель, за счёт независимости от визуального представления, может иметь несколько различных представлений для одной «модели»

Представление отвечает за получение необходимых данных из модели и отправляет их пользователю. Представление не обрабатывает введённые данные пользователя.

Представление может влиять на состояние модели, сообщая модели об этом.

Контроллер обеспечивает «связи» между пользователем и системой. Контролирует и направляет данные от пользователя к системе и наоборот. Использует модель и представление для реализации необходимого действия.

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

Интерактор — сервисный объект, который создает абстракцию над небольшой областью знаний(модель предметной области) и инкапсулирет бизнес-логику приложения. Для этого можно использовать некоторые сервисы и менеджеры, которые рассматриваются скорее как внешние зависимости, а не как часть модуля VIPER.

U5

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

U6

2 Обзор основных архитектурных паттернов, используемых в iOS

приложениях

Чтобы начать разрабатывать какое-либо приложение, нужно определиться с выбором архитектуры, подходящей под решение конкретной задачи. Далее будет приведен список наиболее часто используемых при разработке под платформу iOS архитектур и будут даны их сравнительные характеристики.

MVC(model-view-controller)

Рисунок 2.1 – Схема приложения, использующего концепцию MVC

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

U7 относительно небольшое количество строк кода и не будет содержать большое количество бизнес-логики. Сущесвует проблема, носящая название Massive View Controller. Она состоит в том, что при использовании лишь трех компонент: модели, представления и контроллера, возможен случай работы с бизнес-логикой в контроллере. Также, существенный минус данного подхода при разработке, это сложность написания Unit тестов из-за того, что контроллер тесно связан с View.

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

MVP(model-view-presenter)

37 стр., 18434 слов

Проектирование Базы Данных для коммерческого предприятия

... разработки баз данных и возможностях применения их. Мы рассмотрим кратко пять таких приложений. 1.База данных Системы ... любое приложение способно работать со многими форматами представления данных, осуществлять экспорт и импорт данных благодаря ... баз данных различных моделей — постреляционных, объектно-реляционных, XML. Если постарался классифицировать существующие области применения баз данных, ...

Рисунок 2.2 – Схема приложения, использующего концепцию MVP

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

U8

Так как большая часть бизнес-логики не взаимодействует напрямую с представлением, использование MVP повышает тестируемость кода. Ответсвтвенность распределена между представителем и моделью, а представление играет роль максимально пассивного компонента. Количество кода, требуемого для написания программного продукта намного больше, чем при использовании MVC. Но при этом, сохраняется простота написания кода, и разработчики получают возможность покрыть куда больший процент программы Unit тестами.

VIPER(view-interactor-presenter-entity-router)

Рисунок 2.3 – Схема приложения, использующего концепцию VIPER

U9

VIPER — это подход к архитектуре мобильных приложений (в частности iOS), основанный на идеях Роберта Мартина, изложенных им в статье The Clean Architecture.

Используя данный подход при создании нового модуля-экрана, разработчику нужно будет создать пять классов: Assembly, ViewController, Presenter, Interactor, Router.

Так как Swift – protocol oriented язык, то будет необходимо также создать пять протоколов: ViewInput, ViewOutput, InteractorInput, InteractorOutput, RouterInput

Рисунок 2.4 – Схематичное изображение Clean Architecture

U10

При использовании данной архитектуры, приложение делится на пять модулей. Это уже знакомые по архитектурам MVC и MVP модель, представление, представитель, к которым добавляются компоненты интерактор и роутер. Ответственность между компонентами распределена более явно, сложность тестируемости приложения уменьшена по сравнению с MVC и MVP. Отличие от приведенных выше архитектур заключается в том, что работа с бизнес-логикой осуществляется в интеракторе, вместо Model теперь Entity, представляющее собой структуры данных без какой-либо логики. VIPER предполагает использвание роутера для навигации между модулями в приложении.

К плюсам использвания архитектуры VIPER можно отнести:

1) Распределение обязанностей. Среди рассмотренных ранее архитектур, VIPER имеет наибольшее число компонент, что позволяет распределять обязанности в приложении наиболее явно.

2) Т е с т и р у е м о с т ь . И з — з а л у ч ш е г о р а с п р е д е л е н и я обязанностей,компоненты легче тестировать.

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

U11

3 Core Data

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

26 стр., 12757 слов

Проектирование и разработка базы данных ‘Магазин продажи одежды’

... при пользовании данным приложением. 1. Анализ предметной области Задачей курсовой работы является проектирование и разработка базы данных «Магазина продажи одежды». Особенности: Введение данных в БД осуществляется с ... что, следовательно, доказывает нам то, что данная модель данных находится в третьей нормальной форме. Данные правила также соблюдены для остальных описанных таблиц. Таблица 2.2 - ...

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

Core Data — фреймворк от компании Apple, встроенный в операционную систему iOS, MacOS, который позволяет разработчику взаимодействовать с базой данных. Был представлен компанией Apple c анонсом Mac OS X 10.4 Tiger и iOS с iPhone SDK 3.0. Позволяет данным быть организованными в Сущность-Атрибут-Значение (EAV).

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

Структура фреймворка:

1) Managed Object Context — компонент с которым идет взаимодействие, каждый раз, когда идет сохранение или перезапись.

2) Persistent Store Coordinator — выполняет цель хранения данных.

3) Managed Object Model — модель базы данных.

4) Persistent Store — репозиторий, где хранятся данные.

Сore Data описывает данные, которые хранятся в iOS приложении, код для сохранения и записи данных в приложении. Модель БД создается в Interface Builder. Код пишется на Objective-C или Swift. Core Data организован в классы с разной ответственностью.

Суть работы фреймворка, как внутренней БД проста: создание модели, и при добавлении новых элементов, сохранение с помощью метода saveContext(); в модель.

U12

Рисунок 3.1 – Структура Core Data

Главная цель данного фреймворка — хранение данных, есть также и похожие: Realm, SQLite.

Core Data может конвертировать данные в XML, бинарный код, SQLite для хранения. Core Data схемы стандартизированы.

U13

Если на компьютере не установлен Xcode, то возможность прочитать модель данных есть.

Несмотря на то, что Core Data может хранить данные в реляционной базе данных вроде SQLite, Core Data не является СУБД. Core Data в качестве хранилища может вообще не использовать реляционные базы данных. Core Data скорее является оболочкой/фрэймворком для работы с данными, которая позволяет работать с сущностями и их связями (отношениями к другим объектами), атрибутами, в том виде, который напоминает работы с объектным графом в обычном объектно-ориентированном программировании.

Рисунок 3.2 – Различные классы Core Data и описание их роли

Управляемая объектная модель (managed object model) олицетворяет модель данных приложения. Несмотря на то, что Core Data не является базой данных, можно сравнить управляемую объектную модель (managed object model) со схемой базы данных, то есть, она содержит информацию о моделях или сущностях графа объекта, какие атрибуты они имеют, и как они связаны друг с другом.

U14

Объект NSManagedObjectModel узнает о модели данных путем загрузки одного или нескольких файлов модели данных во время инициализации.

Как и говорит его название, объект NSPersistentStoreCoordinator сохраняет данные на диск и гарантирует, что постоянное хранилище(-а) и модель данных являются совместимыми. Это посредник между постоянным хранилищем(-ами) и контекстом(-ами) управляемого объекта, также он заботится о загрузке и кэшировании данных. Core Data имеет встроенный механизм кэширования.

126 стр., 62509 слов

Модели панельных данных для групп складских запасов торгового ...

... некоторые неудобства. Большинство моделей панельных данных оценивается либо в предположении фиксированных эффектов. [7, c.499] 1.2 Модель с фиксированными эффектами Модель с фиксированными эффектами ... построена регрессионная модель по панельным данным наиболее важных для изучения групп товаров. 1. Модели основанные на панельных данных 1.1 Преимущества панельных данных Множество данных, состоящих из ...

Координатор постоянного хранилища — это дирижер Core Data. Несмотря на свою важную роль в стеке технологий Core Data, программист редко взаимодействует с ним напрямую.

Объект NSManagedObjectContext управляет коллекцией объектов модели, экземплярами класса NSManagedObject. Приложение может иметь несколько контекстов управляемого объекта. Каждый контекст управляемого объекта опирается на координатор постоянного хранилища.

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

Инструмент Fetched Results Controller позволит отслеживать изменения, произошедшие с объектами модели, а также удобно преобразует извлеченные данные в элементы UITableView.

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

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

Объект NSPersistentStoreCoordinator — это мозг стека Core Data в приложении. Он общается с одним или более постоянных хранилищ и гарантирует сохранение, загрузку и кэширование данных.

U15

Координатор постоянного хранилища знает о модели данных (схеме графа объектов) через объект NSManagedObjectModel.

Управляемая объектная модель создает модель данных приложения из одного или нескольких .momd-файлов, двоичного (бинарного) представления модели данных.

Приложение обращается к графу объектов посредством одного или нескольких экземпляров класса NSManagedObjectContext. Контекст управляемого объекта знает о модели данных посредством координатора постоянного хранилища, но он не хранит ссылку на управляемую объектную модель. Необходимость в такой ссылке отсутствует.

Контекст управляемого объекта запрашивает данные у координатора и говорит ему, когда необходимо их сохранить. Все это делает Core Data, приложению довольно редко нужно будет общаться напрямую с координатором постоянного хранилища.

U16

4 Объектно-ориентированная база данных Realm

Realm отличается от других аналогичных библиотек, тем что рассматривает объекты данных как живые объекты — это значит, что объекты обновляются синхронно. Они мгновенно реагируют на изменения и легко сохраняются. Программисту не приходится изучать диаграммы которые есть в сценариях Core Data или SQLite. Вместо этого можно работать по настоящему объектно-ориентированным способом. Мобильная база данных Realm распространяется с открытым исходным кодом с 2016 года и бесплатна для разработчиков.

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

6 стр., 2737 слов

Анализ объектов уникальных и гениальных зданий и сооружений, ...

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

Мобильная платформа Realm, расширена синхронизацией данных в реальном времени и обработкой событий на стороне сервера, которые встроены в приложение. Разработчики используют платформу для создания приложений с мощной функциональностью, такие как мессенджеры, приложения для совместной работы и приложения с оффлайн функционалом. Платформа идеально подходит для адаптации под мобильные устройства существующих API, что позволяет легко создавать удобные и мощные приложения подключённые к устаревшим системам и сервисам. (realm.io)

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

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

U17 объекту без необходимости управлять блокировкой или каких-либо проблем с несогласованностью данных.

Мобильная база данных Realm предлагает службы шифрования для защиты базы на диске с помощью AES-256 + SHA2 64-разрядного шифрования. Это позволяет все данные, хранящиеся на диске зашифровывать и расшифровывать с помощью алгоритма AES-256 и проверять с помощью технологии HMAC SHA-2. Ключ шифрования должен быть сгенерироан каждый раз, когда вы получаете экземпляр Realm.

В отличие от основных данных, мобильная база данных Realm действительно кроссплатформенная и поддерживает iOS, Android, JavaScript веб-приложения и Xamarin.

Тем способом которым работают живые объекты, программист может присоединить элементы пользовательского интерфейса к модели данных и интерфейс будет обновлён реактивно как и изменения в данных. Здесь нет сложного кода синхронизации или путей логики, необходимых, как если бы работа была с Core Data.

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

R e a l m и м е е т м н о гоч и с л е н н ы х к л и е н то в , кото р ы е от к р ы то применяют мобильную базу данных Realm, среди них Netflix и Starbucks.

Мобильная база данных Realm – решение не только для работы в памяти приложений. Решение, которое было схоже с мобильной базой Realm это Google Firebase — хотя это комбинированное решение клиента и сервера. Firebase так же прост в использовании и позволяет начать работу бесплатно, но расходы будут возрастать пропорционально использованию ресурсов.

U18

Основные особенности Realm объектов:

1) Получение объектов из базы очень быстрое, десериализации как таковой нет, чтение с диска происходит только при обращении к конкретному полю.

9 стр., 4131 слов

Разработка ASP.NET приложения с нестандартными WEB – элементами управления

... развития дальнейших технологий. В данной курсовой работе описана разработка ASP.NET приложения с использованием технологии AJAX. §1. ... с Web-приложением. Данные о сеансе работы каждого отдельного пользователя сохраняет объект session. Объект application используется ... объекта respons: AddHeader – устанавливает заголовок HTML имя равным значению. AppendToLog – добавляет строку в конец записи журнала веб ...

2) Именно для этого существует требование делать все поля приватными и обращаться через геттеры.

3) Метод copyFromRealm() — позволяет получать отвязанные, полностью собранные объекты, прямо как обычная ORM. На вход принимается глубина десериализации, по умолчанию MAX_INT.

4) В дебагере все поля будут null. Для получения какого-либо значения нам нужно обращаться через геттер.

5) Все объекты Live, т.е живые. Изменения распространяются моментально в рамках одного потока.

6) Фильтрация объектов осуществляется по полям, причем названия полей программист указывает руками в виде строки. Например так: .equalTo(«id», 1).

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

7) Любой объект доступен только пока открыт instance realm-a, из которого мы его получили. Проверять можно методами isValid. При обращении к невалидному объекту получим исключение.

8) Объекты доступны только в том потоке, в котором созданы. Обращаться из другого потока нельзя, получим исключение.

9) Получение списков очень быстрое, но мы получаем только count. Все запросы lazy, получить большой список из сложных объектов мы можем очень быстро.

10) Списки доступны только для чтения, любые методы изменения приводят к исключению.

11) Т.к. мы можем быстро и дешево получать все элементы, можно забыть о проблеме пагинации. Мы всегда отдаем полный список элементов, при

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

Работая с Realm мы всегда имеем ввиду стандартный realm, однако существуют еще In-Memory Realm и Dynamic Realm.

Стандартный Realm — можно получить методами Realm.getDefaultInstance() или с помощью конкретной конфигурации Realm.getInstance(config), конфигураций может быть неограниченное количество, это по сути отдельные базы данных.

In-Memory Realm — это Realm, который все записанные данные хранит в памяти, не записывая их на диск. Как только мы закроем этот instance, все данные пропадут. Подходит для кратковременного хранения данных.

Dynamic Realm — используется в основном при миграции, позволяет работать с realm — объектами без использования сгенерированных классов RealmObject, доступ осуществляется по именам полей.

Realm не поддерживает наследование. Любой realm-объект должен или наследоваться от RealmObject или реализовывать интерфейс маркер RealmModel и быть помеченным аннотацией @RealmClass. Наследоваться от существующих Realm объектов нельзя. Рекомендуется использовать композицию вместо наследования.

Realm отлично подходит для MV* архитектур, когда вся реализация прячется за интерфейсом базы данных. Все обращения и выборки происходят в модуле базы данных (repository), наверх отдаются Observable c автоматически закрываемым realm при unsubscribe. Или принимаем на вход instance realm и производим все действия с ним. При записи объектов мы открываем realm, записываем данные и закрываем его, на вход подается только объект для сохранения.

11 стр., 5200 слов

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

... устройстве. Платформа является результатом сотрудничества Google и JetBrains, рекомендована сообществом Android-разработчиков [1] для разработки мобильных приложений. ... Разработка мобильных приложений под Android на сегодняшний день очень востребована ввиду высокой популярности данной ОС. Посетители заведений общественного питания с обслуживанием (кафе, рестораны и т.д.), посещающие заведения ...

Использование Realm (без copyFromRealm) накладывает серьезные ограничения на использование clean architecture. Использовать разные модели данных для разных слоев не получится, пропадает весь смысл live объектов и

U20 прокси списков. Также сложности возникнут при создании независимых слоев и открытии\закрытии Realm, тк эта операция привязана к жизненному циклу Activity\Fragment. Хорошим вариантом будет изолированный слой получения данных, преобразование объектов и сохранение их в базе данных.

Realm очень удобен при построении offline-first приложений, когда все данные для отображения мы получаем из базы данных.

Realm сложнее, чем кажется на первый взгляд. Однако все недостатки с лихвой покрываются его мощностью и удобством. Live объекты, нотфикации и Rx, удобное API и множество других вещей упрощают создание приложений. Из конкурентов можно выделить requery, ObjectBox и GreenDao. Полностью же Realm раскрывает себя при построении offline-first приложений, когда все данные мы получаем из кэша и нам необходимы сложные выборки, а также постоянное обновление данных.

Рисунок 4.1 – Сравнение скорости записи в базу с другими СУБД

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

U21 преимущества и причины, почему использование Realm является лучшим выбором при работе с базой данных в мобильном приложении:

1) простая установка;

2) быстрая: Realm — невероятно быстрая библиотека для работы с базой данных. Realm быстрее, чем SQLite и CoreData;

3) кросс-платформенная: файлы базы данных Realm кроссплатформенные и могут совместно использоваться iOS и Android;

4) масштабируемая: масштабируемость очень важно рассмотреть при разработке мобильного приложения, если приложение работает с большим количеством пользователей и большим количеством записей. Разработчик должен учесть это с самого начала при проектировании и выборе инструментов. Realm готова к масштабируемости и работе с большими объемами данных в кратчайшие сроки;

5) хорошо документированная и есть отличная поддержка: команда Realm предоставила читаемую, хорошо организованную документацию о Realm;

6) надежная – Realm используется компаниями в мобильных приложениях, как Pinterest, Dubsmash, и Hipmunk, Starbucks;

7) бесплатная.

U22

5 Картографический сервис Google Maps

С помощью Google Maps SDK for iOS можно добавлять в свое приложение карты на основе данных Google Maps. Пакет SDK автоматически управляет доступом к серверам Google Maps, отображением карты и реакцией на действия пользователя (например, на нажатия и перетаскивания объектов).

На карту можно добавлять маркеры, ломаные линии, наземные наложения и информационные окна. Эти объекты предоставляют дополнительную информацию о местоположениях на карте и обеспечивают возможности взаимодействия пользователей с картой. При написании приложения была использована стандартная карта Google Maps, которая отображает дороги, некоторые объекты, построенные людьми и важные природные объекты, например, реки. Также отображает метки дорог и объектов.

7 стр., 3168 слов

Разработка базы данных информационной системы для автоматизации ...

... области были выбраны следующие виды расчетов для автоматизации движения денежных средств через кассу: расчетные поручения, расчеты по аккредитивам, ... таблице «Расчеты по чекам» По данным таблицам были созданы 3 отчета, которые представлены в приложениях А, Б и В. Рисунок ... этих запросов были созданы отчеты. Они представлены в приложениях Г и Д. Заключение Проанализировав безналичные формы отчетности ...

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

U23 Рисунок 5.1 – Стандартная карта Google Maps

U24

6 Обзор Firebase

Firebase предоставляет облачную NoSQL БД для real-time приложений как сервис. Данный сервис предоставляет API для разработчиков, позволяющий синхронизировать данные приложения между клиентами и хранить их в облаке Firebase.

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

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

Рисунок 6.1 – Панель Аuthentication

Существует возможность управлять Realtime Database внутри консоли, предоставляемой сервисом. Например, исходя из поставленной задачи, можно добавлять заведения вручную, редактировать поля сущностей, удалять сущности. Данные в базе данных хранятся в виде JSON(JavaScript Object Notation).

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

U25

Рисунок 6.2 – Панель Database

Вопросами безопасной передачи, модификации данных занимается Firebase Realtime Database Security Rules – язык правил, с помощью которых можно указать, какими правами в области базы данных может обладать пользователь. Например, доступ к базе данных может предоставляться только зарегестрированным пользователям.

U26

Рисунок 6.3 – Панель Storage

Firebase Storage позволяет хранить файлы, например, фото или видео, на серверах Google. При выполнении работы возникла необходимость хранения фотографий заведений, с чем с легкостью справляется Firebase Storage.

U27

7 Разбор сторонних библиотек, использованных в работе

В качестве менеджера завиcимостей был использован CocoaPods, который содержит более 40 тысяч библиотек, находящихся в свободном доступе. Для того, чтобы добавить зависимости, в корне проекта должен находиться Podfile, в котором указывается список необходимых проекту библиотек.

Рисунок 7.1 – Содержимое Podfile

U28

Для того, чтобы создать Podfile, необходимо выполнить команду pod init из консоли в корне проекта. После создания файла, необходимо добавить в него необходимые зависимости, после чего выполнить команду pod install. Следует обратить особое внимание на раздел Dependency management в Podfile. Для начала стоит ознакомиться с паттерном Dependency injection и обосновать необходимость его использования в проекте.

Внедрение зависимостей – процесс предоставления внешней зависимости программному компоненту. Данных подход позволяет четко указывать, какие зависимости нужны конкретному компоненту программы. Зависимости легко изменять под разные сценарии использования модуля программы. Также, улучшается тестируемость проекта за счет того, что нужные компоненту зависимости могут быть заменены Mock-объектами. Mock-объект – в объектно-ориентированном программировании – тип объектов, реализующих заданные аспекты моделируемого программного окружения. Mock-объект представляет собой конкретную фиктивную реализацию интерфейса, предназначенную исключительно для тестирования взаимодействия и относительно которого высказывается утверждение. Mock-объекты активно используются в разработке через тестирование(TDD – Test Driven Development).

Необходимые зависимости регистрируются с использованием шаблона проектирования Одиночка(Singleton).

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

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

Модуль Dip-UI занимается внедрением завистимостей в модули, использующие Storyboads. Stroyboard предоставляtт разработчику удобный механизм разработки интерфейса программы.

U29

Исходный код класса, который занимается внедрением зависимостей: import Dip import DipUI import ViperKit

class ActionsPhotoPreviewModuleAssembly: DipCollectableAssembly { required init() { } func collect(into container: DependencyContainer) {

container.register(tag: nil) { ActionsPhotoPreviewViewController() }

  • implements(ActionsPhotoPreviewViewInput.self, TransitionHandler.self)
  • resolvingProperties { (container, viewController) in

viewController.output = try container.resolve()

}

container.register { ActionsPhotoPreviewPresenterStateStorage() }

container.register { ActionsPhotoPreviewPresenter(view: $0, interactor: $1, stateStorage: $2) }

  • implements(ActionsPhotoPreviewModuleInput.self, ActionsPhotoPreviewViewOutput.self, ActionsPhotoPreviewInteractorOutput.self) container.register { ActionsPhotoPreviewInteractor(photoService: $0) }
  • implements(ActionsPhotoPreviewInteractorInput.self)
  • resolvingProperties { (container, interactor) in

interactor.output = try container.resolve()

} } }

extension ActionsPhotoPreviewViewController: StoryboardInstantiatable {}

U30

8 Unit тестирование компонент iOS приложения

Юнит-тестирование – процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Тест является спецификацией метода класса, контрактом: какие входные параметры ожидает этот метод, и что остальные компоненты системы ждут от него на выходе.

Принимая за выбранную архитектуру приложения VIPER, можно заранее предположить, какие модули программы будут тестироваться. Это Presenter, Interactor, Router, View. Так как сама модель(Entity) не должна обладать какой-либо логикой, она не может быть тестируемой. К примеру, при тестировании модуля Presenter, мы должны проверить, что при вызове функции из исходного модуля, произойдет вызов метода модуля Interactor для получения какой-либо информации, а также параметром метода интерактора будет значение, хранящееся в исходном модуле. В таком случае тест данного сценария может выглядеть так:

func testThatPresenterCallsInteractorToObtainData() {

// given

presenter.info = «test»

// when

presenter.didTriggerViewReadyEvent()

// then

expect(self.interactorMock.invokedObtainData).to(equal(1))

expect(self.interactorMock.invokedObtainDataParameters.info).to(equal(self. presenter.info))

}

Данный тест проверяет число вызовов нужного метода интерактора и параметр, передаваемый этой функции(он должен быть эквивалентен presenter.info в данном примере).

В тестовом классе Presenter присутсвует

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

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

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

U32

9 Promises

Promises – шаблон написания асинхронного кода. Интерфейс Promise (обещание) представляет собой обертку для значения, неизвестного на момент создания обещания. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается обещание получить результат в некоторый момент в будущем.

При создании обещание находится в ожидании (pending), а затем может стать выполненным (fulfilled), вернув полученный результат (значение), или отклоненным (rejected), вернув причину отказа. В любом из этих случаев вызывается обработчик, прикрепленный к обещанию методом then. Если в момент прикрепления обработчика обещание уже сдержано или нарушено, он все равно будет выполнен, т.е. между выполнением обещания и прикреплением обработчика нет «состояния гонки». Данный подход используется во многих iOS проектах, так как существует необходимость совершить какое-либо действие после выполнения участка кода, который может выполниться через произвольное количество времени или не выполниться совсем. Например, при написании практической части работы, возникла необходимость дождаться выполнения блока, отвечающего за получение меток, оставленных на карте, а затем отобразить их. Если при выполнении запроса на сервер возникла ошибка, выполняется блок catch, из которого, например, можно вызвать функцию, сообщающую пользователю об ошибке на стороне сервера.

Исходный код функции, использующей Promises

func getPlaces() {

firebaseService.getPlaces().then { places in

self.output?.didGetPlaces(places: places)

}.catch { _ in

self.output?.didGetPlacesWithError(message: «Не удалось получить ответ от сервера»)

}}

U33

Цепочки операций

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

func getPlaces() {

firstly {

when(authorizationService.authorize())

}.then {

firebaseService.getPlaces().then { places in

self.output?.didGetPlaces(places: places)

}.catch { _ in

self.output?.didGetPlacesWithError(message: «Не удалось получить ответ от сервера»)

}

}

U34

10 Пользовательский интерфейс разработанного приложения

Рисунок 10.1 – Экран авторизации

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

U35

Рисунок 10.2 – Главный экран приложения, отображающий заведения на

карте

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

Исходный код функции, которая занимается получением мест от сервера, а затем добавляет места в постоянное хранилище данных для их отображения без подключения к интернету:

U36 func getPlaces() {

var tempPlaces = [PlaceM]()

firstly {

placesStorageService.obtainPlaces()

}.then { places in

self.output?.didGetPlaces(places: places)

}.then { _ in

self.firebaseService.getPlaces()

}.then { places in

tempPlaces = places

}.then { _ in

self.placesStorageService.update(with: tempPlaces)

}.then { _ in

self.output?.didGetPlaces(places: tempPlaces)

}.catch { _ -> Void in

self.output?.didGetPlacesWithError(message: «Не удалось получить ответ от сервера»)

}

}

Исходный код класса, который занимается хранением полученных от сервера мест в ПЗУ устройства:

class PlacesStorageServiceImp: PlacesStorageService {

private let storageManager: CoreDataManager!

init(storageManager: CoreDataManager) {

self.storageManager = storageManager

}

func obtainPlaces() -> Promise<[PlaceM]> {

return Promise { fulfill, reject in

let request = PlaceMO.createFetchRequest

U37

do {

let viewContext = storageManager.persistentContainer.viewContext

let purchaseModelObjects = try viewContext.fetch(request) as [PlaceMO]

let purchases = purchaseModelObjects.flatMap({ $0.toEntity() })

fulfill(purchases)

} catch {

print(«Failed to fetch purchases from storage»)

reject(error)

}

}

}

func update(with places: [PlaceM]) {

let viewContext = storageManager.persistentContainer.viewContext

viewContext.performChangesAndWait {

for place in places {

_ = PlaceMO.insert(into: viewContext, placeM: place)

}

}

}

}

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

U38

Рисунок 10.3 – Добавление нового заведения на карту

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

U39

Рисунок 10.4 – Страница заведения

На данном экране пользователь видит информацию о заведении. Он также может отредактировать заведение(например, когда данные более не актуальны).

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

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

U40 остается на низком уровне. Это достигается за счет того, что JSON модель при, например, 1000 возвращаемых мест, имеет размер не более 2 мегабайт.

Основная нагрузка на трафик пользователя приходится на экран с информацией о заведении из-за загружаемой из сети фотографии заведения, а также при загрузке фотографии заведения в сеть. Стоит отметить, что загрузка фотографии в сеть выполняется в background thread, что делает возможным загрузку и в том случае, когда пользователь находится на главном экране iOS устройства или в другом приложении.

U41

ЗАКЛЮЧЕНИЕ

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

  • при выполнении работы был проведен анализ паттернов проектирования и была использована наиболее подходящая под объем и сложность приложения архитектура VIPER;
  • проведен обзор картографического сервиса Google Maps, предоставляющего необходимое для решения поставленной задачи API;
  • был изучен и использован поставщик облачных сервисов и приложений Firebase, позволяющий синхронизировать данные приложения между клиентами и хранить их в облаке.

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

Приложение поддерживает работу в оффлайне благодаря технологии Core Data.

U42

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

[Электронный ресурс]//URL: https://inzhpro.ru/kursovaya/razrabotka-prilojeniy/