macOS・Xcode・Visual Studio を最新化したら、.NET MAUI の「iOS シミュレータだけ」ビルドが落ちる――2025年の現場で多発しているこの相談に、原因の切り分けから恒久対策までを一気通貫で整理します。iOS 18/Xcode 16 の要件変更と .NET MAUI のサポート方針が交差する“沼ポイント”を避け、今後の運用を安定させるための実践ノウハウを具体的に提示します。
iOS 18 + Visual Studio 最新環境で「シミュレータのみ失敗」になる背景
最新環境へアップデート後、iOS シミュレータ向けビルドで次のようなリンクエラーが発生します。
clang++ exited with code 1:
Undefined symbols for architecture arm64:
"_xamarin_is_object_valid", referenced from: <initial-undefines>
"_xamarin_is_user_type", referenced from: <initial-undefines>
ld: symbol(s) not found for architecture arm64
実機ビルドは成功するのに、シミュレータだけが失敗するのはレジストラ(registrar)の違いが主因です。一般に、.NET for iOS は「実機=静的レジストラ(static registrar)」「シミュレータ=動的レジストラ(dynamic registrar)」を既定で使い分けます。動的レジストラ経由で必要となるネイティブシンボル(_xamarin_is_object_valid など)と、インストール済みの iOS ワークロード/Xcode SDK 側のバイナリが噛み合わないと、上記のような Undefined symbols で落ちます。
まず押さえるべき3つの事実
- .NET MAUI 8 のサポートは 2025‑05‑14 に終了しています。以降はセキュリティ修正や新しい Xcode への追随が提供されません。
- 2025‑04‑24 以降の App Store 提出は Xcode 16 以降必須(iOS 18 SDK 等)です。旧 Xcode ではアップロード自体ができません。
- .NET MAUI 9 は Xcode 16/iOS 18 を公式サポートします。開発マシンは macOS 14.5+ が前提です。
結論:恒久対策は「.NET MAUI 9 へアップグレード」
サポートが継続し、Xcode 16/iOS 18 と整合するのは MAUI 9(.NET 9)です。移行は大半のアプリで非破壊的に行えます。以下の順で進めると安全です。
移行手順(Windows/Mac 共通)
- .NET 9 SDK を導入(Windows と Mac の両方)。
- Mac 側で Xcode 16(16.x)をアクティブ化。
- ターミナル/コマンドプロンプトでワークロード更新:
dotnet --info dotnet workload update dotnet workload install maui dotnet workload list - MAUI プロジェクトの
TargetFrameworksを更新:<TargetFrameworks>net9.0-ios;net9.0-android;net9.0-maccatalyst</TargetFrameworks> - iOS の最小サポートを
SupportedOSPlatformVersionで明示(MAUI 9 テンプレート既定は 15.0):<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'"> <SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion> </PropertyGroup> - 主要 NuGet を 9 系へ合わせる(
Microsoft.Maui.*/ コミュニティツールキット / バインディング類など)。 - クリーン&再ビルド:
dotnet clean dotnet build -f net9.0-ios -c Debug dotnet build -f net9.0-ios -c Release
これでシミュレータ/実機のいずれもリンク不整合が解消され、安定してビルドできるようになります。
短期回避:.NET 8 のまま直す場合(推奨度:中)
すぐに MAUI 9 へ上げられない事情がある場合は、.NET 8 でも Xcode 16 に対応した iOS ワークロード(いわゆる「8303 以降」)へ更新します。
- Mac 側で Xcode 16.x を有効にする。
- iOS/MAUI ワークロードを更新:
dotnet workload update dotnet workload install ios dotnet workload install maui※ CI 環境などでバージョンを固定したい場合は--version(Workload Sets)や--from-rollback-fileを活用します。 - シミュレータのみクラッシュ/リンク失敗が残る場合の回避(任意):
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' and $(RuntimeIdentifier.Contains('iossimulator'))"> <MtouchExtraArgs>$(MtouchExtraArgs) --registrar:static</MtouchExtraArgs> </PropertyGroup>
注意:.NET MAUI 8 自体は 2025‑05‑14 でサポート終了しており、将来的な SDK 変更で再び不整合が起きるリスクは残ります。恒久策としては MAUI 9 への計画的移行が必要です。
「古い iOS を残したい」場合の現実解
2025 年時点の Xcode 16 系では、Apple 公式の「Xcode Support」表における Deployment Targets(App Store Connect へアップロード可能な範囲)は iOS 15–18 です。つまり、iOS 12–14 を最小ターゲットにして新しいバイナリをストア配信することはできません。
加えて 2025‑04‑24 以降は Xcode 16 以外でビルドしたバイナリ自体がアップロード不可になりました。従って「別 Mac に Xcode 15 を温存して iOS 12 提出を継続」は現実的ではありません(社内配布や自前配信を除く)。最小サポートの見直しは避けられない前提で、次の運用を検討してください。
- アプリの最小 iOS バージョンを 15.0 へ引き上げ、旧 OS ユーザーには最終対応版(ラストグッドバージョン)を案内する。
- ユーザーコミュニケーション:アップデート情報/FAQ/プッシュ通知で「旧 OS はメンテナンス終了」を明記。
- どうしても iOS 12–14 を維持したい場合は、社内配布(Enterprise/MDM)やWeb アプリ化で機能提供を継続する。
なぜ「シミュレータだけ」落ちるのか——技術的な要点
- レジストラの違い:実機は静的レジストラが既定、シミュレータは動的レジストラが既定。動的経路で参照される
libxamarin系シンボルのバージョン齟齬が起こりやすい。 - SDK とワークロードのミスマッチ:Xcode を 16 に上げたのに .NET for iOS ワークロードが旧版のままだと、シミュレータの arm64 リンク時に未解決シンボルとなる。
- iOS 拡張(Share/Notification Service など)を含む場合、ターゲットごとのリンカオプションや Deployment Target の不一致がエラーを助長する。
実務に効く「確認ポイント」チェックリスト
| 項目 | 見る場所/コマンド | OK 条件 |
|---|---|---|
| dotnet SDK / ワークロード | dotnet --info / dotnet workload list | .NET 9(推奨)または .NET 8+Xcode 16 対応ワークロード |
| Xcode の有効化 | Mac の Xcodes / xcode-select -p | アクティブが 16.x(または要件に合致) |
| TargetFramework | csproj | net9.0-ios(推奨) |
| 最小 iOS バージョン | csproj | <SupportedOSPlatformVersion>15.0</...> を明示 |
| RuntimeIdentifier | csproj | シミュレータは iossimulator-arm64、実機は ios-arm64 |
| レジストラ回避 | csproj(任意) | 必要時のみ --registrar:static をシミュレータに付与 |
バージョン互換マトリクス(2025‑11 時点の実務目安)
| Xcode | iOS SDK | App Store へのアップロード可(Deployment Target) | .NET MAUI | 推奨度 |
|---|---|---|---|---|
| 15.4 | 17.5 | iOS 12–17.5 | MAUI 8(サポート終了) | 不可(2025‑04‑24 以降アップロード不可) |
| 16.0–16.4 | 18.0–18.5 | iOS 15–18 | MAUI 8(EoS)/MAUI 9(公式サポート) | MAUI 9 一択(.NET 8 の継続利用は短期のみ) |
※「Deployment Target」の範囲は Apple 公式の Xcode サポート表に基づきます。
テンプレートどおりの csproj 例(MAUI 9/iOS 18)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net9.0-ios;net9.0-android;net9.0-maccatalyst</TargetFrameworks>
<UseMaui>true</UseMaui>
</PropertyGroup>
15.0
ios-arm64
iossimulator-arm64
CI/自動化で“バージョンずれ”を防ぐコツ
- Workload Sets でピン留め:
dotnet workload install maui --version 9.0.10x.yのようにバージョンを明示。 - global.json で SDK を固定し、ローカルと CI の差異を排除。
- Mac ビルドホストでは
xcode-selectや Xcodes.app で「アクティブ Xcode」を常に確認。
まだ落ちる時の掟(トラブルシュート)
- キャッシュ総入れ替え:
bin/obj/~/.nuget/packagesの対象パッケージを削除 →dotnet restore→dotnet build。 - バインディング/サードパーティ:XCFramework/静的ライブラリの Deployment Target、
VALID_ARCHS相当、Bitcode 廃止対応を再確認。 - 拡張ターゲット(Share/Notification Service):本体と同一の
SupportedOSPlatformVersion/RuntimeIdentifierを設定。 - レジストラの最終手段:シミュレータでも
--registrar:staticを試す(ビルド時間は増える可能性あり)。
FAQ
Q. iOS 12–14 をどうしてもサポートしたい。
A. App Store での新規提出/更新は Xcode 16 以降が必須となり、Deployment Target は iOS 15 以上に限られます。旧 OS ユーザー向けには最終対応版を案内し、以降は機能を凍結するのが現実的です(社内配布を除く)。
Q. .NET 8 のまま長期運用できる?
A. できません。MAUI 8 は 2025‑05‑14 でサポート終了済みです。短期的に Xcode 16 対応版のワークロードへ更新して凌ぐのは可能ですが、恒久的には MAUI 9 へ移行してください。
Q. エラーに出てくる _xamarin_is_object_valid は何?
A. 動的レジストラ経由のメタデータ検証で参照されるランタイムシンボルの一部です。Xcode/.NET ワークロード間の不整合で未解決になることがあり、MAUI 9 への移行やワークロード更新で解消されます(応急として静的レジストラの指定も可)。
まとめ:いま取るべき最短ルート
- 最短の恒久策:MAUI 9(.NET 9)へ移行し、iOS 最小 15.0で再ビルド。
- 短期回避:.NET 8 でも Xcode 16 対応ワークロードへ更新し、必要ならシミュレータに
--registrar:static。 - 運用設計:旧 OS の取り扱い方針(ラストグッド版の提示、告知、社内配布の検討)を明文化。
注記(出典の要点)
・App Store 提出に Xcode 16 以降が必須(2025‑04‑24 以降)。
・Xcode 16 の Deployment Target(アップロード可)は iOS 15–18。
・.NET MAUI 9 は Xcode 16/iOS 18 対応、macOS 14.5+ 前提。
・.NET MAUI 8 のサポートは 2025‑05‑14 で終了。
・シミュレータで Undefined symbols(_xamarin_is_object_valid など)が起きる事例と原因。

コメント