Windows 上の Visual Studio から .NET MAUI iOS アプリを Ad‑Hoc 配布しようとすると、アーカイブ処理だけが何時間も終わらない……そんな事象に悩まされていませんか。この記事では、Mac では CLI 発行が成功するのに Pair to Mac 経由だと止まってしまうケースを前提に、原因候補と具体的な回避策・調査手順を整理して解説します。
.NET MAUI iOS の Ad‑Hoc 配布で「アーカイブ」が終わらない現象
まず、今回想定している状況を整理します。
- .NET MAUI で iOS アプリを開発している。
- 配布方式は Ad‑Hoc(Apple Developer の Ad‑Hoc プロビジョニングプロファイルを使用)。
- Windows 10 上の Visual Studio(17.13.5)から「発行 → Ad‑Hoc」を実行すると、「Publish the app」のステップ 5(アーカイブ)がいつまで経っても終わらない。
- IDE 側にはエラーも警告も表示されず、2 時間以上経っても進捗が変わらない。
- 一方で、同じプロジェクトを Mac のターミナルから
dotnet publishすると、約 1,500 秒(25 分前後)で正常終了して.ipaが生成される。 - iOS シミュレーターでのデバッグ(Windows VS → Pair to Mac)は問題なく行える。
この条件が揃っている場合、プロジェクトや証明書の設定そのものではなく、「Windows の Visual Studio から Mac にリモートでアーカイブを依頼する経路(Pair to Mac / XMA)」に問題が集中していると考えるのが自然です。
想定環境の例
| 項目 | 内容 |
|---|---|
| クライアント OS | Windows 10 |
| IDE | Visual Studio 2022 17.13.5(.NET MAUI ワークロード) |
| リモート Mac | 物理 Mac(Pair to Mac で接続) |
| Xcode | 16.2 |
| .NET MAUI | 9.0.5 |
| 配布方式 | Ad‑Hoc 配布(Apple Distribution 証明書+ Ad‑Hoc プロビジョニングプロファイル) |
| 状態 | シミュレーター向けビルドは成功/Mac CLI での発行も成功/VS からのアーカイブだけ終わらない |
このような場合、「アプリそのものは正常にビルド・署名できるが、Windows ⇔ Mac 間のリモートビルドのどこかで詰まっている」という切り分けが重要なポイントになります。
なぜ Windows の Visual Studio からだけ止まるのか
.NET MAUI の iOS ビルドでは、Windows からのビルドでも最終的には Mac 側で xcodebuild や codesign が実行されます。大まかな流れは次のようなイメージです。
| フェーズ | Windows(VS)から Mac CLI の場合 | Mac で直接 CLI 実行の場合 |
|---|---|---|
| ビルドコマンドの起点 | Visual Studio が MSBuild を起動し、Pair to Mac を通じてリモートビルドを依頼 | ターミナルから dotnet publish を直接実行 |
| .NET ビルド | リモートの .NET SDK でビルド(XMA 経由) | ローカルの .NET SDK でビルド |
| xcodebuild / アーカイブ | リモートプロセスとして実行され、結果が VS に返る | ローカルプロセスとして実行され、ターミナルにログが出力 |
| Keychain アクセス | UI ダイアログが出ても Windows 側には見えない | Mac の画面に直接ダイアログが表示される |
| ログの見え方 | VS の出力ウィンドウに要約が出るだけで、途中で止まっても「待ち状態」に見えやすい | ターミナルに詳細ログが出続けるため、どこで止まっているか分かりやすい |
この差によって、Mac 側ではユーザー操作待ち(例:Keychain ダイアログ)で完全に止まっているのに、Windows の Visual Studio からは「単に時間がかかっているだけ」に見えるというギャップが生まれます。
シミュレーターでのデバッグが成功する理由
「シミュレーターなら動くのに、実機向けアーカイブだけ止まる」というのも重要なヒントです。
- シミュレーター用ビルドは、実機用と比べてコード署名やアセット処理が簡略化されることが多い。
- Ad‑Hoc 配布用アーカイブでは、本番に近い形でのコード署名・最適化・アセット変換が走る。
- 特に、codesign が秘密鍵にアクセスする瞬間に Keychain ダイアログが出やすく、ここで止まるケースがよくあります。
そのため、シミュレーターが動く=証明書設定が完全に正しいとは限らず、「実機用ビルドでだけ有効になる処理」に問題が潜んでいることを前提に調査していく必要があります。
まずは確実に配布物を得る:Mac 上での CLI 発行
原因調査は重要ですが、まずは「配布したいビルド成果物(.ipa)を確実に得る」ことが最優先です。既に Mac のターミナルから dotnet publish が成功しているのであれば、当面は CLI 発行を正規ルートとして運用するのがおすすめです。
基本的な CLI 発行コマンド例
dotnet publish -f net9.0-ios -c Release -p:RuntimeIdentifier=ios-arm64 \
-p:ArchiveOnBuild=true \
-p:CodesignKey="Apple Distribution: <組織名>" \
-p:CodesignProvision="<AdHocプロファイル名>"
主なオプションの意味は次のとおりです。
| オプション | 意味 | ポイント |
|---|---|---|
-f net9.0-ios | ターゲットフレームワーク | プロジェクトの TargetFramework に合わせる |
-c Release | ビルド構成 | Ad‑Hoc 用なので Release を指定 |
-p:RuntimeIdentifier=ios-arm64 | 実機用ランタイム(arm64) | シミュレーターではなく実機を対象にする |
-p:ArchiveOnBuild=true | ビルド時にアーカイブも作成 | .xcarchive 〜 .ipa までを自動生成 |
-p:CodesignKey | 使用する Apple Distribution 証明書 | Keychain に登録されている「証明書の名前」と一致させる |
-p:CodesignProvision | 使用するプロビジョニングプロファイル | Ad‑Hoc プロファイルの「名前」を指定 |
生成される成果物は、通常次のいずれかのパスに出力されます。
bin/Release/net9.0-ios/ios-arm64/publish/*.ipabin/Release/net9.0-ios/ios-arm64/publish/*.xcarchive
毎回長いコマンドを打つのが面倒であれば、簡単なシェルスクリプトにまとめておくと便利です。
#!/bin/zsh
set -e
PROJECT_DIR="/path/to/YourMauiProject"
cd "$PROJECT_DIR"
dotnet publish -f net9.0-ios -c Release -p:RuntimeIdentifier=ios-arm64 \
-p:ArchiveOnBuild=true \
-p:CodesignKey="Apple Distribution: <組織名>" \
-p:CodesignProvision="<AdHocプロファイル名>"
echo "Ad-Hoc パッケージの生成が完了しました。"
このように、「配布物を出す経路」と「Visual Studio からのアーカイブが止まる問題の調査」は切り離して考えると、開発の足が止まりにくくなります。
Visual Studio(Pair to Mac)側でアーカイブが終わらない主な原因と対処
ここからは、本題である「なぜ Windows の Visual Studio 経由だけが止まってしまうのか」を、代表的な原因ごとに掘り下げていきます。
| 原因候補 | 症状の特徴 | 優先度 |
|---|---|---|
| Keychain のアクセス許可ダイアログ待ち | Mac 画面にダイアログが出ており、OK するまで進まない | 最有力 |
| XMA / キャッシュの不整合 | 再起動やクリーン後に直ることがある | 高 |
| VS・.NET SDK・Xcode のバージョンずれ | 特定バージョンの組み合わせでのみ再現 | 中 |
| ディスク容量不足 | 他の Mac プロジェクトでもアーカイブ失敗が増える | 中 |
| アセットやリンク設定の異常 | 画像追加後にのみ失敗する等、変更に依存 | 中 |
Keychain のアクセス許可ダイアログ待ち(最有力)
Ad‑Hoc 配布では、codesign が Apple Distribution 証明書の秘密鍵にアクセスします。このとき、Keychain に対して次のようなダイアログが表示されることがあります。
- “codesign” がキーチェーン “login” 内の秘密鍵 “Apple Distribution: …” へのアクセスを要求しています。
- [許可] [常に許可] [拒否]
Mac の画面を見ていると一目瞭然ですが、このダイアログは Windows の Visual Studio には転送されません。そのため、VS から見ると「アーカイブが進んでいるように見えるが、実は Mac 側でユーザー操作待ちになっている」状態になります。
対処:Mac 側で一度手動アーカイブして「常に許可」にする
最も簡単な回避方法は、次のように Mac 上で一度手動でアーカイブを実行し、「常に許可」を選択しておくことです。
- Xcode で該当プロジェクト(もしくはサンプルの署名付きプロジェクト)を開く。
- Product > Archive からアーカイブを開始する。
- Keychain のダイアログが出たら、「常に許可(Always Allow)」を選択する。
- アーカイブが最後まで完了することを確認する。
これで、同じ証明書を使う codesign に対して、今後はダイアログ無しでアクセスが許可されるようになります。その結果、Pair to Mac 経由であっても署名処理がスムーズに通り、アーカイブが完了しやすくなります。
対処:Keychain を事前に解錠し、CLI から許可設定する
より確実に UI なしで処理できるようにしたい場合は、Mac のターミナルから次のようなコマンドを実行します。
# Keychain を解錠
security unlock-keychain -p '<Macのログインパスワード>' ~/Library/Keychains/login.keychain-db
# Apple 純正ツールからのアクセスを UI なしで許可
security set-key-partition-list -S apple-tool:,apple: -s -k '<Macのログインパスワード>' \
~/Library/Keychains/login.keychain-db
これにより、codesign や xcodebuild などの Apple 純正ツールからのキーアクセスは、ダイアログ無しで行えるようになります。
確認ポイント
- アーカイブ中に Mac の画面を直接確認し、ダイアログが出ていないかチェックする。
- 同じ証明書を使って、Mac 単体で Xcode アーカイブが成功するかを確認する。
- Keychain アクセスの問題を解消した後に、Windows 側から再度アーカイブしてみる。
リモートビルド(XMA)キャッシュの不整合
次に疑うべきは、Xamarin.Mac Agent(XMA)によるリモートビルドのキャッシュ不整合です。古い中間成果物や一部のキャッシュが壊れていると、actool(アセット処理)や mtouch、codesign などで処理が止まることがあります。
対処:Windows 側のクリーンアップ
- VS を終了する。
- プロジェクトフォルダ内の次のディレクトリを削除する。
binobj.vs(ソリューション直下)
- VS を再起動し、ソリューションを開き直してから再度 Pair to Mac を行う。
対処:Mac 側のキャッシュ削除
Mac 側でも、以下のようなキャッシュを削除しておくと効果があります。
~/Library/Caches/Xamarin/配下~/Library/Caches/XMA/などのリモートビルド関連フォルダ- Xcode の DerivedData(例:
~/Library/Developer/Xcode/DerivedData)
削除後は Mac を一度再起動し、再度 Windows から Pair to Mac を行ったうえでアーカイブを試します。
バージョン整合性のずれ(Visual Studio・.NET SDK・Xcode)
.NET MAUI は .NET/Xcode/iOS SDK の組み合わせに敏感です。Visual Studio 側で MAUI テンプレートや .NET 9 SDK を更新したものの、Mac 側のワークロードが追随していない場合、特定パターンでのみビルドやアーカイブが止まることがあります。
確認すべきポイント
- Visual Studio インストーラーで、.NET MAUI ワークロードおよび .NET 9 SDK が最新かを確認。
- Mac 側で
dotnet --infoを実行し、使用されている SDK バージョンを確認。 - 同じく Mac 側で
dotnet workload listを実行し、maui関連ワークロードがインストール済みか確認。 - Xcode が複数インストールされている場合、次のコマンドで使用するバージョンを明示する。
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
- ライセンス同意が済んでいないとビルドが止まることもあるため、必要に応じて次を実行。
sudo xcodebuild -license accept
Mac 側の CLI で dotnet publish が成功しているのであれば、基本的にはバージョン整合性は取れているはずですが、Pair to Mac 経由では別の dotnet 実行環境を参照しているケースもあり得ます。Mac 側の PATH やシェルプロファイルを変更した場合は特に注意が必要です。
ディスク容量不足
iOS アプリのアーカイブでは、多数の一時ファイルや中間生成物が作成されます。特に、AOT、リンク処理、大量のアセットを含むプロジェクトでは、20〜30GB 以上の空き容量を見込んでおいた方が安全です。
- Mac のストレージに 10GB 前後しか空きがない状態だと、途中で処理が止まったり極端に遅くなったりします。
- 同じ Mac で他の Xcode プロジェクトのアーカイブも失敗しやすくなっていれば、容量不足の可能性が高くなります。
Mac の「この Mac について > ストレージ」から空き容量を確認し、不要なアプリ・キャッシュ・古い .xcarchive などを削除して十分な空きを確保しておきましょう。
アセットやリンク設定の異常
最後に、プロジェクト側の要素として疑うべきなのが、アセットやリンカー設定です。たとえば次のようなケースです。
- 巨大な PNG・JPEG ファイルをそのまま
Assets.xcassetsに入れている。 - 推奨される解像度・形式と異なる app icon / splash 画像を使用している。
- リンク設定を Aggressive にしており、必要なアセンブリまでトリミングされている。
Mac 側の CLI 発行も成功しているので、アセットそのものが致命的に NG という可能性は低めですが、アーカイブ処理の一部でのみ問題が顕在化することもあります。次のような切り分けを試すとよいでしょう。
Assets.xcassetsを一時的にシンプルなアイコンセットだけにしてビルドしてみる。- リンク設定をデフォルト(例:SDK アセンブリのみ)に戻してみる。
- 追加したばかりの巨大画像やフォントを一度除外してビルドしてみる。
どこで止まっているかを可視化する:MSBuild バイナリログ
ここまでの対処で解決しない場合、「どのタスクで止まっているのか」を MSBuild のログから特定するのが有効です。そのために使えるのが MSBuild のバイナリログ(.binlog)です。
追加 MSBuild 引数でバイナリログを出力する
Visual Studio の発行設定で、追加 MSBuild 引数として次を指定します。
-bl:publish.binlog -v:diag
-bl:publish.binlog… ビルドプロセス全体をpublish.binlogというファイルに記録。-v:diag… 詳細(diagnostic)レベルのログを出力。
発行を実行すると、ソリューションフォルダやプロジェクトフォルダに publish.binlog が生成されます。これを MSBuild Structured Log Viewer 等のツールで開くと、どのターゲット・タスクで処理が止まっているかを視覚的に確認できます。
ログで着目すべき主なタスク
| タスク名の例 | 役割 | ここで止まる場合の疑いどころ |
|---|---|---|
_CompileToNative / mtouch | AOT コンパイル・ネイティブ化 | コードサイズ・リンク設定・AOT 設定 |
_CompileAppManifest | Info.plist の生成・加工 | バンドル ID・バージョン・能力設定 |
_CompileAssetCatalogs / actool | アセットカタログのコンパイル | 画像サイズ・形式・Assets.xcassets の構造 |
_CodesignAppBundle | アプリバンドルのコード署名 | 証明書・プロビジョニングプロファイル・Keychain |
_CreateIpa | .ipa のパッケージング | ディスク容量・パスやファイル名関連の問題 |
特定のタスクでログが途切れている、あるいはそのタスクの開始以降何も進んでいないようであれば、その部分を重点的に調査していきます。
Mac 側の状態を観察する:プロセスと画面
Pair to Mac 経由のビルド中は、Mac 側でも次のような点をチェックしておくと原因特定に役立ちます。
アクティビティモニタでの確認
- dotnet
- xcodebuild
- actool
- codesign
これらのプロセスが CPU を使い続けているなら「処理は進んでいるが時間がかかっている」状態、CPU 使用率が 0% 付近で止まっているなら「何らかの待ち状態」の可能性が高いです。特に codesign が CPU を使っていない場合は、Keychain アクセス待ちやディスク/ネットワーク I/O 待ちを疑うとよいでしょう。
Mac の画面にダイアログが出ていないか
意外と見落としがちなのが、Mac 側の画面そのものです。アーカイブ開始後は、次のようなダイアログが出ていないか必ず確認しましょう。
- Keychain のアクセス許可ダイアログ
- Xcode の初回実行に関するダイアログ
- Gatekeeper によるブロック(アプリの実行許可)
これらはすべて「ユーザーがボタンを押すまで処理が進まない」タイプのダイアログです。VS には表示されないため、Mac を遠隔操作している場合などは特に注意が必要です。
再発させないための運用ルール
一度問題が解決しても、新しい Mac を導入したり証明書を更新したりすると、同じような現象が再発することがあります。そこで、再発防止のために運用ルールとして組み込んでおきたいポイントをまとめます。
新しい Mac / 証明書を導入したら、まず Mac 単体で署名付きビルド
- 新しい Mac を開発環境に追加したとき。
- Apple Distribution 証明書や Ad‑Hoc プロビジョニングプロファイルを更新したとき。
このような場合は、最初に Mac 上で Xcode または CLI を使って署名付きアーカイブを 1 回成功させる習慣をつけておくと、Keychain ダイアログ問題を未然に防ぎやすくなります。
大型アップデート後は「キャッシュ削除 → 再ペアリング」を定型化
.NET MAUI/Xcode/Visual Studio のいずれかを大きくアップデートした直後は、次のような手順を「儀式」として実行するのがおすすめです。
- Windows 側で
bin/obj/.vsを削除。 - Mac 側で Xcode DerivedData と XMA 関連キャッシュを削除。
- Pair to Mac の登録を解除し、再度ペアリング。
- 簡単なサンプル MAUI プロジェクトで、シミュレーターと実機向けビルドを一度試す。
こうしておくことで、環境アップデートに伴う「謎のビルド失敗」に引きずられにくくなります。
配布は CLI 発行を標準にし、Visual Studio は主に開発・デバッグ用にする
特にチーム開発では、「本番向け Ad‑Hoc / App Store 配布は Mac 上の CLI 発行で行う」と決めておくと、環境依存のトラブルを減らせます。
- CI/CD(GitHub Actions や Azure DevOps)に組み込みやすい。
- 同じコマンドで再現性の高いビルドができる。
- VS の UI 変更やバージョンアップの影響を受けにくい。
Visual Studio はあくまで開発・デバッグ・簡易な実機テスト用と位置づけ、本番配布物は CLI で安定的に生成する、という役割分担が現実的です。
Microsoft への問題報告を行うときのポイント
公式フォーラム等では「Visual Studio のメニューから Report a problem(問題を報告) を送ってください」という回答で終わってしまうこともあります。せっかく報告するのであれば、次の情報を添えておくと、再現・調査されやすくなります。
- Visual Studio のバージョン(例:17.13.5)。
- .NET SDK / MAUI のバージョン(
dotnet --infoとdotnet workload listの抜粋)。 - Xcode のバージョン(例:16.2)。
- Windows 側の OS バージョンと Mac 側の OS バージョン。
- Mac 側で
dotnet publishしたときは成功すること、およびそのログ。 - Visual Studio で取得した
publish.binlog(MSBuild バイナリログ)。
特に .binlog があれば、「どのタスクで止まっているのか」を開発側でも確認できるため、単なる「症状報告」よりもずっと有用な情報になります。
まとめ:アプリの問題ではなく「ビルド経路の問題」として切り分ける
ここまで見てきたとおり、
- Mac の CLI からは
dotnet publishが成功する。 - iOS シミュレーターでのデバッグも成功する。
- それでも Windows の Visual Studio からの Ad‑Hoc アーカイブだけが終わらない。
という状況では、アプリやコードそのものではなく、「Visual Studio → Pair to Mac → Xcode / codesign」というビルド経路に問題が集中していると考えるのが妥当です。
特に最有力なのは、
- Keychain のアクセス許可ダイアログ待ち
- XMA / キャッシュの不整合
の 2 点です。まずは Mac の画面とアクティビティモニタを確認しつつ、Keychain 設定の見直しとキャッシュ削除・再ペアリングを実施し、それでも解決しない場合にバイナリログ解析やバージョン整合のチェックに進む、という順番でアプローチすると効率的です。
同時に、Mac 上での CLI 発行を標準ルートとして整備しておけば、Visual Studio 側の挙動に引きずられず、安定して Ad‑Hoc 配布用の .ipa を生成し続けることができます。開発と配布の経路を意識的に分けることで、.NET MAUI iOS 開発の運用はぐっと楽になるはずです。

コメント