Uno Platform 概要

Uno Platform は、オープンソースで開発されているクロスプラットフォームのアプリケーションを開発するためのライブラリです。Apache 2.0 ライセンスで提供されています。
Uno Platform で作ったアプリケーションは iOS/Android/Windows/WebAssembly で動作するアプリケーションを作ることが出来ます。

Uno Platform の公式サイトは以下になります。

[Uno Platform](https://platform.uno/)

この Uno Platform は、Windows 10 向けのアプリケーション開発プラットフォームである Universal Windows Platform (以降 UWP) 向けに記述されたソースコードを Android/iOS/WebAssembly 向けにもビルド出来るような互換レイヤーを提供するというアプローチで作られています。
そのため、Visual Studio の提供する UWP 向けのデザイナー、デバッガー、コード補完機能などの恩恵をフルに受けながら Android/iOS/WebAssembly などの Windows 以外のプラットフォーム向けのアプリケーションの開発が出来ます。

![visual_studio_window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/f181155a-da4e-1010-bc0b-6c5082abaf2d.png)

実際に試せるサンプルとして Windows 10 の電卓アプリケーションを Uno Platform で Android/iOS/WebAssembly に移植しているサンプルがあります。
このサンプルは GitHub で以下の URL で公開されています。

[Uno Calculator](https://github.com/unoplatform/calculator)

このサンプルをダウンロードしてビルドして実行してみました。実際に UWP/Android/iOS/WebAssembly の全てのプラットフォームで完全に動作する電卓が実現できています。

![uno_calc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/7069be3b-140e-9a98-7190-c134b8efcdc0.png)

## Uno Platform の仕組み

Uno Platform の仕組みについて説明します。Uno Platform は UWP 向けに記述されたソースコードを Android/iOS/WebAssembly 向けにもビルド出来るように中間レイヤーを作ったものという説明をしました。Android アプリの場合を例に少し詳しく説明します。

Uno Platform のプロジェクトを作成して Android 向けのプロジェクトを開くと Uno.UI という NuGet パッケージへの参照が追加されています。この Uno.UI に UWP の API と同じインターフェースを持ったクラス群が定義されています。
Uno.UI では Xamarin.Android を使って Android 向けの画面を表示するように UWP の各種 API を実装されています。iOS も同様に Uno.UI が Xamarin.iOS を使って UWP の API を実装しています。WebAssembly でも Uno.UI が最終的な HTML への変換を行っています。

WebAssembly 版の Uno Calculator をブラウザーの開発者ツールで覗いてみると、Standard という TextBlock コントロールで定義されている文字列が、実際には HTML の p タグになっています。

![uno_calc_html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/530d550b-58d2-ccb4-b10e-14b16583b3fc.png)

ここまでの話をまとめた図が Uno Platform の公式サイトにあります。

![uno_diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/c4812140-42c7-e359-6546-d7add67f605f.png)

この図は Uno Platform の公式サイトの HOW IT WORKS (https://platform.uno/how-it-works/) にある図です。
一番右の Android の列を見てみると、アプリケーションコード（開発者が書く C# + XAML）の下に Uno という互換レイヤーがあり、その下に Xamarin があります。
最下層の mono は、Xamarin が使っているランタイムです。iOS も Android と同じ方式になっています。
WebAssembly は Xamarin が無いので、直接 mono のラインタイムを使って WebAssembly 上で動いていることがわかります。一番左の UWP は、もともとのアプリケーション コードが UWP なので、そのまま UWP として動きます。

このようにして、Uno Platform では UWP 向けに書いたプログラムを全てのプラットフォームで動くようにしています。

本書では説明しませんが、ここで紹介したプラットフォーム以外にも macOS などの他のプラットフォーム向けの実装も開発中なので将来的には、より多くのプラットフォームで動くようになることが期待できます。

## Uno Platform の利点

Uno Platform は WPF/UWP の開発に慣れ親しんだ人が、そのノウハウを最大限に活用しながら Windows 以外のアプリケーションを開発することが出来ます。
WPF/UWP と同じように開発出来るので、ContentControl や DataTemplate や DataTemplateSelector、データ バインディングなどの機能を利用することが出来ます。

また、ネイティブ コントロールを直接表示することも出来ます。
例えばボタンを普通に使うと UWP のような見た目のボタンが Android/iOS でも表示されますが、ネイティブのコントロールを ControlTemplate に設定したスタイルが Uno Platform で定義されているので、そのスタイルを適用することで見た目をネイティブのボタンにすることが出来ます。

以下の図はボタンとトグルにデフォルトの見た目と、ネイティブの見た目を適用したものを並べたものです。

![uno_nativestyle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/b659e841-166b-8ff2-7be8-196860991cd0.png)

特筆すべき事項として、この見た目がデフォルトのものとネイティブのもので Button と NativeButton のように別のコントロールが提供されているのではなくコントロールのスタイルを変えるだけで見た目の変更が出来るようになっています。

UI コントロール以外の UWP の API は、Uno Platform では多くがサポートされていません。
対応しない API を呼んだ場合はコンパイル時に警告が出ます。そのまま実行は出来ますが、実際に動作はせず常に同じ値を返すか NotImplementedException が発生します。

例えばファイルを開くダイアログを出してユーザーにファイルを選択してもらう機能を提供する FileOpenPicker クラスは Android/iOS などでは実装がされていません。そのため FileOpenPicker のプロパティやメソッドを呼び出すと NotImplementedException が発生します。
実装されている機能については、ドキュメント上に記載があるので使用したい API については事前に確認をお勧めします。

また、実装されていない機能を呼び出すと Uno0001 の警告が発生します。警告が出ている場合は確認しておきましょう。

![uno_notsupportedapiswarn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/4cea74cd-000e-ddec-3035-01cec9c4bcfa.png)

警告は出ているが実際には問題ない場合は警告の出ている行で Ctrl + . を押すことで警告を抑止することが出来ます。
実際に Visual Studio で警告を抑止したときに生成されるコードを以下に示します。

```csharp
#pragma warning disable Uno0001 // Uno type or member is not implemented 
    if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
#pragma warning restore Uno0001 // Uno type or member is not implemented
```

## まとめ

この記事では、Uno Platform の紹介と、クロスプラットフォームで動く仕組みについて説明しました。
最終的には Xamarin.Android/Xamarin.iOS/WASM 上で直接動くので性能面でもネイティブアプリに遜色ない処理速度が出ることが期待できます。
また、UWP の開発と同様に Visual Studio による高機能な支援機能の恩恵をフルに受けることが出来ます。


## ちょまどさんからの一言

(*ﾟ▽ﾟ* っ)З うのぷらっとふぉーむ！

つまり、Uno Platform を使えば、大好きな C# + XAML だけで

1. iOS アプリ
2. Android アプリ
3. Web アプリ（WebAssembly）
4. Windows 10 アプリ (UWP)

が一気に効率良くクロスプラットフォーム開発できるってことだよね！　それってすごい！

あと、UWP アプリのコードを書くだけで上記 4 プラットフォームで動くということで、
今まで UWP / WPF の開発をしてきている人が、そのノウハウを最大限に生かして開発できるのも良いね！
例えば (同じく C# クロスプラットフォーム開発フレームワークでありよく比較対象に挙がる) Xamarin.Form の XAML 記法は UWP とかの記法と違う独自記法だけど、Uno Platform は UWP と同じように書けるね。

これからどんどん読み進めるのがワクワクだね、一緒に楽しもうね！