これまでXamarinを使用してiOSとAndroid向けのアプリを開発しましたが、それぞれ独立したプロジェクトでありロジックも別々になってしまっています。これではクロスプラットフォーム開発環境である意味が薄れてしまうため、今回はロジックの共通化を行います。また、これまで紹介しきれなかったMicrosoft Azure モバイルサービスの機能をご紹介したいと思います。
Xamarinのロジックの共通化
Xamarinを起動して、ソリューションを確認するとiOSとAndroid両者でファイルやクラス名が全く違うことに気づかれると思います。これはXamarinは薄いラッパーに過ぎず、アプリの構成についてはiOSやAndroidなどの各プラットフォームに依存しているからです。つまり、各プラットフォームごとにアプリケーションの起動サイクル、状態・状態変化、割り込みへの応答、バックグラウンド・フォアグラウンドへの移行などを学習する必要があります。
このようなことを冒頭に書いてしまうと「なんだ、結局勉強のし直しか」と感じてしまう方もおられると思いますが、大半はイベント名が違うだけであり基本的な動作は同じです。
画面遷移の処理を例にあげますと、第2回・第3回で行ったiOSと第4回で行ったAndroidではリソース名やツールの使い方などは違いますし、画面表示のイベント名も「ViewDidLoad」と「OnCreate」と異なっています。しかし、遷移前の画面と遷移後の画面に対して共通の入れ物(クラス)でデータを受け渡しする。という大まかな部分については両者同じではないでしょうか?
共通クラスの切り出し
このように細かい実装から離れて全体を俯瞰してみると、「ToDoItem.cs」がiOSとAndroid両方のプロジェクトに存在しており、共通化できそうに思えないでしょうか?
コードを見ると「ToDoItem」クラスが両者にあるのでここは間違いなく共通化できそうです。Androidだけ「ToDoItemWrapper」というクラスが入っているようです。
ポータブルクラスライブラリの追加
共通化部分をポータブルクラスライブラリ(以降PCLと表記する)としてアプリから独立したDLLとして切り出します。まず、ソリューションを右クリックして「新しいプロジェクトの追加」を選び、Portable Library プロジェクトの追加を行います。
次に追加したプロジェクトを右クリックしてオプションを開き、ビルド - 一般の設定を変更し、「PCL 4.5 - Profile7」を選択して「OK」をクリックします。
自動で作成される「MyClass.cs」は不要なので消してください。次に「ToDoItem.cs」ファイルをiOSのプロジェクトからコピペします。この時点でビルドすると、「Newtonsoft.Json」が見つからないというエラーが出ます。
参照アセンブリの追加
エラーが出る原因は参照アセンブリが不足しているからです。PCLのプロジェクトの参照ディレクトリで右クリックして「参照アセンブリの編集」をクリックします。
「Edit References」画面にて「Microsoft.WindowsAzure.Mobile.dll」と「Newtonsoft.json.dll」を選択します。
- 「.NET Assembly」タブを選択する。
- プロジェクト配下の「Components/azure-mobile-services-1.1.0/lib/ios」ディレクトリを選択する。
- 「Microsoft.WindowsAzure.Mobile.dll」と「Newtonsoft.json.dll」を選択する。
- 「追加」をクリックする。
- 参照の更新に「Microsoft.WindowsAzure.Mobile.dll」と「Newtonsoft.json.dll」が追加されていることを確認する。
- 「OK」をクリックする。
これで参照アセンブリが追加され、再度ビルドを行うとエラーは解消されているはずです。
PCLをiOSプロジェクトに組み込む
iOSの「ToDoItem.cs」を削除して、参照アセンブリにPCLを追加します。
ソリューションから「ToDoItem.cs」を右クリックして削除します。
参照アセンブリの追加は、「参照」を右クリックして「Projects」タブを選択後、PCLを選択して「OK」をクリックします。
再度ビルドを行い、ビルドエラーが起きないことを確認してください。iOSシミュレーターで動作確認してみるのも良いでしょう。
PCLをAndroidプロジェクトに組み込む
iOSと同様にAndroidにもPCLを組み込んでみましょう。ただし、Androidの「ToDoItem.cs」には「ToDoItemWrapper」というクラスが存在するため、「ToDoItem.cs」を削除するのではなく、「ToDoItemWrapper.cs」に移行します。
- 「ToDoItem.cs」を「ToDoItemWrapper.cs」に名前を変更します。
- 「ToDoItemWrapper.cs」ファイルを開いて、「ToDoItem」クラスを削除します。
- 最終的にこの図のようになっていることを確認します。
移行が完了しましたら、iOSと同様にPCLを参照アセンブリに追加します。
ここでもビルドを行い、ビルドエラーが起きないことを確認してください。
以上で、「ToDoItem」クラスの共通化は完了です。このようにiOS、Android両方で使えるクラスはどんどんPCLに追い出してコードの重複を排除して、プラットフォーム間でライブラリ共有が可能なことがXamarinの魅力です。
さらに共通化するために
さて、先の例ではPCLの参照アセンブリに「Microsoft.WindowsAzure.Mobile.dll」を組み込みましたが、現実装では不要です。なので、削除しても良いのですが、まだまだ共通化できる余地があります。
例をあげます。Command+Shift+Fキーで「複数ファイルからの検索」が開きます。そこに「MobileServiceClient」といれて検索をしてみてください。
すると、iOSプロジェクトにある「QSTodoService.cs」とAndroidプロジェクトにある「ToDoActivity.cs」がヒットします。同じクラスを使っているということは、共通化が可能ということです。
ここから先は皆さん自身でクラスの共通化にチャレンジしてみてください。先の「ToDoItem」クラスの切り出しより若干難易度が高いと思います。
Microsoft Azure モバイルサービスの機能紹介
これまでにXamrinを使用してiOSとAndroidのアプリを作成しましたが、サーバサイドへのロジック追加を一切行っていないことにお気づきいただけたでしょうか?
このようにモバイルサービスではデータの追加・取得・編集・削除といった基本的な操作はWebAPIとしてサーバ側にあらかじめ用意されています。WebAPIを呼び出すためにクライアント側の実装もクライアント用SDKが用意されているため、いちいちHttpClientから叩いてJSONを解析して…といった実装は不要です。
本連載にて紹介しきれなかったMicrosoft Azure モバイルサービスの機能の一部をご紹介します。
認証
簡単な設定を行うだけで、Twitter, Facebook, Google, Microsoft Account, Azure Active Directoryを使用して認証を行うことが可能です。詳細はGet started with authentication (Xamarin.iOS) - Mobile Servicesをご確認ください。
日本語ですと、Xamarin で Windows Azure モバイルサービスを使う(その2:認証編) - Qiitaが参考になると思います。
プッシュ通知
サーバからアプリへのプッシュ通知も簡単な設定とわずかな実装だけで実現できます。詳細はGet started with push notifications (Xamarin.iOS) - Mobile Servicesをご確認ください。こちらも日本語はXamarin で Windows Azure モバイルサービスを使う(その3:プッシュ通知編) - Qiitaが参考になると思います。
オフラインサポート
インターネットに接続されていない場合も継続してアプリの使用が可能です。オフラインで更新した内容はオンラインになった時に反映されます。さらに、オンラインと差分があった場合はどちらか選べます。
詳細は次のページを参照してください。
.NET バックエンド
本連載ではバックエンドにJavaScriptを選択しましたが、.NET を選択することが可能です。サーバサイドもc#で書くことが可能です。
以上で本連載は終了となります。Microsoft Azure モバイルサービスは日々進化していますので、これからも新しい便利な機能がどんどん追加されると思いますので、皆さん是非使ってください。