はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

MAUIテンプレートを活用してXamarin.Formsアプリを移植してみよう

前回:
hatsune.hatenablog.jp

前回は、.NET Upgrade Assistantを使って、Xamarin.Formsのアプリを.NET MAUI化してみました。
ソリューション構造は、Xamarin.Formsのままで.NET MAUI化ができましたが、できれば、.NET MAUIのソリューション構造にしておきたいですよね。
理由としては、まったくの私見であり経験則というほどのものでもないのですが、これだけソリューション構造が異なるとすると、将来的なことを考えると.NET MAUIのソリューション構造の形にしておいた方が良いのではないかと思うからです。

.NET MAUIアプリを初期生成する

Visual Studioで「.NET MAUIアプリ」テンプレートを使って、新規アプリケーション作成を「MAUIApp」という名前で実施します。

フレームワークとしては「.NET 7.0」を選択します。

フレームワークを限定する

「.NET MAUIアプリ」テンプレートには、AndroidiOSMacOS、Tizen、WindowsOSの5つのプラットフォームが定義されています。

MAUI.appのTargetFrameworkを限定する

今回は、AndroidiOSのみが必要なので、MAUI.appのTargetFrameworkをAndroidiOSのみにします。
]

Platform定義の削除

ソリューションの「Platforms」フォルダの下からも不要なプラットフォームのフォルダを削除します。

試しにビルド

ビルドを開始しました...
1>------ ビルド開始: プロジェクト: MAUIApp, 構成: Debug Any CPU ------
1>MAUIApp -> C:\Sample\MAUIApp\MAUIApp\bin\Debug\net7.0-ios\iossimulator-x64\MAUIApp.dll
1>MAUIApp -> C:\Sample\MAUIApp\MAUIApp\bin\Debug\net7.0-android\MAUIApp.dll
========== ビルド: 成功 1、失敗 0、最新の状態 0、スキップ 0 ==========
========== ビルド は 10:28 AM に開始され、02:32.818 分 かかりました ==========

無事にiOSAndroidの2つがビルドできました。

移植を始めよう

ここまでが移植するもの関係なく必要な共通作業となります。
それでは、「Xamarin.Formsアプリ」テンプレートで作成したソリューションから移植をしていきましょう。

共通プロジェクト部分


Xamarin.Formsアプリの共通プロジェクト部分である「XamarinApp」部分については、.NET MAUIアプリではプロジェクトが1つになっていることもあって、下記の場所に配置されています。

App.xaml関連

Xamarinでは、App.xaml.csの中でメインページを指定していました。

.NET MAUIでは、AppShellを介してメインページを指定しています。

試しにApp.xaml.csで直接MainPageを指定しても正常に動作します。

AppShellの役目

AppShellには「TabBar」を定義してい複数の画面を切り替えるようなUIを作ることができます。
「FlyoutItem」を定義すればハンバーガーメニューとそこからの画面切り替えUIを作ることができます。
このあたりの画面遷移UIを採用しているのならば、AppShellは残しておいて、将来的にはXamarin.Formsでの実装方法からAppShellでの実装に変えていくと良いかもしれません。
今回は、そこまでは手を入れずにAppShellは残しておいてMainPageの指定にだけ使用しましょう。

画面の移植

Xamarin.Formsでも画面関連は、iOSAndroidで基本同じ定義になるので共通プロジェクト側に入っています。
これをそのまま.NET MAUI側にコピーしていくのが基本ですがいくつか変更が必要です。

XAMLファイル関連

Xamarin.Formsの画面定義である拡張子がxamlXAMLファイル関連の変更点としては名前空間の変更があります。
具体的には、Xamarin.Formsの名前空間「xmlns="http://xamarin.com/schemas/2014/forms"」→MAUIの名前空間「xmlns="http://schemas.microsoft.com/dotnet/2021/maui"」の置換が必要です。

XAML.csファイル関連

usingのところで参照している「Xamarin」「Xamarin.Forms」を「Microsoft.Maui」「Microsoft.Maui.Controls」に変更します。
usingではなくコード本文中で「Xamarin.Forms.~」のように記載している部分があれば、そこも変更が必要です。

Androidのリソースを移植する


.NET MAUIのプラットフォーム共通リソースについて

.NET MAUIはプロジェクトフォルダの直下に「Resources」フォルダがあって、ここにプラットフォーム共通の「アイコン」「起動時スプラッシュ」「文字フォント」「画像」などを格納できます。
Xamarin.Formsのときに共通プロジェクト側においてあるリソースがあれば、ここへの配置を考えてみると良いでしょう。
また、iOSAndroidで分けてリソース管理していたものも、移植を機会に共通化して定義の二度手間が省けるものは省いていくようにリファクタリングすることも計画すると良いかもしれません。

.NET MAUIのAndroid固有リソースについて

.NET MAUIでのAndroid固有リソースは、[Platforms]-[Android]-[Rrsoureces]フォルダにあります。
Xamarin.FormsでのAndroidプロジェクトの[Resouces]フォルダの中身を丸ごとコピーしてしまえば移植は完了です。

Androidの固有定義を移植する

AndroidManifest.xmlを移植する

Xamarin.FormsのAndroidプロジェクトの[Properties]フォルダにある「AndroidManifest.xml」ファイルを、.NET MAUIの[Platforms]-[Android]フォルダの下に上書きコピーします。

MainActivity.csを移植する

Xamarin.FormsのAndroidプロジェクトの「MainActivity.cs」ファイルは、を基底クラスとしているので、それを.NET MAUIの[Platforms]-[Android]フォルダの下に上書きコピーしてしまっては問題が発生します。

内容を抜粋して移植します。
このとき、Xamarin.FormsやEssentialsの初期化コード、LoadApplicationメソッドなどは削除します。

条件付きコンパイルシンボルの調整

MAUI.appにある[ビルド]-[全般]でビルド時のコンパイルシンボルを設定できます。
iOSについては「__IOS__」というシンボルが定義されているのですが、Androidについては「__DROID__」というシンボルが定義されていないので、追加します。

実機実行

Xamarin.Formsアプリをアップグレードしたときと異なり、開発者モードにした実機をUSB接続すればターゲットとして実機がでてきて、すぐにデバッグ実行できます。
なぜかSplashScreenに指定した画像が表示されませんが、それも、Visual Studioを繋げずに実機側でアプリを起動すればきちんと表示されます。

今回は非常にシンプルな(ほとんど何もしない)アプリでしたが、次回はMVVMで作成したXamarin.FomrsアプリからXAMLやロジックをコピーして、.NET MAUIアプリとして再構築を試したいと思います。

次回: