[Из песочницы] История разработки приложения для создания квестов под iOS

Зарождение идеи Скажу сразу — изначально не планировалось, что идея пойдет в массы. Но как только жизнь не складывается…Итак, идея родилась еще осенью 2013 года. Близился день рождения моей девушки и мне хотелось придумать какой-нибудь необычный, креативный и нематериальный подарок.

От друга я почерпнул идею — квест по городу. Накидал план, придумал подсказки и т.д., однако оказалось, что не все так просто: • Во-первых, нужно каким-то необычным образом уведомить девушку о подарке. Можно было, конечно, просто вручить ей конверт с инструкциями, но это было бы слишком просто.• Во-вторых, на каждом этапе должна находиться подсказка для перехода на следующий. Где и как эти подсказки размещать — вопрос (вариант с конвертом, как я уже говорил, мне категорически не нравился)/• В-третьих, создание квеста превращалось в достаточно трудоёмкий процесс, требующий много времени.

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

Через полгода вышел Swift — новый язык программирования от Apple. Отзывы были положительные, синтаксис мне очень. Это мотивировало меня на изучение данного языка. И тут я вспомнил про квест… картинка сложилась сама собой.

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

Функционал Необходимо было обеспечить несколько возможностей в приложении:1. Создание квеста, состоящего из нескольких этапов, каждый их которых включает в себя задание с ответом в одной из трех форм — число, строка, дата.2. Прохождение квеста.2. Хранение списка друзей.3. Возможность отправки созданного квеста другу.

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

Разработка. Начало Всё было достаточно просто: несколько TableView с квестами и их этапами, запись всего этого дела в CoreData и контроллер для прохождения этапов.Затруднения при разработке вызвала необходимость добавления друзей: список нужно было где-то хранить и не локально, а на удаленном сервере.

Изучив форумы и статьи, я решил арендовать VPS сервер, тем более что стоимость такой услуги не очень велика. На нём стоял Debian 7. Немного танцев с бубнами и сервер был настроен. В базу MySql были добавлены необходимые таблицы для хранения списка пользователей и отправленных квестов.

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

Для выполнения HTTP запросов из XCode был выбран модуль фремворка Swifter (который к слову нужен для отправления твитов). Написан он целиком на Swift и для меня вполне подошел.

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

f1d232ce33974bbc80e160e629e77836.PNG

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

c4b578fa87d04570ace9734a7d7d23f2.PNG

При отправке квеста нужно было указать получателя из списка друзей, после этого на сервере выполнялся PHP-скрипт, который создавал (или обновлял) в MySQL необходимые записи. Оставалось только ждать, пока твой друг скачает его. Это неплохо. Но, во-первых, друг вообще может не увидеть, что ему пришел квест. А, во-вторых, если квест нужно было выполнить в режиме «срочно», то ожидание — не очень подходящий вариант. Здесь в помощь мне пришли Push Notifications.

Push notifications

Это небольшое прямоугольное окно-уведомление появляющееся в верхней части экрана. Его плюс в том, что можно оперативно уведомлять человека о чем-либо, при этом программа не обязательно должна быть запущена: главное, чтобы был Интернет. Например, друг отправил мне квест, и я смогу сразу получить уведомление об этом. С помощью Local notifications такого сделать не получится, так как там привязка идет к определенному, заранее рассчитанному времени.

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

Схема работы выглядела так:

Был некий vps сервер, на котором находился php демон (служба, которая работает в фоновом режиме и выполняет запрограммированные действия). Термин «демон» уходит корнями к «демону Максвелла», который сортировал молекулы в мысленном эксперименте. Здесь же он сортировал записи в таблице.

Вариантов написания этих демонов очень много, в данном случае был выбран однопоточный php демон.

Каждые 10 секунд он выполнял соединение с базой MySql и проверял таблицу Notifications (созданная таблица с пятью колонками: id, дата, отправитель, получатель и текст) на наличие новых записей. Обнаружив новое, он отправлял его на сервер уведомлений Apple, который в свою очередь обрабатывал его и отправлял уже на устройство получателя. Для отправки оповещения использовал библиотеку NotificationPusher, которая работает еще и с устройствами на Android.

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

Если пользователь удалял программу или менял аккаунт, то я действовал соответствующим образом и с его token-ом.

Есть еще одна небольшая особенность push notifications — они работают только когда приложение свернуто. Если же приходит оповещение с сервера, когда приложение активно, то просто вызывается предопределенная процедура, в которую передаются параметры уведомления. Используя переданные параметры, можно открывать самописное окошко с текстом, отправителем и… чем угодно.

Чтобы протестировать работу всего этого «чуда», необходимы реальные устройства, на эмуляторе работать не будет. Причем, если вы устанавливаете Developer версию приложения на устройство, то и сертификат для работы уведомлений должен быть Developеr, а если используете TestFlight, то нужен Distribution сертификат.

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

b01ee9b28b8b47e8b3e071733a9b0046.PNG7dd14569b6824f4a963e78e0442b0f83.PNG

iBeacons

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

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

iBeacons можно использовать при создании этапов. Например, установить маячок где-нибудь в городе, из настроек этапа указать его UUID, major и minor. Человек будет искать его, используя приложение. Это было бы достаточно интересно с точки зрения интерактивности.

Сразу встал вопрос: как с этими маячками работать? Необходим был какой-нибудь образец для тестирования. Оказалось, на рынке представлено огромное количество Beacons разных по форме, длительности работы, дальности обнаружения и, разумеется, цене. Я попытался найти объявления о продаже на Avito, но, увы, не нашел. Благо на всемогущем Ebay нехватки в предложениях не было, и я заказал один маячок, который пришел в течение нескольких недель.

Пришедший маяк хоть и оказался работоспособным, но, во-первых, к нему надо было покупать батарейку (стоимость которой составила 300 рублей), а во-вторых, он через неделю перестал работать.

Решил сделать вторую попытку и заказал их напрямую у производителя. Выбрал компанию Minew из-за стоимости маячков — 16 долларов (на тот момент в пересчете на рубли сумма составила чуть больше 600 рублей) и силиконового кейса. Радиус действия 70 метров, батарейка в комплекте и время работы 2 года также были значительными преимуществами перед остальными поставщиками. Связался с менеджером, запросил несколько тестовых образцов и стал ждать.

Посылка с 3 маячками пришла через полторы недели. Красивый и приятный на ощупь кейс, батарейка действительно была в комплекте. Скачал приложение для тестирования и программирования маячков LightBlue, подключился — все работает. К слову, чтобы поменять какой-либо параметр (например, идентификатор маячка, major или minor), нужно ввести новое значение для параметра в hex формате и в таком же формате ввести пароль. Нажимаем кнопку Save, забываем устройство, заново подключаемся к нему и вуаля: все сохранилось.

За пару дней встроил в приложение «Найти маячок» в качестве нового вида этапа.

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

e928181e6c22413fb908e65981fc9ed5.PNG7accb5bf932048e8935f28c0c963f030.PNG

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

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

Kickstarter

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

Для граждан РФ, к сожалению, процесс публикации очень сильно осложнен…точнее, отсутствует вовсе. Чтобы опубликовать свой проект, нужно быть резидентом одной из стран: США, Великобритании, Канады, Австралии, Новой Зеландии, Даннии, Норвегии, Швеции, Ирландии или Нидерландов.

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

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

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

После того как проект завершится, и если он будет удачным (т.е. соберет необходимую сумму), то деньги отправляются им на счет (за вычетом комиссий Kickstarter и Amazon Payments, разумеется). После вычета своего процента, указанного в договоре, агент пересылает деньги уже на ваш счет.

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

Но это совсем другая история.

© Habrahabr.ru