コラム/C#で作れる! iOS & Android クロス開発環境 Xamarin を試す - WisdomSoft
WisdomSoft - for your serial experiences.

C#で作れる! iOS & Android クロス開発環境 Xamarin を試す

Xamarin は C# で iOS や Android のアプリケーションを開発できるクロスプラットフォームの開発環境です。

Xamarin でモバイル開発を統一する

Xamarin は .NET Framework 互換のオープンソース環境である Mono をベースとする開発ツールで、C# 言語を用いて iOS 及び Android アプリケーションを開発できるクロスプラットフォーム開発環境です。元々 Mono Touch と Mono for Android と呼ばれていた別々のツールが統合し、ブランド名を改めたものが Xamarin です。

通常 iOS アプリケーション開発には Objective-C が使われ、Android の開発では Java が使われるため、異なるプログラミング言語や開発ツールを習得しなければなりませんでしたが、Xamarin では Xamarin Studio と呼ばれる開発環境と、 C# 言語で iOS と Android の双方の開発が可能です。

Xamarin は同一の開発環境でクロス開発を可能とするものであり、いわゆる「一度書いたらどこでも動く」をサポートするものではありません。iOS と Android のプロジェクトは別々であり、UI など OS に依存するコードは共有できません。この点は、かなり現実的な路線であると言えます。共有可能なコードは基本型など .NET Framework の基本クラスライブラリの範囲であり、モデルやビジネスロジックが中心となるでしょう。

図1 Xamarin の構造
図1 Xamarin の構造

上の図のように、Xamarin で開発するアプリケーションで iOS と Android で共通する部分は開発ツールと基本クラスライブラリの範囲です。C# の基本機能の範囲であればコードを共有できますが、UI などは iOS 用のプロジェクトと Android 用のプロジェクトで、個別に開発しなければなりません。

HTML によるブラウザアプリケーションのように、同じソースコードで同じようにクロスプラットフォームで動いて欲しいという要望もあると思いますが、それならば HTML アプリケーションで開発するべきです。かつての Java のように「一度書いたらどこでも動く」を極端に目指そうとすると、その OS の固有の機能を導入できず、iOS と Android で共通する機能しかサポートできなくなってしまいます。

また、HTML アプリケーションと OS ネイティブのアプリケーションを比較すればよく分かりますが、OS に密なネイティブアプリケーションの方がユーザー体験の面で優れています。OS 機能へのアクセスやデバイスに最適化された操作を提供する UI は、やはり、そのシステム固有の API を使わなければなりません。Xamarin は、こうしたシステムに依存した部分は、そのシステムの文化に合わせて記述し、データモデルやビジネスロジックなど、システムに依存しない部分を再利用できる、非常に現実的な開発ツールを目指しているように感じます。

Xamarin Studio

Xamarin にはオープンソースの統合開発環境である MonoDovelop をカスタマイズした Xamarin Studio が含まれています。Visual Studio との連携機能もありますが、有償の上位エディションのみの対応となっています。フリーで開発するには Xamarin Studio を使います。Xamarin は Windows 版と Mac OS X 版がありますが、iOS アプリケーションを開発するには Mac OS X が必要になります。

Xamarin のライセンスは、本稿執筆時点で無償版の STARTER、独立開発者向けの INDIE が $299、企業向けの標準的な開発で推奨される BUSINESS が $999、そして最上位の ENTERPRISE が $1899 となっています。無償版でも Xamarin Studio による開発を体験できますが、アプリケーションのサイズや機能に制限があり、本格的な利用には適しません。

図2 ライセンス(公式サイトより
図2 ライセンス
図3 Xamarin Studio(Windows)
図3 Xamarin Studio

Xamarin をインストールすると、合わせて Android SDK など、必要なツールやコンポーネントがインストールされます。Mac OS X で iOS アプリケーションを開発する場合は Xcode と iOS SDK が必要になります。

iOS アプリケーションの開発

Xamarin は Xcode 及び iOS SDK と連動して Mac OS X 上で iOS アプリケーションを開発できます。もちろん Windows と同じように Xamarin Studio 上で開発でき、Android SDK をインストールして Android アプリケーションの開発も可能です。

Xamarin による iOS アプリケーション開発を要約すると、Xcode の Interface Builder で UI を記述した nib ファイルと、ビューを管理するビューコントローラーの Objective-C ヘッダファイルを作成すると、Xamarin Studio 側で自動的にビューコントローラーのヘッダファイルで宣言されたプロパティやメソッドを C# コードに変換します。そして、実装を C# コードで記述できるという仕組みです。

図4 Xamarin Studio(Mac OS X)
図4 Xamarin Studio(Mac OS X)

試しに、ボタンを押すとラベルに表示されているテキストが変化する簡単なアプリケーションを作成します。Xamarin Studio を起動して「ファイル」メニューの「新規」→「ソリューション」項目を選択して「新しいソリューション」ウィンドウを表示します。

図5 新しいソリューションの作成(iOS)
図5 新しいソリューションの作成(iOS)

表示されたウィンドウの左側のリストから「C#」→「iOS」項目を展開すると iOS 関連のプロジェクトテンプレートが表示されます。Xcode と同じように、iPhone 用や iPad 用に個別に開発することも、iPhone と iPad の両方に対応した Universal なアプリケーションで開発することもできます。

Xamarin で iOS アプリケーションを開発する場合、UI は Xcode での開発と同じように nib ファイル(xib ファイル)を使います。nib ファイルの編集は Xcode ではなく Xcode の Interface Builder を使って編集します。Universal アプリケーションの場合、実行時に iPhone であれば iPhone 用の UI を、iPad であれば iPad 用の UI を読み込みます。

この場では 「C#」→「iOS」→「Universal」項目を選択し、表示された中央のリストから「Single View Application」を選択してプロジェクトを作成します。

図6 自動生成されたファイル
図6 自動生成されたファイル

プロジェクトを作成すると図6のようなファイルが生成されます。上記の例では、「SampleiOSApplication」という名前でプロジェクトを作成したため SampleiOSApplicationViewController.cs、SampleiOSApplicationViewController_iPad.xib、SampleiOSApplicationViewController_iPhone.xib が生成されています。「プロジェクト名ViewController.cs」がビューコントローラーのコードであり、これに対応する nib ファイルが「プロジェクト名ViewController_iPad.xib」と「プロジェクト名ViewController_iPhone.xib」になります。

nib ファイルをダブルクリックすると Xcode の Interface Builder が開きます。UI の作成は Xcode で作成する通常の iOS アプリケーション開発と同じです。任意のビューオブジェクトを配置するだけです。この場では UILaber オブジェクトと UIButton オブジェクトを配置します。

図7 Xcode の Interface Builder
図7 Xcode の Interface Builder

nib ファイルで作成した UI のビューオブジェクトやイベントを処理するには、対応するビューコントローラーと関連づける必要があります。アシスタントエディターを表示しヘッダファイルを表示してください。

Xcode 側でプロジェクトのファイルを見ると、C# コードではなく、Objective-C のヘッダファイルが存在します。この場では SampleiOSApplicationViewController.h というファイルがあるので、これにアウトレットやアクションを宣言します。これも、Xcode による一般的な iOS アプリケーション開発と同じ流れです。

図8 ビューを選択し、副ボタンでドラッグ
図8 ビューを選択し、副ボタンでドラッグ
図9 ビューのアウトレットやアクションの接続
図9 ビューのアウトレットやアクションの接続

ラベルは label プロパティとして接続し、ボタンが押されたときの処理は pushButton メソッドに接続します。これを保存して Xamarin Studio に戻ると、Objective-C で宣言したプロパティやメソッドが C# のビューコントローラーに反映されています。自動生成されたコードはビューコントローラーの partial クラスとして別のファイルに書かれています。ビューコントローラーの C# ファイルを展開すると、図10のように「ビューコントローラー名.designer.cs」ファイルが存在します。これが、ビューコントローラーの partial クラスで、Xamarin Studio によって自動生成されるコードを含みます。

図10 C# 側に自動生成されたコード
図10 C# 側に自動生成されたコード

ビューコントローラーにアウトレットで接続したプロパティは、C# 側で Outlet 属性を持つプロパティとして生成されています。同様に、アクションとして接続された間せっどは Action 属性を持つメソッドとして生成されています。あとは、ビューコントローラーにメソッドを実装し、必要な処理を記述すれば完成です。

この場では、ボタンが押されたときに呼び出される pushButton() メソッドを実装し、ボタンが押されるとラベルの文字を変更するプログラムを作成します。

コード1 SampleiOSApplicationViewController.cs
using System;
using System.Drawing;

using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace SampleiOSApplication
{
    public partial class SampleiOSApplicationViewController : UIViewController
    {
        static bool UserInterfaceIdiomIsPhone
        {
            get
            {
                return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone;
            }
        }

        public SampleiOSApplicationViewController()
            : base(UserInterfaceIdiomIsPhone ?
                "SampleiOSApplicationViewController_iPhone" :
                "SampleiOSApplicationViewController_iPad", null
            )
        {
        }

        public override void DidReceiveMemoryWarning()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning();

            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Perform any additional setup after loading the view, typically from a nib.
        }

        partial void pushButton(NSObject sender)
        {
            label.Text = "Set up";
        }

        public override bool ShouldAutorotateToInterfaceOrientation(
        UIInterfaceOrientation toInterfaceOrientation)
        {
            // Return true for supported orientations
            if (UserInterfaceIdiomIsPhone)
            {
                return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
            }
            else
            {
                return true;
            }
        }
    }
}
実行結果
コード1 実行結果

コード1は nib ファイルでデザインされた UI と接続されている pushButton() メソッドを実装し、ボタンが押されるとラベルの文字を変更するプログラムです。使用するプログラミング言語は C# ですが、それ以外は Xcode で開発する iOS アプリケーションと大きな違いがないことが確認できます。

Android アプリケーションの開発

Xamarin による Android アプリケーション開発では、Xamarin Studio 独自の UI エディタを用いて開発できます。グラフィカルなツールで UI を定義し、コード側で UI オブジェクトを取り出して関連づけるという方式です。

Xamarin Studio を用いて Android アプリケーションを開発してみます。「ファイル」メニューの「新規」→「ソリューション」を選択し「新しいソリューション」ウィンドウを表示します。

図11 新しいソリューションの作成(Android)
図11 新しいソリューションの作成(Android

表示されたウィンドウの左側のリストから「C#」→「Android」項目を選択し、中央に表示されたリストから「Android Application」を選択してプロジェクトを作成してください。

プロジェクトと同時に自動生成されたコードの中に MainActivity.cs という名前のファイルがあり、これがアプリケーション起動時に読み込まれる Activity となります。このファイルは、アプリケーションが読み込まれたときに、画面に表示するビューとして Resources/layout フォルダ内の Main.axml を設定しています。名前の通り XML ベースのファイルです。

Main.axml は Mono for Android のビューを定義するファイルで、これをダブルクリックするとプレビュー画面が表示されます。画面右側にある「Toolbox」から任意のビューオブジェクトを選択し、画面にドラッグ・アンド・ドロップすることで貼り付けられます。

図12 Xamarin Studio での UI デザイン
図12 Xamarin Studio での UI デザイン

この場では Button オブジェクトと TextView オブジェクトを追加し、ボタンが押されたときにテキストを変更するプログラムを記述します。axml ファイルに設定したビューオブジェクトは、Id プロパティに指定した名前で識別でき、この名前に対応する定数が Resources/values/ フォルダの Resource.designer.cs ファイルに自動生成されます。

今回の例では、ボタンに button、テキストに textView という名前を設定しています。

コード2 MainActivity.cs
using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace AndroidApplication
{
    [Activity (Label = "AndroidApplication", MainLauncher = true)]
    public class Activity1 : Activity
    {
        int count = 1;

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            // Get our button from the layout resource,
            // and attach an event to it
            Button button = FindViewById<Button> (Resource.Id.button);
            TextView textView = FindViewById<TextView> (Resource.Id.label);
			
            button.Click += delegate {
                textView.Text = "Set up.";
            };
        }
    }
}
実行結果
コード2 実行結果

コード2は Xamarin Studio で作成した、ボタンを押すと下部のテキストが変化するプログラムです。FindViewById() メソッドを用いて ID からビューオブジェクトを取得し、プロパティの設定やイベントの高禄を行っています。ボタンが押されると Button オブジェクトの Click イベントに追加しているデリゲートが呼び出されます。