.NET for iOS / AndroidのSDKバージョンを制御する
.NET for iOS / Android、およびMAUI SDKのバージョンを制御する方法が以前より簡単になるという情報を見つけたので書いていきます。
問題
.NET 6以降のiOS/Android SDK管理では、基本的に最新へ上げ続ける事を要求されるようになりました。 つまり、特定のバージョンを使い続けたり、以前のバージョンに戻すことが難しいと言うことです。
特に.NET for iOS SDKのバージョンが上がると、Xcodeのバージョンを上げないとビルドすらできなくなる場合もあり大変困ります。
どうにかするには --from-rollback-file
という非公開のコマンドオプションを駆使して頑張るしかなかったのですが、 dotnet
コマンドの機能が強化されて問題が緩和されたようです。
Workload?
Workload
の中身は、C#のコードをiOS/Androidアプリにするためのビルドツールや、ネイティブAPIのC#ラッパーなどです。
つまり、Xamarin時代では個別にインストールされていたXamarin.iOS / Android SDKに相当します。
.NET 6以降でこれらのSDKは Workload
という仕組みでインストールされます。
Visual StudioとSDKの更新サイクルを分離して、個別にアップデート出来るようにするのが大きな目的です。
dotnet workload
コマンドが用意されており、例えばMAUI SDKをインストールする場合は dotnet workload install maui
を実行します。
dpotnet install
では常に最新のWorkloadがインストールされ、 dpotnet update
でインストール済みのWorkloadを全て最新に更新します。
新機能 ワークロードセット
.NET SDK 8.0.400でワークロードセット(workload sets)機能が追加されバージョンを指定してインストールや更新ができるようになります。
.NET SDK ワークロード セット - .NET CLI | Microsoft Learn
これにともない、各Workloadをマニフェストから取得される最新バージョンへ個別に更新する manifests
戦略か、ワークロードセットのバージョンに揃えて更新する workload-set
戦略かを選べるようになります。 dotnet workload config --update-mode
で現在の更新戦略を確認や変更が可能です。
また、 dotnet workload install
や dotnet workload update
の際にバージョン指定することで、更新方法が自動的に workload-set
戦略に切り替わるようです。
ワークロードセットのバージョンというのがちょっと分かりにくいのですが、複数のWorkloadにまたがる世代を表すバージョン番号ととらえると良い気がします。 利用可能なワークロードセット バージョンの確認方法が課題ですが、将来的には一覧で確認できるようにしてくれるそうです。
以前のバージョン固定方法
おまけとして、ワークロードセット機能が追加される以前の環境で、頑張ってWorkloadのバージョンを固定する方法も載せておきます。 .NET 7時代に調べた内容なのでコマンド実行結果などに出てくるバージョンが古いですがご容赦下さい。
アンドキュメントな方法でバージョンを指定する
実は workload install
と workload update
には --from-rollback-file
という隠しパラメータが存在していて、所定のフォーマットのjsonファイルを与えるとバージョン指定が出来ます。
ロールバックファイルの中身はこんな感じ。
json
{
"microsoft.net.sdk.maui": "7.0.52",
}
コマンド実行する時はこんな感じになります。
workload install maui --from-rollback-file rollback.json
先行事例に倣って"microsoft.net.sdk.maui"と指定しましたが、実験したところ代わりにWorkload IDの"maui"を使っても大丈夫でした。
参考
ドキュメント化しないと明言されているissue
Add
workload install --from-rollback-file
documentation · Issue #28226 · dotnet/docs
MAUIのバージョンを固定したいと相談しているissue
How do I Pin a Maui App to a specific version? · Issue #8985 · dotnet/maui
ロールバックファイルで指定する内容
ロールバックファイルで指定するバージョンをいくつにしたら良いか?
大抵の場合は安定環境にインストールされているバージョンをメモして、それを利用するのが良さそうです。
WindowsでVisual Studioをインストールした環境で dotnet workload list
を実行すると以下のような結果となりました。
```
インストール済みワークロードの ID マニフェストのバージョン インストール ソース
maui-android 7.0.52/7.0.100 VS 17.4.33213.308 android 33.0.4/7.0.100 VS 17.4.33213.308 maui-windows 7.0.52/7.0.100 VS 17.4.33213.308 maui-maccatalyst 7.0.52/7.0.100 VS 17.4.33213.308 maccatalyst 16.1.1477/7.0.100 VS 17.4.33213.308 maui-ios 7.0.52/7.0.100 VS 17.4.33213.308 ios 16.1.1477/7.0.100 VS 17.4.33213.308 ```
消せないWorkload
WindowsでVisual Studioをインストールしている環境では関連するWorkloadをアンインストールできなくなるようです。
「インストールソース」で頭に"VS"が付いてるものをアンインストールしようとすると、見つからない(実際にはインストールされている)扱いとなるので特別扱いされます。
"ロールバックファイルで指定する内容"の状態からmaui
とios
のWorkloadをインストールするとこのようになります。
```
インストール済みワークロードの ID マニフェストのバージョン インストール ソース
ios 16.2.1024/7.0.100 SDK 7.0.100, VS 17.4.33213.308 maui 7.0.59/7.0.100 SDK 7.0.100 ```
この後、maui
とios
のWorkloadをアンインストールできますが、maui
のそのままリストから消えるのに対し、ios
の方は「インストールソース」の"SDK 7.0.100"部分だけ消えてWorkload自体は残ります。
CIなどを考える場合、WindowsではVisual Studioをインストールせずに.NET SDK、Workloadだけを直接インストールしたビルド専用マシンにするのが良さそうです。
Workload Manifest
WorkloadのIDやバージョンはWorkload Manifestに定義されています。 ManifestファイルはNuGetで配布されていて、dotnetコマンドはこれを自動的に取得して有効なIDか、新しいバージョンがあるかなどを判別しているようです。
nuget.orgで"Microsoft.NET.Sdk"と検索するとそれらしいのが沢山ヒットします。
命名規則は次のようになっているようで......
Microsoft.NET.Sdk.<プラットフォーム>.Manifest-<.NET SDKバージョン>
.NET 7.0.1xx系で利用可能なiOS開発用SDKの場合は Microsoft.NET.Sdk.iOS.Manifest-7.0.100
という具合ですね。
中身には WorkloadManifest.json
という名前でマニフェストファイルの実体が入っています。
フォローしませんか?
お気軽にご依頼・ご相談ください