Данное приложение является одним из решений продемонстрировать навыки, полученные в процессе обучения iOS разработки в течении почти 2-х лет. Основной задачей для меня было реализовать основные знания по:
- работе с сервером (получение и парсинг данных, работа c NSURLSession),
- обработка данных и хранение их для оффлайн просмотра в CoreData,
- обработка запросов пользователя в рамках приложения (сортировка и выборка данных из CorData),
- работа с переходами по экранам приложения, анимация и компоновка основных элементов (UIKit), применение паттерну MVC при разработке архитектуры приложения.
На протяжении написания всего приложения я старался придерживаться нативных библиотек от «Apple» и не использовать сторонних фреймворков (кроме раскрывающихся ячеек, - уж очень понравилась реализация).
Пользователю предлагается приложение, являющееся, копией существующего сайта предприятия «Золотое шитье» www.zolotoe-shitvo.kr.ua. С той лишь разницей, что приложение позволяет хранить оффлайн версию контента, помечать просмотренные продукты собственным рейтингом и использовать историю просмотренных товаров.
При входе, пользователю предлагается список категорий на выбор, при выборе категории, открывается экран со списком товаров из данной категории. По выбору ячейки товара, ячейка раскрывается, предоставляя пользователю детальное описание и фотографию изделия. При повторном нажатии на описание, ячейка свернется в прежнюю форму, при нажатии на фотографию, совершится модальный показ нового экрана с полноразмерным представлением товара, полем для выбора оценки товара и возможностью отправить запрос (по почте) или связаться (телефонным звонком) для заказа данного товара. Поле самой фотографии предполагает использование жеста «увеличение/уменьшение», для лучшего отображения всех деталей изделия на фото. При нажатии на поле вне фотографии, экран вернется к списку товаров.
Также, в приложении работает поиск. При открытой определенной категории, поиск совершается по всем товарам в данной категории. Если поиск совершается вне какой-либо категории (на экране списка категорий), то поиск будет делаться по всем товарам, представленным в базе данных. Нижнее меню (UITabBarController) имеет 4 кнопки: «Категории», «О нас», «Контакты» и «Избранное». При нажатии на «Категории», открывается экран со списком категорий, или (если было открыто), выбранная категория. «О нас» - описание деятельности предприятия. «Контакты» - данные для связи и карта для просмотра местоположения. Если нажать на карту, то откроется приложение «Карты» с предложением проложить маршрут к зданию предприятия. «Избранное» хранит в себе 2 секции таблицы: 1 секции показывает все товары, которые были отмечены «звездочкой» (поставлен какой-либо рейтинг), вторая секция отображает историю просмотров, при чем, если просмотр был совершен в течении сегодняшнего или вчерашнего дня, формат времени меняется вместо «07 сентября в 21:08» показывается «сегодня в 21:08».
После LaunchScreen загружается картинка-дубликат с крутящимся activityIndicator и происходит проверка наличия списка всех категорий. Если отсутствует интернет, об этом сообщается во всплывающем alert. Если загрузка приложения происходит впервые, загружается экран «TutorialPageVC» и пользователю показываются основные возможности приложения. Если приложение запускается не первый раз, осуществляется остановка activityIndicator и создается переход на экран «CategoriesVC». При первой загрузке приложения, во время показа гида по возможностям запускается метод «getAllPosts()» и, в цикле, осуществляется проход по каждой категории и фоновой загрузке всех постов в категории с сохранением их в базе данных. Если загрузка не первая, то проверяется дата последнего обновления категории, и, если прошло больше 10 дней, осуществляется проверка новых товаров на сервере.
Показывается список всех категорий. При активации функции поиска, появляется клавиатура, если введен номер, то осуществляется поиск в базе данных по артикулу изделия, если текст, то по наименованию. По нажатии кнопки «Отмена», клавиатура скрывается. Если результат поиска положительный, то показываются ячейки с товарами (класс ProductTVCell), если нет, то возвращаются ячейки с показом наименований категорий (класс CategoriesTVCell). По нажатии на категории осуществляется переход на экран «ProductsVC» или «MetallonitVC», в зависимости, от выбора категории. Для повторного ознакомления с возможностями приложения, добавил кнопку в NavigationBar, по нажатию на которую, появляется алерт с вопросом о повторном просмотре гида. В случае согласия, открывается гид, в случае отказа, алерт исчезает.
Таблица со списком товаров. Ячейка сделана «кастомно» с помощью xib файла (ProductCell.xib), так как, использована дополнительно в таблицу экрана «FavoritesVC». Ячейка имеет функцию раскрытия по нажатию (динамическая высота) и с добавленным распознаванием касания по нажатию на фотографию. Также, для удобства, при нажатии на ячейку, скажем, в конце списка, чтобы увидеть детальную информацию, которая появится при раскрытии ячейки, сделал автоматическое смещение позиции ячейки к началу экрана (верха таблицы). Логика поиска работает так же, как и на экране «CategoriesVC», только поиск осуществляется в рамках заданной категории. Отработана логика появления/скрытия клавиатуры по нотификациям (NSNotification.Name.UIKeyboardWillShow и.UIKeyboardWillHide). При детальном просмотре товара, можно нажать на описание и ячейка свернется обратно, при нажатии на фотографию, осуществится появление экрана «DetailVC». Реализован UIRefreshControl для обновления списка, если загрузка данных этой категории еще не завершена. В случае отсутствия загруженных данных, показывается activityIndicator, с сообщением «Идет загрузка…».
Экран с фотографией изделия (реагирующей на жесты «увеличить/уменьшить»), рейтингом, кнопками «Позвонить» и «Заказать информацию». Фотография (UIImageView) лежит на UIScrollView (класс CustomScroll), который принимает размеры уменьшенной фотографии по свойству «ContentMode» со значением «AspectFit». При загрузке экрана, значения UIImageView пересчитываются, чтобы корректно отобразить рисунок либо по максимальной ширине экрана, либо по высоте. После этого рассчитывается размер UIScrollView. При увеличении фотографии пользователем, UIScrollView свои размеры не меняет, а позволяет передвигать просмотр в обоих направлениях. Рейтинг устанавливает значение от 1 до 5, путем выбора закрашенных звезд. При этом меняется значение свойства сущности в базе данных. По нажатию на кнопку «Заказать информацию», появляется MFMailComposeViewController, который позволяет отправить запрос на почту предприятия с указанием данных товара (наименовании, артикуле и пр.). MFMailComposeViewController возвращает результат MFMailComposeResult отправки письма в качестве алерта. По всем состояниям MFMailComposeResult сообщение для пользователя о результатах отправки письма. По нажатию на кнопку «Позвонить», совершается звонок непосредственно на предприятие.
Экран показа определенных категорий товаров, где описание не столь принципиально и продукты могут быть отображены в виде UICollectionView. UICollectionViewCell создана «кастомно» в отдельном классе (CollViewCell или RaznoeCell, в зависимости от выбранной категории). Текстовое поле статично и показано в UILabel. В случае отсутствия данных скрыто. UICollectionView помещен в UIScrollView для удобства просмотра. В случае отсутствия данных скрыто. В случае отсутствия загруженных данных, показывается activityIndicator, с сообщением «Идет загрузка…».
Экран с описанием деятельности предприятия и его историей. Текст статический, размещен в UITextView. При открытии экрана, если позиция текста не в самом начале, то делается перемещение по тексту к верху экрана.
Экран с контактной информацией. Адрес предприятия является статическим текстом, размещен в UILabel (NSMutableAttributedString). Карта реализована с помощью делегатов MKMapViewDelegate и CLLocationManagerDelegate. В Info.plist внесены запросы на разрешение получение текущего местоположения пользователя для прокладки маршрута к адресу предприятия. По нажатию на карту, открывается приложение «Карты» для совершения данных действий. Кнопки «Написать» и «Позвонить» работают по такому же принципу, как и на экране «DetailVC».
Экран с таблицей. Таблица имеет 2 сворачиваемые секции: «Отмеченные звездочкой» и «История просмотров». Отмеченные звездочкой: отображает список товаров, которые были отмечены рейтингом. История просмотров хранит список всех продуктов, которые были открыты для детального просмотра. В случае, если просмотр совершен менее, чем 2 дня назад, отображается не числовое значение даты, а наречие (вчера или сегодня).
Данный экран является UIPageViewController’ом, в котором реализуется показ возможностей приложения. Данные по каждому PageItem хранятся в массиве тюплов [(String), (String)]. Первое - это имя картинки, второе - текст под ней. При передвижению по экранам, происходит вызов «PageItemVC», куда передается тюпл.
Экран, на котором отображается картинка и текст с описанием. При загрузке, получает тюпл с 2 элементами. Проверяет на nil, и, в случае, если значения есть, реализует отображение данных.