前回、Azure API Appの簡単な利用方法を解説しました。
今回は、これをXamarin.Formsから利用してみましょう。
Xamarinプロジェクトを作成する
まず、前回作成したソリューションにXamarin.Formsのプロジェクトを追加します。
ここでは「HelloXamarin」という名称にしました。
さて、前回作成したRESTクライアントはMicrosoft.Rest.Clientを利用していますが、これは.NET Frameworkか.NET Standard 1.4以上しかサポートしていません。
PCLのプロジェクトは、プロファイルによって利用できる.NET Standardのバージョンが異なりますが、どうがんばっても1.2止まりです。
https://docs.microsoft.com/en-us/dotnet/standard/net-standard
このため、PCLは諦めてXamarin.Formsの共通プロジェクトを.NET Standard化します。
という訳で、まずはHelloXamarinプロジェクトを削除します。
プロジェクトから削除しても、ファイルシステムには残っています。
後から、AppクラスとMainPageクラスは再利用したいので、ここではフォルダは削除せず「HelloXamarinOriginal」にフォルダ名を変更しています。
つづいて、.NET Standardのクラスライブラリを「HelloXamarin」という名称で作成します。
注意点が一つあります。
「HelloXamarin」という名称のXamarin.Formsのソリューションフォルダが存在しますので、「HelloXamarin」という名称の.NET Standardクラスライブラリを作成するときは、作成場所に注意しましょう。ソリューションフォルダの下に作成すれば良いかと思います。
さて、作成した.NET StandardプロジェクトからNuGetを通してXamarin.Formsを追加したいところですが、現時点ではXamarin.FormsはPCLなのでそのままでは追加できません。
そこでcsprojを直接編集して、PCLを参照可能にし、ついでにXamarin.Formsの参照をつけてしまいましょう。
プロジェクトを右クリックし「HelloXamarin.csprojを編集する」をクリックしてください。
そして次のように書き換えてしまいましょう。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard1.4</TargetFramework> <PackageTargetFallback>portable-net45+win8+wpa81+wp8</PackageTargetFallback> <DebugType>full</DebugType> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.8" /> <PackageReference Include="Xamarin.Forms" Version="2.3.4.247" /> <PackageReference Include="Xamarin.Forms.BehaviorsPack" Version="1.2.0" /> </ItemGroup> <ItemGroup> <!-- https://bugzilla.xamarin.com/show_bug.cgi?id=55591 --> <None Remove="**\*.xaml" /> <Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" /> <EmbeddedResource Include="**\*.xaml" SubType="Designer" Generator="MSBuild:UpdateDesignTimeXaml" /> </ItemGroup> </Project>
PackageTargetFallbackという要素が指定されていますが、これは利用したいNuGetパッケージに対象の.NET Standardのパッケージがなかった場合は、強制的に指定プロファイルのPCLのライブラリを使ってね、と指定していることになります。
つまりXamarin.FormsのPCLのバイナリをこれを通して参照させています。
また、今回はUWPも対象にしているため、.NET Standardは1.4にしています。
なおXamarin.Formsの.NET Standard化については、次のブログも参考になりますので一読する事をお勧めします。
さて、よく見ると参照しているパッケージが3つありますね。
- Microsoft.Rest.ClientRuntime
- Xamarin.Forms
- Xamarin.Forms.BehaviorsPack
1.と2.は説明は不要でしょう。3.ですが、後でサンプルコードを書くのを楽するために利用します。
利用頻度の高い汎用的なBehaviorライブラリで超お勧めです。特に作者がいい感じです。
さて、それでは「HelloXamarinOriginal」に名前変更しておいたフォルダから、AppクラスとMainPageクラスをコピってきましょう。xamlとxaml.csがあるので4ファイルある事を忘れないでください。
これを
こう、コピッペッとします。
あとは、Android・iOS・UWPプロジェクトから参照を再設定すれば完了です。
ここまででひとまずビルドして実行できることを確認しましょう。
XamarinにAPI App呼び出しを組み込む
つぎのような手順で組み込んでいきます。
- MainPageViewModelの「ガワ」を作る
- MainPage.xamlをつぎの三つの観点で修正する
- MainPageViewModelをBindingContextへバインド
- API Appを呼び出すコマンドを実行するBehaviorの追加
- API Appの呼び出し結果の表示
- APIクライアントの組込み
MainPageViewModelの作成
MainPageViewModel.csを追加し、ひとまず次のようなコードを書きましょう。
まだ「ガワ」だけで肝心のAPIの呼び出し処理はありません。
public class MainPageViewModel { public ObservableCollection<string> Values { get; } = new ObservableCollection<string>(); public Command GetAllCommand { get; } public MainPageViewModel() { GetAllCommand = new Command(GetAll); } private async void GetAll() { } }
つぎの三つが存在する事が見て取れるでしょう。
- API Appを実際に呼び出す想定のGetAllメソッド(まだ空っぽ)
- GetAllメソッドを呼び出すGetAllCommand
- API Appの呼び出し結果を格納する想定のObservableCollection
Values
MainPage.xamlの修正
先にも説明した通り、つぎの三点を組み込みます。
- MainPageViewModelをBindingContextへバインド
- API Appを呼び出すコマンドを実行するBehaviorの追加
- API Appの呼び出し結果の表示
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloXamarin" xmlns:behaviorsPack="clr-namespace:Xamarin.Forms.BehaviorsPack;assembly=Xamarin.Forms.BehaviorsPack" x:Class="HelloXamarin.MainPage"> <ContentPage.BindingContext> <local:MainPageViewModel/> </ContentPage.BindingContext> <ContentPage.Behaviors> <behaviorsPack:EventToCommandBehavior EventName="Appearing" Command="{Binding GetAllCommand}"/> </ContentPage.Behaviors> <Grid> <ListView ItemsSource="{Binding Values}"/> </Grid> </ContentPage>
BindingContextにMainPageViewModelが設定されており、API Appの戻り値をListViewに設定しようとしているのが見て取れるでしょう。
ポイントはEventToCommandBehaviorです。
<behaviorsPack:EventToCommandBehavior EventName="Appearing" Command="{Binding GetAllCommand}"/>
良くあるBehaviorですが、PageのAppearingイベントが発行された時(つまり画面の初期表示時など)にGetAllCommandを呼び出すよう定義しています。
こういった、利用頻度が高いBehaviorがいくつかセットになっているので、Xamarin.Forms.BehaviorsPackお勧めです。作者的に。
APIクライアントの組込み
それではいよいよAPIクライアントを組み込んでいきましょう。
まずは前回のエントリーで作成したつぎの四つのクラスをコピーします。
- AnonymousServiceClientCredentials.cs
- HelloApiService.cs
- HelloApiServiceExtensions.cs
- IHelloApiService.cs
こんな感じですね。
そしてMainPageViewModelにクライアントを呼び出す処理を実装しましょう。
実装する先はGetAllメソッドです。
private async void GetAll() { var helloApiService = new HelloApiService( new Uri("http://helloapiservice.azurewebsites.net"), new AnonymousServiceClientCredentials()); var values = await helloApiService.GetAllAsync(); foreach (var value in values) { Values.Add(value); } }
さあ動かしてみよう!
ということで、Androidエミュレーターで実行したのが次のイメージです。
これでAzure API ServiceとXamarin(他クライアント)を連携させる基本が実現できました。
もっと簡単な方法があるかも知れませんが、ご存知の方は良かったら教えていただけると嬉しいです。
では今回はここまで。
それではまた!