PR/BLOG

広報・ブログ

Uno Platform 習作 その1

畝地さん

技術開発推進部の畝地(あぜち)です。
プロスポーツで少ないながらも有観客が始まりましたね。
最大5000人であっても、心配性な私はDAZN観戦です。
来年の為に今は我慢。

さて、今回から2回にわたり Uno Platform での開発を行っていきます。

内容

図のようにWebAPIにリクエストを送ってレスポンスを受取り、結果を表示するプログラムを作成します。

  • プログラムは exe(UWP)、WebAssenbily、iOSシミュレータ、Androidエミュレータ で動くこととします。
  • iOSシミュレータ を動かすためには Mac が必要です。
  • Uno Platform は 2020/05 に macOS にも対応しましたが、今回は対象外とします。

今回はWebAPIとの通信と画面遷移までを行います。

 

開発環境構築

Qiita で公開されている情報を参考に構築を行います。
Uno Platform 入門 2 : 環境構築をしよう!
続いて、Microsoftが公開している情報を参考に Mac とペアリングを行います。
Xamarin.iOS 開発のために Mac とペアリングする
タイトルからも分かるように Xamarin.iOS の情報です。
前回説明したように Uno Platform は Xamarin 上で動いているので Xamarin の情報を参考にできます。

 

WebAPI

プログラムが通信する WebAPI については今回説明しません。
リクエストに対して以下のレスポンスを返す想定とします。

<ArrayOfUsers xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebApp.Controllers">
 <Users>
   <Name>管理者</Name>
   <UserId>admin</UserId>
 </Users>
</ArrayOfUsers>

また、以下の想定とします。

  • Uno Platform開発環境と同じマシンで動いているものとする。
  • クエリストリング「lst=true」が渡された場合、ユーザー一覧を返す。
  • クエリストリング「uid」(ユーザーID)および「pwd」(パスワード)が渡された場合、それに対応するユーザーを返す。
  • ユーザー名:管理者、ユーザーID:admin、パスワード:12345 のユーザーが登録されているものとする。

 

ログイン画面の作成

では早速作成していきましょう。
Visual Studio でプロジェクトを新規作成し、テンプレートは「Cross-Platform App(Uno Platform)」を選択して任意の名前を入力します。

 

プロジェクトが作成されたら、ソリューションエクスプローラーから「xxx.Shared」にある「MainPage.xaml」を右クリックし「デザイナーの表示」を選択します。
(xxxはプロジェクト名、以降も同様。本サンプルでは「UnoApp」としています)

開かれたデザイナー下段にある「XAML」に表示されているコードを以下のように変更します。


<Page
   x:Class="UnoApp.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="using:UnoApp"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d">

   <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
       <ScrollViewer>
           <StackPanel Background="AliceBlue" Height="220" Margin="20" Padding="5" VerticalAlignment="Top">

               <TextBlock Text="User ID" Margin="5" />
               <TextBox x:Name="textBox1" Margin="5" />

               <TextBlock Text="Password" Margin="5" />
               <PasswordBox x:Name="textBox2" Margin="5" />

               <Button Content="Login" Click="Button_Click" HorizontalAlignment="Center" Margin="10" Width="100" Height="40"/>

           </StackPanel>
       </ScrollViewer>
   </Grid>

</Page>

XAMLを変更するとデザイナー上段の「デザイン」部分も変更されます。

 

ログイン画面の確認

デザインの変更が確認出来たら、それぞれのプラットフォームで確認してみます。
ソリューションエクスプローラーから確認したいプラットフォーム(xxx.Droid、xxx.iOS、xxx.UWP、xxx.Wasm)を右クリックし 「スタートアップ プロジェクトに設定」を選択、確認したいプラットフォームが太字になったことを確認したら F5 で実行します。

それぞれのプラットフォームの実行例が以下です。

すべてのプラットフォームで同じ画面が表示され、パスワードを入力するとマスクが掛かります。
クロスプラットフォーム開発の利点1つです。

 

クラス作成

次にサーバーから受け取った内容を保持するクラスを作成します。
JSONで処理したいので「ソリューションのNuGetパッケージの管理」から「Newtonsoft.Json」をインストールし、
「xxx.Shared」の直下に「Users.cs」を作成したら、コードを以下のように変更します。す。


using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;

namespace UnoApp.Shared
{
   [JsonObject("Users")]
   class Users
   {
       [JsonProperty("UserId")]
       public string UserId { get; set; }

       [JsonProperty("Name")]
       public string Name { get; set; }
   }
}

 

ログイン画面のコードビハインド

「xxx.Shared」にある「MainPage.xaml.cs」を選択し、コードを以下のように変更します。
プラットフォーム毎の分岐は「#if / #elif / #else」で行われ、今回のコードでは以下となります。

  • 「#if __WASM__」は WebAssenbly で実行された場合の分岐。
  • 「#elif __ANDROID__」は Android で実行された場合の分岐。
  • 「#elif __IOS__」は iOS で実行された場合の分岐。
  • 「#else」は上記以外の分岐。今回は exe(UWP)で実行された場合となる。

using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Popups;
using UnoApp.Shared;
using Newtonsoft.Json;
#if __IOS__
using Foundation;
#endif

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace UnoApp
{
   /// <summary>
   /// An empty page that can be used on its own or navigated to within a Frame.
   /// </summary>
   public sealed partial class MainPage : Page
   {
       public MainPage()
       {
           this.InitializeComponent();
       }

       private async void Button_Click(object sender, RoutedEventArgs e)
       {

           string uid = textBox1.Text;
           string pwd = textBox2.Password;
           string endpoint = string.Format(
               "https://localhost:44340/api/Sample?uid={0}&pwd={1}",
               uid,
               pwd
               );

#if __WASM__

           // WebAssenblyは専用ハンドラを利用します。
           var handler = new Uno.UI.Wasm.WasmHttpHandler();

#elif __ANDROID__

           endpoint = string.Format(
               // Androidエミュレータから localhost にアクセスするには 10.0.2.2 を指定します。
               "https://10.0.2.2:44340/api/Sample?uid={0}&pwd={1}",
               uid,
               pwd
               );

           var handler = new System.Net.Http.HttpClientHandler();
           handler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true;

#elif __IOS__

           endpoint = string.Format(
               // iOSシミュレータは localhost を解析できないようなので実IPを指定します。
               "https://192.168.xx.xx:44340/api/Sample?uid={0}&pwd={1}",
               uid,
               pwd
               );

           var handler = new System.Net.Http.HttpClientHandler();
           handler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true;

#else

           var handler = new System.Net.Http.HttpClientHandler();
           handler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true;

#endif

           try
           {

               System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(handler);
               System.Net.Http.HttpResponseMessage result = await client.GetAsync(new Uri(endpoint));

               string json = await result.Content.ReadAsStringAsync();

               //jsonを解析して結果を取得する
               List<Users> usr = new List<Users>();
               usr = JsonConvert.DeserializeObject<List<Users>>(json);

               string Name = usr[0].Name;

               if (Name == "")
               {
                   var dialog = new MessageDialog($"User ID または Password が違います");
                   await dialog.ShowAsync();
               }
               else
               {
                   // ID・Passクリア
                   textBox1.Text = "";
                   textBox2.Password = "";
                   // 遷移
                   this.Frame.Navigate(typeof(ListPage));
               }

           }
           catch (Exception ex)
           {
               var dialog = new MessageDialog($"エラーが発生しました:" + ex.Message.ToString());
               await dialog.ShowAsync();
           }

       }

   }
}
           

通信準備部分に分岐がありますが、通信やJSON処理、画面遷移は分岐せずに実装できます。
また、今回はシミュレータ等を使用するため分岐がありますが、iOS/Androidを実機とする場合は、「#elif __ANDROID__」と「#elif __IOS__」の分岐は不要です。

 

遷移先画面の作成

「xxx.Shared」を右クリック → 「追加」→「新しい項目」と選択し、表示されたダイアログで「空白のページ」を選択、 「名前」に「ListPage.xaml」と入力し、「追加」を選択します。

 

動作確認

任意のプラットフォームで実行し、「User ID」「Password」を入力、「Login」を押下します。
「ListPage.xaml」の内容が表示されます。

 

次回

次回は「ListPage.xaml」にユーザー一覧の表示、前画面へ戻る。を実装します。

  • 当ページの人物画像はNIGAOE MAKERで作成しました。
一覧に戻る
ゆりちゃん

技術開発推進部ゆりちゃんからのお願い顔マークを押して、技術ブログの
感想をお聞かせください^^