
昨日、私たちが開発したCoin Keeperアプリケーションは、ロシアのAppStoreの有料アプリケーションの上位3位になりました。
興味深いことに、通常のObjective-Cではなく、MonotouchおよびMonodroidフレームワークを使用してC#で開発しました。
内部では、アプリケーションのアーキテクチャ、トリック、および長所についてお話したいと思います。 さらに、プロジェクトについて貴重なコメントを提供できる人に5つのプロモーションコードを提供します。
コインキーパーは、個人の財務を会計するためのアプリケーションです。 アプリケーションのメイン画面は、大きなコインホルダーのように見えます。 収益、財布、費用は山として表示されます。 廃棄物を修正するには、コインをスタックからスタックに移動するだけです。 詳細については、 CoinKeeper.meアプリケーションのWebサイトをご覧ください 。 ユーザーはこのアイデアを本当に気に入りました。

どんなモノタッチ獣?
プロジェクトを開発するときは、 MonoTouchおよびMonoDroidフレームワークを使用します。これらの製品は、Mono、Gnome、Ximian、Midnight Commanderプロジェクトの創設者であるMiguel de Icazaが率いるXamarinによって作成および開発されました。 コードをネイティブマシンコードにコンパイルし、ネイティブプラットフォームUIライブラリを使用しながら、C#でiPhoneとAndroid向けのモバイルアプリケーションを開発できます。
多くはモバイルプラットフォーム向けのクロスプラットフォーム開発に懐疑的ですが、私の意見では、クロスプラットフォームアプリケーションはネイティブアプリケーションやそれらのようなユーザーと変わらないことを証明しています。
さて、楽しい部分、汚れた技術的な詳細に行きましょう:)
一般的なアーキテクチャ

アプリケーションの一般的なアーキテクチャは次のようになります↑
さらに、DALおよびBLは、AndroidおよびWindows Phone 7バージョン(ソースコードの約50%)にコピーすることなく取得できます。
DAL
Webアプリケーションのデータアクセス層のクラシック。 ビジネスロジック(BL)は、この層の機能のみを使用してデータにアクセスします。
これは多すぎると時間の無駄だと思うかもしれません。 ただし、たとえば、WP7 SQL Compact Editionと別のORMが使用されているため、クロスプラットフォームの目的で、ORMの薄いラッパーを使用しました。
BL
ビジネスロジックまたはアプリケーションビジネスロジックの場合、レイヤーは以下を担当します。
-トランザクションの作成、繰り返しトランザクション、トランザクション履歴。
-カテゴリと自動予算(アプリケーション自体が、必要な金額を決定します:) [オートメーション]セクションで)。
-統計とレポート。
-意図的に蓄積するロジック。
-異なる通貨のアカウント間の取引。
ユーザーインターフェイスは、静的クラスとして表されるビジネスロジックオブジェクトのみを使用します。
一般に、アーキテクチャに関するすべてが、何か不明な点がある場合は、質問してください。詳しく説明します。
「チップ」
自動化
ご存じのとおり、iPhoneユーザーは非常に気まぐれであり、さまざまな骨の折れるアクションを好まないため、不必要な作業からなるべく多くのユーザーを救おうとしました。
自動予算
ユーザーの初回起動時に、給与に応じて、その月の予算を自動的に生成することをお勧めします。 データは、たとえば、30,000ルーブルの給与を持つロシア人の費用の提案などの公共統計に基づいています。


プリセットカテゴリー
2番目に便利なことは、カテゴリベースです。 アプリケーションで100の典型的な費用のカテゴリを収集し、それらをアイコンに関連付けました。 経費項目の作成はどこでも簡単になりました:)

通貨送金
コインキーパーのアカウントと費用は異なる通貨で保存できます。 最初に、異なる通貨間で転送する場合、両方の値を入力することをユーザーに提案しました。
それから彼らはそれが悲しいことであることに気づき、今では毎日外国為替から現在の為替レートを更新しています。 ユーザーは、必要に応じて値を調整できます。

増分統計
成功した技術ソリューションに戻りましょう。 このアプリケーションには、月ごとの収入と支出の棒グラフと、その月の支出の円グラフの2つのグラフがあります。
ダイアグラムを作成するときに、オリジナルを思いつくことができるように思えますか? しかし、問題があります。ユーザーがログインしてその年の収入/費用の統計を確認し、すべてのトランザクションの計算を開始すると、これには数秒かかる場合があり、モバイルアプリケーションでは受け入れられません。
データベースを設計するための簡単な手法、非正規化を使用しました。 ユーザーが追加した各トランザクションは、2つの特別なテーブルのレコードを更新します 。


統計を入力するとき、これらのテーブルの行を表示するだけです。
単体テスト
アプリケーションの開発を開始したとき、すばらしいTouch Unitライブラリはまだ存在していなかったため、独自の小さなテストフレームワークを作成する必要がありました。
考え方は簡単です。すべてのテストを実行し、アプリケーション内に新しいインターフェイスオブジェクトを作成し、結果を表示するTestAllメソッドがありました。 それはすべて、特別なビルドターゲットを使用してエミュレーターまたは電話で開始されました。

アニメーション
2つの困難な瞬間がありました。
上型と下型を非表示にし、開きます。


最初に、対応するビューのTouchesBegan、TouchesMoved、TouchesEndedイベントにサブスクライブし、プレートの下部/上部に触れ始めたときに、それを移動し始めました。 ただし、最初のテストの後、このアプローチはユーザーにとって非常に不便であることが判明しました。ユーザーは、ダイの「キャプチャ」エリアの上または下に指を動かすことがよくありました。
明らかに他の解決策がいくつか登場しました。 タスクはサイコロの中に手押し車をインターセプトするUIScrollViewがあり、クリックしたときにコインを引き出す必要があるカテゴリもあるため、タスクはさらに複雑になりました。
一連の実験の後、すべてのジェスチャーにグローバルハンドラーが必要であることが明らかになりました。 しかし、UIGestureRecognizerを使用する代わりに、画面上のすべてのタッチを手動でキャッチし、この情報に基づいてサイコロを移動することにしました。 これを行うために、SendEventメソッドを再定義したCustomWindowクラスをUIWindowから継承しました(コードは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とコインを引き出すメカニズムが機能します。 はい。iOS5では、上から引き出される通知が導入されたため、緑色のダイを取得することがより難しくなりましたが、新しいバージョンではこの問題を解決しようとします。
アニメーションとカテゴリの表示

アプリケーションは、現在の費用のレベルを色で塗りつぶした円の形でカラフルに表示します。 この場合、色はこのカテゴリの費用の強度と、1か月以内に予算に収まる量に依存します。 このアイデアを実装するために、2つの異なるアプローチを考え出しました。そのうちの1つをここで説明します。
最初は静的な背景画像で、すべてが明確です。 次に、色付きの円のある写真から円の上部を何らかの方法で「切り取る」必要があります。 これを行うには、円の絵を配置するビューを作成し、このビューのClipToBoundsプロパティを設定します。 次に、円の図を上に移動して、円の一部が親ビューの境界からはみ出して切り取られるようにします。 このクリッパービューを正しく配置し、コンテンツができたら次のようにします:)
おわりに
MonoTouch / MonoDroid開発トピックに興味がある場合は、 AndreyBaskovがこれらのフレームワークに基づいた一連の開発記事とクロスプラットフォームモバイル開発を簡素化するさまざまな実用的なソリューションを徐々にレイアウトするブログを購読してください 。
読んでくれてありがとう! アプリケーションに関する貴重なアドバイスを提供できる人に送信する5つのプロモーションコードについて思い出させてください:)
UPD:プロモーションコードを使用して、ある種のナンセンスを思いつきました:)最初に尋ねる5人に紹介します。
UPD2:プロモーションコードは終了しました:(