Pull to refresh
0
Touch Instinct
Разрабатываем мобильные приложения

Coin Keeper. iPhone приложение на C#

Reading time 5 min
Views 21K

Вчера разработанное нами приложение Coin Keeper заняло третье место в топе платных приложений русского AppStore.

Интересно то, что мы разрабатывали его не на привычном Objective C, а на C#, используя фреймворки Monotouch и Monodroid.

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



Coin Keeper это приложение для учета личных финансов. Главный экран приложения похож на большой держатель монет. Доходы, кошельки и расходы представлены как стопки. Чтобы зафиксировать трату, достаточно перенести монетку из стопки в стопку. Подробнее вы можете узнать на сайте приложения CoinKeeper.me. Пользователям идея очень понравилась:



Что за зверь Monotouch?

Мы при разработке проектов отдаем предпочтение фреймворкам MonoTouch и MonoDroid.

Эти продукты создала и развивает компания Xamarin во главе с Miguel de Icaza, основателем проектов Mono, Gnome, Ximian и Midnight Commander. С их помощью можно разрабатывать мобильные приложения для iPhone и Android на C#, при этом код компилируется в нативный машинный код и используются родные UI библиотеки платформ.

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

Ну приступим к самому интересному, к грязным техническим подробностям :)

Общая архитектура



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

Причем, DAL и BL можно брать и без изменений копировать в Android и Windows Phone 7 версии, а это около 50% исходного кода!

DAL


Классический для веб-приложений Data Access Layer. Бизнес-логика (BL) для доступа к данным использует только функции этого слоя.

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

BL


Business Logic или бизнес-логика приложения, слой отвечает за:
— создание транзакций, повторяющиеся транзакции, историю транзакций;
— категории и автобюджет (приложение само определяет сколько нужно тратить :) подробнее в разделе Автоматика);
— статистику и отчеты;
— логику накопления на цели;
— транзакции между счетами в разных валютах.

Пользовательский интерфейс использует исключительно объекты бизнес-логики, представленные как статические классы.

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

«Фишки»

Автоматика


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

Автобюджет


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



Предустановленные категории


Вторая удобная мелочь — база категорий. Мы собрали в приложении 100 типовых категорий расходов и привязали их к иконкам. Создание статей расходов стало проще некуда :)



Перевод валют


Счета и траты в Coin Keeper могут храниться в разных валютах. Изначально при переводах между разными валютами мы предлагали пользователю ввести оба значения.

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



Инкрементальная статистика


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

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

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




При заходе в статистику мы просто выводим строчки из этих таблиц.

Unit тесты


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

Идея простая: был метод TestAll, который запускал все тесты, создавал новый объект интерфейса прямо внутри приложения и выводил результаты. Запускалось это все на эмуляторе или телефоне при помощи специальной цели для сборки.



Анимация



Тут было 2 сложных момента.

Cкрывание и раскрывание верхней и нижней плашек.




Сначала мы просто подписывались на события TouchesBegan, TouchesMoved, TouchesEnded у соответсвующих view и при начале прикосновения к нижней/верхней части плашки начинали ее двигать. Однако после первых тестов данный подход оказался сильно неудобен для пользователей: они часто начинали двигать пальцем выше или ниже области «захвата» плашки.

Явно напрашивалось какое-то другое решение. Задача еще усложнялась тем, что внутри плашек есть UIScrollView, который перехватывал тачи внутри себя, а также есть категории при нажатии на которые должна вытаскиваться монета.

После ряда экспериментов стало понятно что нам нужен глобальный обработчик всех жестов. Но вместо того чтобы использовать UIGestureRecognizer, мы решили вручную отлавливать все прикосновения на экране и на основе этой информации двигать плашки. Для этого мы сделали свой класс CustomWindow унаследованный от UIWindow, в котором переопределили метод SendEvent (код как раз на C#, но Objective-C девелоперы должны легко его понять):

public override void SendEvent (UIEvent evt)
{
	base.SendEvent (evt);
			
	if (PanelsDragger.TrackTouches)
	{
		var touch = evt.AllTouches.AnyObject as UITouch;
				
		if (touch == null)
			return;
				
		PanelsDragger.TouchAction(touch, touch.LocationInView(this));
	}
}


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

Анимация и отображение категорий




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

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

Заключение


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

Спасибо что дочитали! Напомню про 5 промокодов, которые вышлю тому, кто сможет дать ценный совет по приложению :)

UPD: с промокодами мы какую-то ерунду придумали :) Отдам первым 5 людям, которые попросят.
UPD2: промокоды закончились :(
Tags:
Hubs:
+102
Comments 89
Comments Comments 89

Articles

Information

Website
touchin.ru
Registered
Founded
Employees
51–100 employees
Location
Россия