nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Development Technologies。

KAMISHIBAI for Xamarin.Forms 1.0.0をリリースしました。

ここしばらく作っては消しを繰り返していた、お手製画面遷移ライブラリ

f:id:nuitsjp:20170807125900p:plain

をリリースしました。コードとドキュメントはGithub上に公開しています。利用の際はNuGetからインストールして利用してください。

目指したのは

  1. Xamarin.Formsで可能なあらゆる画面遷移が実現可能
  2. タブ切り替えを含むPageが切り替わるタイミングで、一貫性のある画面遷移イベントが通知され
  3. 型安全に画面遷移パラメーターを受け渡せて
  4. ちゃんとViewとViewModelが分離できる

画面遷移ライブラリです。ちょっと胡散臭いですね。

実際にコードを見ていただいた方が良いでしょう。DateTime型を引数に画面遷移するシナリオを考えます。まずはViewModelです。

public INavigationRequest<DateTime> RequestSecondPage { get; } = 
    new NavigationRequest<DateTime>();

public Task Navigate(DateTime selectedDate)
{
    return RequestSecondPage.RaiseAsync(selectedDate);
}

見ての通り、ViewModelからはパラメーターを渡して遷移要求をあげるだけで、遷移処理そのものは記述しません。
遷移処理はXAMLに書きます(C#で書いても良いですが)。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage ...>
    <ContentPage.Behaviors>
        <mvvm:PushModalAsync Request="{Binding RequestSecondPage}" 
                             x:TypeArguments="views:SecondPage"/>
    </ContentPage.Behaviors>

PushModalAsyncビヘイビアに注目してください。
RequestSecondPageから遷移要求を受け、SecondPageへ、PushModalAsyncで画面遷移する事が理解できるでしょう。

そして値を受け取るのは、遷移イベントの通知で受け取ります。

    public class SecondPageViewModel : IPageInitializeAware<DateTime>, INotifyPropertyChanged
    {
        ...
        public void OnInitialize(DateTime selectedDate)
        {
            SelectedDate = selectedDate;
        }

ここまでで興味をもっていただけた方は、良かったらチュートリアルをお試しください。

なお大雑把なアーキテクチャモデルは次のとおりです。

f:id:nuitsjp:20170807164150p:plain

NavigatorクラスがXamarin.Forms.INavigationをラップし、イベント通知と遷移パラメーターの受け渡しを実現しています。
画面遷移はViewModel層でNavigationRequestを利用して画面遷移要求をView層にあげる事から始まります。
NavigationRequestはPushAsyncやPopAsyncなど、NavigationBehaviorを継承したBehaviorにバインドされており、NavigationRequestからの要求を受けて、BehaviorがNavigatorクラスを呼び出して画面遷移します。

流れ的には以下のようなイメージです。

f:id:nuitsjp:20170807171121p:plain

NavigationBehaviorを継承して独自の遷移処理を実装すれば、アーキテクチャ上、Xamarin.Formsで実装可能な画面遷移は全て実現可能です。

アーキテクチャについては、もう少し詳細な情報をこちらに記載しています。

ところで本当に「Xamarin.Formsで可能なあらゆる画面遷移が実現可能」なのでしょうか?
ということで、ちょっと前に感動したMasterDetailPageの設計パターンに適用してみました。元記事はこちらになります。

qiita.com

こんなMasterDetailPageを作ります。

f:id:nuitsjp:20170807161006g:plain

  1. DrawerからHome以外を選択して画面遷移した後、戻るボタンでHomeへ戻る
  2. DrawerからHome以外を複数回選択して画面を切り替えても、戻るボタンを押すとHomeへ戻る
  3. その間、左上のボタンはずっとハンバーガーメニューの状態になっている
  4. Homeを表示した状態で戻るボタンを押すと、Androidのホームに戻る
  5. Drawerから選択した画面から、ドリルダウンで詳細へ遷移すると左上のボタンは矢印ボタンになる

Xamarin.FormsのデフォルトのMasterDetailPageだとちょっと面倒な仕様ですが、Detail側でNavigationPageを2段階にネストして利用することで実現されています。
詳細な解説は先に紹介したQiitaの記事をご覧ください。
Qiitaの記事ではView層でガッツリ実装されていますが、これをKAMISHIBAIを適用しつつ、ViewとViewModelを分離します。

分離して実装したサンプルコードがこちらにあります。

github.com

ここのSpecialMasterDetailPageソリューションを参照してください。
ちゃんとViewとViewModelが分離されているのが見て取れると思います。

解説は次回にでも行いたいと思います。

それでは今回はここまで。良かったら使ってください!

Service LocatorをInjectionするパターンの再考察

しばらく前に、Dependency InjectionパターンとService Locatorパターンの記事を書きました。

www.nuits.jp

この中で、私はService Locatorパターンは次の点でDependency Injectionパターンに劣ると記載しました。

  1. 本来不要であるServiceLocatorへの依存が発生してしまう
  2. 依存関係が分かりにくくなる
  3. テストが困難になる

詳細は先のリンクの記事を参照していただきたいのですが、3.について次のような意見を頂いたため再考してみました。

「Service Locatorを利用するとテストの並行実行性が保てないのは、Service Locatorが静的な実装になっているからで、インスタンスを利用すれば良いのでないか?」

なお本エントリーは、元々先のリンク先の末尾に記載していたものがベースとなっていますが、一旦削除し独立してまとめ直しました。

続きを読む

REST APIをAzure MobileApps SDKを利用して実行する

前回のエントリーではMicrosoft.Rest.Clientを利用してAzure API AppのREST APIを利用しました。

www.nuits.jp

ちなみにこれ、AutoRestというプロダクトの一部みたいですね。今日もう少し調べてて知りましたw
さて、前回のエントリーを書いたところ、MobileApps SDKを使うと簡単にできるよ!との情報をいただきましたので試してみました。
確かに簡単ですね。

というわけで、今回はMicrosoft.Azure.Mobile.Clientを利用してREST APIを呼び出してみたいと思います。

  • Azure MobileApps SDKを利用してREST APIを呼び出す
  • AutoRestとMobileApps SDK考察
続きを読む

Hello, Azure API Apps with Xamarin.Forms

前回、Azure API Appの簡単な利用方法を解説しました。

www.nuits.jp

今回は、これをXamarin.Formsから利用してみましょう。

  • Xamarinプロジェクトを作成する
  • XamarinにAPI App呼び出しを組み込む
    • MainPageViewModelの作成
    • MainPage.xamlの修正
    • APIクライアントの組込み
  • さあ動かしてみよう!
続きを読む

Hello, Azure API App with .NET Core

本エントリーでは、Microsoft Azure上でWeb(REST) APIを構築するAPI App初心者向けのエントリーです。

対象読者は以下を想定しています。

  • Azureのアカウントは作成した
  • API App使いたいけど何も分からない
  • とりあえずAPIを公開して呼び出すところまでの手引きが欲しい(要はHello, Worldレベル)
  • Visual StudioやC#は、利用経験があり環境構築済みである(Visual Studio 2017 Windows版を想定)
  • とりあえず無料で試したい

大丈夫。私も右も左も分からない中からできたので、誰でもできます。

なお本エントリーではRESTクライアントも自動生成しますが、それはXamarinからも利用可能なもの。。。のはずです。まだ試していませんが、.NET Standardで動くので動くでしょうきっと(とは言え、.NET Standard 1.4以上が必要なので、PCLからは利用できません)。

なお、この手の記事は鮮度が非常に重要です。
本エントリーは2017年7月11日時点の情報に則って記載しています。

それでは解説を始めましょう。

続きを読む

.NET Standardや.NET Coreでmscorlib 2.0.5.0の参照がないと怒られた場合の対処方法

.NET StandardのプロジェクトからPCLのプロジェクトを無理やり参照しようとしたような場合に発生します。
PackageTargetFallbackを指定しているような場合です。

System.~系への参照が、PCLでは明示的にバージョンが指定されているが.NET Standard側では明示的に指定しないから?見たいですが正確には良く分かりません。
良く分かりませんが、NuGetから次のCompatibilityパッケージをインストールすることで対応可能です。

www.nuget.org

これは過渡的な対応で、.NET Standard 2.0や.NET Core 2.0がリリースされると心配は不要になるようです?