個人的なメモ

Tomohiro Suzuki @hiro128_777 のブログです。Microsoft MVP for Developer Technologies 2017- 本ブログと所属組織の公式見解は関係ございません。

iOS で Uno Platform と Xamarin.Forms の registar.m を比べてみました。

はじめに


こんにちは、@hiro128_777です。


この記事は「Xamarin Advent Calendar 2019」の22日目になります。

最近何かと話題の Uno Platform ですが、iOS, Android に関しましては内部的には Xamarin を利用していると言うことですので、気になっているのでちょっと触ってみました。

私は、Xamarin.iOS が大好きなので、Xamarin.iOS との関係、特に registar.m の生成が Xamarin.Forms の iOS アプリとどう違うかを調べてみました。


作ってみたアプリ


registar.m を調べるにはとにかく実機ビルドしなければいけませんので、超簡単なサンプルを作って早速ビルドしてみました。

f:id:hiro128:20191222174415p:plain

そして同じアプリを 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 で利用できるように、かなりコードを書いていることに起因しています。



サンプルアプリの ipa のサイズ


Uno Platform : 13.5MB
Xamarin.Forms : 8.7MB


f:id:hiro128:20191222231906p:plain


上記のようになりました。 Uno Platform の方がアセンブリの数が多いので、順当な結果です。実際に大きいアプリになればフレームワークの容量はあまり関係ないので、そこまで気にするほどではないと思います。


まとめ


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


以上です。