はじめに
こんにちは、@hiro128_777です。
この記事は「Xamarin Advent Calendar 2019」の22日目になります。
最近何かと話題の Uno Platform ですが、iOS, Android に関しましては内部的には Xamarin を利用していると言うことですので、気になっているのでちょっと触ってみました。
私は、Xamarin.iOS が大好きなので、Xamarin.iOS との関係、特に registar.m の生成が Xamarin.Forms の iOS アプリとどう違うかを調べてみました。
作ってみたアプリ
registar.m を調べるにはとにかく実機ビルドしなければいけませんので、超簡単なサンプルを作って早速ビルドしてみました。
そして同じアプリを Xamarin.Forms でも作ってビルドしました。
registar.m の比較
Uno Platform と Xamarin.Forms で生成された registar.m を比較してみましょう。
registar.m についてはレジストラーを使えるようにするための仕組みですのでこちらの公式ドキュメントも是非ご参照ください。
docs.microsoft.com
起動時に読み込むアセンブリの比較
比較しやすいように実際の registar.m と順番を変えています。
Uno Platform
static const char *__xamarin_registration_assemblies []= { "UnoSampleApp", "mscorlib", "Uno", "Uno.Core", "Uno.Foundation", "Uno.UI", "Uno.UI.Toolkit" "Uno.Xaml", "Xamarin.iOS", "Mono.Security", "System", "System.Xml", "System.Numerics", "System.Core", "System.Net.Http", "System.Drawing.Common", "System.Data", "System.Runtime.Serialization", "System.Runtime.CompilerServices.Unsafe", "System.ServiceModel.Internals", "System.Web.Services", "System.Xml.Linq", "System.Collections.Immutable", "Microsoft.Practices.ServiceLocation", "Microsoft.Extensions.Logging.Abstractions", "Microsoft.Extensions.Logging", "Microsoft.Extensions.DependencyInjection.Abstractions", "Microsoft.Extensions.Logging.Filter", "Microsoft.Extensions.Primitives", "Microsoft.Extensions.Logging.Console", "Microsoft.Extensions.Configuration.Abstractions", };
Xamarin.Forms
static const char *__xamarin_registration_assemblies []= { "XFSampleApp.iOS", "XFSampleApp", "mscorlib", "Xamarin.Forms.Platform", "Xamarin.Forms.Platform.iOS", "Xamarin.Forms.Core", "Xamarin.Forms.Xaml" "Xamarin.iOS", "Mono.Security", "System", "System.Xml", "System.Numerics", "System.Core", "System.Net.Http", "System.Drawing.Common", "System.Data", "System.Runtime.Serialization", "System.ServiceModel.Internals", "System.Web.Services", "System.Xml.Linq" };
比べてみると、Xamarin.Forms の方がだいぶ少ないですね。Uno Platform は、iOS の UI コンポーネントを UWP の UI コンポーネントの API で利用できるように、かなりの量のコードを書いています。この部分が丸々乗っかって来てるので、起動時に必要なアセンブリが多くなっています。
トランポリンの数の比較
トランポリンは C# 側のハンドラーメソッドを、Objective-C のランタイム側から引数をマーシャリングして呼ぶ仕組みです。
詳しくはこちらをご覧ください。
また、こちらの公式ドキュメントも参考になります。
docs.microsoft.com
Uno Platform : 124
Xamarin.Forms : 163
Uno Platform がかなり少ないですね。トランポリンの分布は調べるのがかなりしんどいので調べていません。
Class Map の 登録
Class Map は C# 側のオブジェクトで、Objective-C のランタイム側からアクセスする必要があるものを起動時に Objective-C のランタイムに登録する仕組みです。
Uno Platform : 486
Xamarin.Forms : 340
Uno Platform がかなり多くなっています。これも、Uno が、iOS の UI コンポーネントを UWP の UI コンポーネントの API で利用できるように、かなりコードを書いていることに起因しています。
まとめ
Uno Platform と Xamarin.Forms を、registar.m から比較してみましたが、最終的にどちらも Xamarin.iOS を利用しているので、その観点からは大きな差はないことがわかりました。もう少し何か出るかと思って調べてみましたが、単に使っている UI コンポーネントのライブラリが違うだけと言うそのままの結果でした。
Xamarin.iOS の上に、Uno Platform または、 Xamarin.Forms が乗っているという構成は全く同じですので、UWP の XAML を使いたいのか Xamarin.Forms の XAML を使いたいのか、あとは SPA も一緒に生成したいかでどちらを使うか決めればよいと思います。
@tan-yさんも仰っていましたが、Uno Platform は、UI コンポーネントの定義とレンダリングが分離されていません。よってカスタムでレンダリングしたいときに Xamarin.Forms のように比較的戦略的に機能を追加するのは難しく、あまり自分でカスタマイズして使う前提ではないのかも知れません。Uno Platform の FAQ にも、 UWP で提供されている全ての API を 様々なプラットフォーム上に展開するのがゴールだとあるので、カスタマイズは方向性として違うのだと思います。
Uno Platform は、UWP の各デバイスへの展開
Xamarin.Forms は、各デバイスの UI コンポーネントを統合して抽象化
なので、同じ XAML を使っていても、そもそもの思想が違うようです。
ですが、Uno Platform が Xamarin.iOS, Xamarin.Android を使用しているのも、Xamarin.iOS, Xamarin.Android がプラットフォームのブリッジとして、とてもよくできているからだと思っています。Xamarin.Forms がそれ自体の実装に、iOS, Android のブリッジを持たず、Xamarin.iOS, Xamarin.Android の上に乗せる形になっているのも、とても素晴らしい設計です。
Uno Platform と Xamarin.Forms は方向性が違うので今後の発展がとても楽しみです。また時間をとって、もっと色々調べてみたいです。
今回生成した、registar.m こちらなのでよろしければご覧くださいませ。
Uno Platform
Xamarin.Forms
以上です。