ぴーさんログ

だいたいXamarin.Formsのブログ

【Xamarin → .NET 6+(MAUI)移行】 csprojファイルに書くと良いかも知れない設定 3選

Xamarin.FormsアプリをMAUIへ移行する際にプロジェクトファイル(csproj)を直接編集して設定変更することが度々ありました。 今回はその中で利用機会のありそう3点をご紹介します。

  • プラットフォーム固有のソースファイル指定
  • (MAUI向け) XamlC強制
  • HttpHandler設定

プラットフォーム固有のソースファイル指定

1つのプロジェクトで複数プラットフォーム向けのアプリをビルドする場合におすすめの設定です。 MAUIで特に有効ですが、SDKスタイルのプロジェクト全般で利用できるためマルチプラットフォーム向けライブラリを作る際にも役立ちます。

csprojファイルを編集して<Project>要素の直下に追加します。

<!-- ターゲットがAndroidの場合だけ .Android.cs をコンパイルするようにする -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'android'">
    <Compile Remove="**\**\*.Android.cs" />
    <None Include="**\**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
<!-- ターゲットがiOSの場合だけ .iOS.cs をコンパイルするようにする -->
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) != 'ios'">
    <Compile Remove="**\**\*.iOS.cs" />
    <None Include="**\**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

説明

ファイルの命名規則を利用して、特定のプラットフォームの場合にのみコンパイルするファイルを制御できるようにします。 これにより、ソースコードが #if だらけで読みにくくなることを防ぐことができます。

特にMAUIでカスタムViewやカスタムHandlerを書く場合、ネイティブコントロールを扱うためのプラットフォーム固有のコードが大きくなるため、ファイル分割の恩恵も大きくなります。 例えば、このようにファイル分割します。 *.cs に共通なプロパティ定義などを書き、 *.<プラットフォーム名>.cs でネイティブコントロールのプロパティに伝播させるイメージです。

  • CustomViewHandler.cs
  • CustomViewHandler.Android.cs
  • CustomViewHandler.iOS.cs

余談

実は指定内容が「"◯◯以外"の場合、".◯◯.cs"を除外する」というややこしい物になっています。 これはデフォルト設定が「".cs"を全て含める」と指定しているのを打ち消すためです。

(MAUI向け) XamlC強制

MAUIプロジェクトの場合にのみ有効な設定です。 Xamarin.Formsの頃と比較してデバッグ実行時の画面遷移が遅くて困っている場合にお試しください。

csprojファイルを編集して<Project>要素の直下に追加します。

<PropertyGroup>
    <!-- MAUIのデフォルト設定を変更して、Debugビルドでも事前コンパイル済みのXAML読み込みを利用するようにしてViewの初期化を高速化します。 -->
    <!-- 代わりにコンパイル時間が伸びるため、繰り返しビルドする場合や実行時の速度が重要でない場合はコメントアウトしてください。 -->
    <MauiXamlCValidateOnly>False</MauiXamlCValidateOnly>
    <_MauiForceXamlCForDebug>True</_MauiForceXamlCForDebug>
</PropertyGroup>

説明

Xamarin.Formsには、XAMLの定義内容を事前コンパイルして実行時の初期化処理を速くする機能があります。 この機能はMAUIにも引き継がれましたがデバッグ時の挙動が変わっており、実行時にはXAMLの解析しながら初期化するため遅くなり、事前コンパイルはエラー検証のために使うようになりました。 この変更は、XAMLコンパイル結果をアプリに組み込む工程を省略することで、繰り返しビルドを速くするためのようです。

画面の初期化が遅すぎてデバッグ時の動作検証に支障がある場合、上の設定を使ってみてください。

HttpHandler設定

Xamarinで HttpClientHandler を使っていたプロジェクト向けの設定です。必要な場合のみ利用してください。

csprojファイルを編集して<Project>要素の直下に追加します。

<PropertyGroup>
    <UseNativeHttpHandler>false</UseNativeHttpHandler>
<PropertyGroup>

説明

Android/iOSネイティブのHTTP通信実装ではなく.NET由来のHTTP通信実装を使いたい場合、Xamarinでは HttpClientHandler を利用すると実現できました。 一方、.NET 6以降ではUseNativeHttpHandlerの設定によって HttpClientHandler の挙動が変わるため同じようにはいきません。

true(デフォルト)の場合、内部でネイティブのHTTP通信実装が使われてしまうため、Xamarinの挙動に近づけるためにfalseに変更する必要があります。 falseの場合でも、Xamarin(Mono)と.NETではHttpClientHandlerの実装が異なるため、期待と異なる挙動をする可能性があります。 その場合はGitHubでそれぞれリポジトリを調べてみてください。