頭ん中

しがないITエンジニアが、考えた事を書きます。

Uno Platformを試す

XAMLひとつでWindows/iOS/Android/WebAssemblyに対応という夢のような話です。 f:id:siamcats:20200206025122p:plain

Create a Single Page App with Uno

既にチュートリアルのやってみた系記事はあるので、いくつか躓いたところと、良くあるXAMLのデザインテンプレートが実際どんな感じになるか紹介したいと思います。

環境

  • Windows 10 バージョン1909
  • Visual Studio 2019 バージョン16.4.3
  • Uno Platform バージョン2.0.532

Hello Worldまで

  • 拡張機能からUno Platformを探してインストールします。 f:id:siamcats:20200210110139p:plain
  • NuGetから以下の各パッケージを確認してください。
    • Uno.CoreUno.UIUno.Wasm.Bootstrapを最新の安定版にアップデート。
    • Refractored.MvvmHelpersを各プロジェクトにインストール。 f:id:siamcats:20200210105539p:plain
    • Microsoft.Extensions.Logging.Consoleアップデートしないこと。 f:id:siamcats:20200210105746p:plain
  • ソリューションを一旦閉じて開きなおします。

ここまでやってビルドすればHello Worldです。XAMLを編集すればホットリロードもできると思います。その後もチュートリアルを進めるとコードビハインドやModel部分の実装例が続きます。

詰まったこと

ホットリロードできない

  • NuGetでRefractored.MvvmHelpers入れた後、再起動してないから。

Wasmが起動できない

  • Wasmの起動時に例外DirectoryNotFoundExceptionが出る。
  • Issueを探すと.NET Coreランタイムの2.2が必要とあった。
    • コマンドプロンプト>dotnet --list-sdks→確かに2.2が入ってなかった。
    • ココから落としてインストールする。
    • 再起動するも現象変わらず。
  • Gitter{ユーザー名}\AppData\Local\Temp\mono~を消すとGoodみたいな過去ログあり。
    • VS閉じてTemp配下の関連ファイルを削除後、ソリューション開いて再ビルド。
    • 無事起動した。
  • 起動時エラーからは推察できないんですが、ソリューション開いた時の出力に.NET Coreのインストールバージョンチェックが出てきてるみたいです。気が付かなかった。

XAMLデザインを試す

ここではUWPアプリのデファクトスタンダード的デザインNavigationViewで試してみたいと思います。

試したXAML

<NavigationView>
    <NavigationView.MenuItems>
        <!--シンボルアイコン-->
        <NavigationViewItemHeader Content="Symbols" />
        <NavigationViewItem Content="フレンド" Icon="People"/>
        <NavigationViewItem Content="メッセージ" Icon="Read"/>
        <NavigationViewItem Content="ToDo" Icon="Bullets"/>
        <NavigationViewItemSeparator/>
        <!--フォントアイコン-->
        <NavigationViewItemHeader Content="Font Icons"/>
        <NavigationViewItem Content="Wi-Fi" >
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE701;" FontFamily="Segoe MDL2 Assets"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>
        <NavigationViewItem Content="保存">
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE74E;" FontFamily="Segoe MDL2 Assets"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>
        <NavigationViewItem Content="ゴミ箱" >
            <NavigationViewItem.Icon>
                <FontIcon Glyph="&#xE74D;" FontFamily="Segoe MDL2 Assets"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>
        <!--シェイプで描いたアイコン-->
        <NavigationViewItemSeparator/>
        <NavigationViewItemHeader Content="Shape Icons"/>
        <NavigationViewItem Content="Facebook">
            <NavigationViewItem.Icon>
                <PathIcon Data="M11.344,5.71c0-0.73,0.074-1.122,1.199-1.122h1.502V1.871h-2.404c-2.886,0-3.903,1.36-3.903,3.646v1.765h-1.8V10h1.8v8.128h3.601V10h2.403l0.32-2.718h-2.724L11.344,5.71z" />
            </NavigationViewItem.Icon>
        </NavigationViewItem>
        <NavigationViewItem Content="Twitter" >
            <NavigationViewItem.Icon>
                <PathIcon Data="M18.258,3.266c-0.693,0.405-1.46,0.698-2.277,0.857c-0.653-0.686-1.586-1.115-2.618-1.115c-1.98,0-3.586,1.581-3.586,3.53c0,0.276,0.031,0.545,0.092,0.805C6.888,7.195,4.245,5.79,2.476,3.654C2.167,4.176,1.99,4.781,1.99,5.429c0,1.224,0.633,2.305,1.596,2.938C2.999,8.349,2.445,8.19,1.961,7.925C1.96,7.94,1.96,7.954,1.96,7.97c0,1.71,1.237,3.138,2.877,3.462c-0.301,0.08-0.617,0.123-0.945,0.123c-0.23,0-0.456-0.021-0.674-0.062c0.456,1.402,1.781,2.422,3.35,2.451c-1.228,0.947-2.773,1.512-4.454,1.512c-0.291,0-0.575-0.016-0.855-0.049c1.588,1,3.473,1.586,5.498,1.586c6.598,0,10.205-5.379,10.205-10.045c0-0.153-0.003-0.305-0.01-0.456c0.7-0.499,1.308-1.12,1.789-1.827c-0.644,0.28-1.334,0.469-2.06,0.555C17.422,4.782,17.99,4.091,18.258,3.266"/>
            </NavigationViewItem.Icon>
        </NavigationViewItem>
    </NavigationView.MenuItems>
</NavigationView>

結果はこんな感じ

f:id:siamcats:20200210212857p:plainf:id:siamcats:20200210141830p:plain

f:id:siamcats:20200210173300p:plain

ほぼほぼそのままの見た目で動作しています。IsBackButtonVisible="Collapsed"PaneDisplayMode="Top"などのプロパティも各プラットフォームでしっかり効いてます。

ボタンアイコンについては、Symbolに対応しているので表示されますが、環境依存のフォントは当然ながら駄目です。Webも含めたマルチプラットフォーム前提ならSVG Pathで描くべきでしょうか。

感想

Xamarinと比べると、UWPアプリとしてのUIを作ればそのままマルチプラットフォームで動いてくれる感じです。試していくとResourceDictionary使えなかったりなんだりといろいろ出てきますが、コミュニティの活動は活発で今後のロードマップも壮大なので、今後に注目です。

凝ったアニメーションやデザイン要件は皆無だけど無駄にマルチプラットフォームにしたいみたいなネイティブアプリ案件なら(そういうのこそEnterprisyなWindowsに多いので)現時点でも選択肢になると思いました。