
Yesterday, the
Coin Keeper application we developed took third place in the top paid applications of the Russian AppStore.
Interestingly, we developed it not in the usual Objective C, but in C #, using the Monotouch and Monodroid frameworks.
Inside, I would like to talk about the architecture of the application, tricks and good moments. In addition, I will distribute
5 promotional codes to anyone who can give valuable comments on the project.
')
Coin Keeper is an application for personal finance. The main screen of the application is similar to a large
coin holder . Revenues, wallets and expenses are presented as piles. To fix the waste, it is enough to transfer a coin from the pile to the pile. You can find out more on the website of the application
CoinKeeper.me . Users really liked the idea:

What kind of beast is Monotouch?
When developing projects, we prefer the
MonoTouch and
MonoDroid frameworks .
These products are created and developed by
Xamarin , led by Miguel de Icaza, the founder of Mono, Gnome, Ximian and Midnight Commander projects. With their help, you can develop mobile applications for iPhone and Android on C #, while the code is compiled into native native code and the native UI libraries of platforms are used.
Many are skeptical of any cross-platform development for mobile platforms, but in my opinion our case proves that cross-platform applications are no different from native and like users.
Well, let's get down to the most interesting, to dirty technical details :)
General architecture

The overall architecture of the application looks like this ↑
Moreover, DAL and BL can be taken without any changes and copied to Android and Windows Phone 7 versions, which is about 50% of the source code!
Dal
Classic for web applications Data Access Layer. Business logic (BL) for data access uses only the functions of this layer.
You might think that this is a chore and a waste of time. But, for example, WP7 uses SQL Compact Edition and another ORM, so in order to cross-platform, we made a thin wrapper over ORM.
BL
Business Logic or application business logic, the layer is responsible for:
- transaction creation, recurring transactions, transaction history;
- categories and autobudget (the application itself determines how much to spend :) in more detail in the Automation section);
- statistics and reports;
- the logic of accumulation on the target;
- transactions between accounts in different currencies.
The user interface exclusively uses business logic objects, represented as static classes.
In general, and everything about architecture, if anything remains unclear - ask questions, tell you more.
"Chips"
Automation
As you know, iPhone users are very capricious and do not like various painstaking actions, so we tried to save them as much as possible from unnecessary work.
Autobudget
When you first start the user, we offer him to automatically form a budget for the month, depending on salary. The data is based on public statistics, for example, a proposal for the expenses of a Russian with a salary of 30,000 rubles.


Predefined categories
The second handy little thing - the base categories. We have collected in the annex 100 standard categories of expenses and tied them to the icons. Creating items of expenditure is nowhere easier :)

Currency Translation
Coin Keeper accounts and expenses can be stored in different currencies. Initially, for transfers between different currencies, we asked the user to enter both values.
Then they realized that it was sad and now every day we update current exchange rates from a foreign exchange. The user, if he wants, can adjust the value.

Incremental statistics
Let us return to the successful technical solutions. The annex has two graphs: a bar chart of income and expenses by month and a pie chart of expenses for the month.
It would seem that you can come up with the original when building charts? But there is such a problem, if the user comes to see the statistics of income / expenses for the year and we start counting it across all transactions, it may take a couple of seconds, which is unacceptable for mobile applications.
We used a simple database design technique - denormalization. Each transaction added by the user
updates the records in two special tables:


When entering statistics, we simply output lines from these tables.
Unit tests
When we started developing the application for the wonderful
Touch Unit library, there wasn’t yet, so I had to write my little test framework.
The idea is simple: there was a TestAll method that ran all the tests, created a new interface object right inside the application, and outputted results. It all started on an emulator or phone with the help of a special assembly target.

Animation
There were 2 difficult moments.
Covering and opening the top and bottom dies.


At first, we simply subscribed to the TouchesBegan, TouchesMoved, TouchesEnded events at the corresponding view and when we started touching the bottom / top of the plate, we began to move it. However, after the first tests, this approach turned out to be very inconvenient for users: they often began to move their fingers above or below the “grip” area of ​​the plate.
Some other solution was evident. The task was further complicated by the fact that inside the dies there is a UIScrollView that intercepted the tachi inside of itself, and there are also categories when you click on which the coin should be pulled out.
After a series of experiments, it became clear that we needed a global handler for all gestures. But instead of using UIGestureRecognizer, we decided to manually catch all touches on the screen and based on this information move the dies. To do this, we made our CustomWindow class inherited from the UIWindow, in which we redefined the SendEvent method (the code is just in C #, but Objective-C developers should easily understand it):
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)); } }
And already on the basis of information about the location of the wheelbarrow, we accordingly move the necessary dies. As a result, now you can start a gesture in any part of the screen and when the finger reaches the desired plate, it will pick up and begin to hide. At the same time, touch events also reach other controls, which allows UIScrollView and the coin-dragging mechanism to work. Yes, in iOS 5 with the introduction of notifications that are pulled out from above, it became harder to get the green plate, but in the new version we will try to get rid of this problem.
Category Animation and Display

The application shows colorfully the level of current expenses: in the form of a circle filling with color. The color depends on the intensity of spending in this category and how much you fit into the budget within a month. To implement this idea, we came up with 2 different approaches, one of which will be described here.
The first is a static picture of the background, everything is clear. Next, we need to somehow "cut off" the upper part of the circle in the picture with a color circle. To do this, we create a view inside which we put a picture of a circle and set the ClipToBounds property of this view. Next, we move the picture of the circle up so that a part of the circle crawls beyond the boundaries of the parent view and is clipped. Correctly position this clipper view and voila we have the content :)
Conclusion
If you are interested in the development theme on MonoTouch / MonoDroid, subscribe to
our blog , where
AndreyBaskov will gradually post a cycle of development articles based on these frameworks, as well as various practical solutions that simplify mobile cross-platform development.
Thank you for reading! Let me remind you about the 5 promotional codes that I will send to someone who can give valuable advice on the application :)
UPD: with promo codes we came up with some kind of nonsense :) I will give to the first 5 people who will ask.UPD2: promotional codes are over: (