【C#】Uno Platformを使ってみた

1. Uno Platform

Uno Platform は Windows, iOS, Android, Web 上で動くアプリケーションを開発できるクロスプラットフォームです。

platform.uno

Xamarinと似ていますが、いくつか違う点があります。一番はUWP/WPFと同じような形式でXAMLが書けることです。これによって、今までWindowsアプリを作っていた人が簡単にモバイル向けアプリのコーディングができるようになります。他にもいい点がありますが、ちょまどさんの記事を参考にするといいと思います。必要な環境構築も丁寧に書いてありますので...。

qiita.com

2. アプリをつくってみた

今回作成したアプリは「新型コロナウイルス感染症対策サイトへアクセスするためのツール」です。

github.com

このサイトは東京をメインに北海道や鹿児島県などの多岐にわたる地域に派生しています。派生先のURLはGithub上で共有されており、一般の人が探すにはちょっとハードルが高いと思います。そこで、見たいときに他県の情報もみれるようなアプリを作りたいと思います。

2.1 デザイン - XAMLコード

まずはデザインですね。Uno Platformには4つの各プラットフォーム向けプロジェクトと統合された1つの Shared というプロジェクトが生成されます。この Shared に書き込むことによって、どのプラットフォームにも反映されます。

Gridで要素を分割することで、WebViewによる全画面表示を防いでいます。

<Page
    x:Class="StopCOVID19ViewerApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:StopCOVID19ViewerApp"
    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}">
     <Grid.RowDefinitions>
            <RowDefinition Height="12*"/>
            <RowDefinition Height="1*"/>
     </Grid.RowDefinitions>
      <WebView x:Name="webView" Grid.Row="0"/>
      <TextBlock Text="地域の選択" Grid.Row="1" Margin="30 15" FontSize="16"/>
      <ComboBox x:Name="SelectBox" PlaceholderText="東京都" Grid.Row="1" Width="150" Height="30" Margin="130 10"/>       
      <Button Content="更新" x:Name="buttonRefresh" Grid.Row="1" Click="ButtonRefresh_Click" Margin="300 10 10 30"/>
     </Grid>
</Page>

2.2 ロジック - C#コード

今のところ例外処理などはあまり考えていません...。Dictionary に公開されている県とそのURLを追加して、それをXAMLから参照しています。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

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

namespace StopCOVID19ViewerApp
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        WebSiteURLs webSite = new WebSiteURLs();

        public MainPage()
        {
            this.InitializeComponent();
            this.SetComboBoxItems();
        }

        protected void SetComboBoxItems()
        {
            foreach (var item in webSite.prefecture.Keys)
                SelectBox.Items.Add(item.ToString());
        }

        private void ButtonRefresh_Click(object sender, RoutedEventArgs e)
        {
            string valueFromCB = SelectBox.SelectedValue.ToString(); //コンボボックスから選択されたアイテムの取得
            string valueFromDic = webSite.prefecture[valueFromCB];
            var uri = new Uri(valueFromDic);
            webView.Navigate(uri);
        }
    }

    public class WebSiteURLs
    {
        public Dictionary<string, string> prefecture = new Dictionary<string, string>();

        public WebSiteURLs()
        {
            //都道府県を登録しておく
            prefecture.Add("北海道", "https://stopcovid19.hokkaido.dev/");
            prefecture.Add("埼玉県", "https://stopcovid19.e-toda.jp/");
            prefecture.Add("千葉県", "https://chiba-covid19.mypl.net/");
            prefecture.Add("東京都", "https://stopcovid19.metro.tokyo.lg.jp");
            prefecture.Add("神奈川県", "https://www.pref.kanagawa.jp/osirase/1369/");
            prefecture.Add("山梨県", "https://stopcovid19.yamanashi.dev/");
            prefecture.Add("岐阜県", "https://covid19-gifu.netlify.com/");
            prefecture.Add("愛知県", "https://stopcovid19.code4.nagoya/");
            prefecture.Add("三重県", "https://covid19-mie.netlify.com/");
            prefecture.Add("兵庫県", "https://stop-covid19-hyogo.org/");
            prefecture.Add("愛媛県", "https://ehime-covid19.com/");
            prefecture.Add("岡山県", "https://covid19-okayama.netlify.com/");
            prefecture.Add("鹿児島県", "https://covid19.codeforkagoshima.dev/");
        }
    }
}

3. 実行結果

プラットフォーム(OS)によってプロジェクトがわかれているので、スタートアッププロジェクトの設定を行ってやります。

3.1 Androidで実行してみた

ボタンが隠れてしまっていますね...。ロジックは順調に動いています。

f:id:takunology:20200318153942p:plain

3.2 iOS で実行してみた

実はXAMLiOSに合わせているので、当然ながら問題ないですね。

f:id:takunology:20200319023507p:plain

3.3 UWPで実行してみた

ボタンやコンボボックスは左下表示されています。問題なく動きます。

f:id:takunology:20200318153829p:plain

3.4 Webで実行してみた

一番下のウィンドウが Edge, 左が Chrome, 右が Firefoxです。 更新ボタンを押しても何も表示されません。Webに対してWebViewは対応していないのでしょうか?

f:id:takunology:20200319023710p:plain

4. おわりに

1つのファイルを書きかえるだけですべてのプラットフォームに対応するなんて素晴らしいです!感動しました。ただWebで表示できなかった理由が分かりませんでした。

マジですごいですね。これ。

参考ページ

Uno Platformを初めて使うならこちらのページがオススメです。後はWPFまたはUWPのXAMLとコードビハインドの書き方を調べれば作れます!

qiita.com

qiita.com