.NET MAUI/Xamarin.iOSの「Entitlements.plistが見つからない」エラーをVisual Studio 2022とPair to Macで確実に解決する方法

Windows の Visual Studio 2022 から .NET MAUI/Xamarin.iOS の iOS アーカイブを作成する際に、Platforms/iOS/Entitlements.plist が見つからないというエラーで止まることがあります。本記事では「なぜ起きるのか」「どこを直せば良いのか」を、実務でそのまま使える手順とチェックリスト、具体的な設定例、検証方法までまとめて体系的に解説します。

目次

症状

アーカイブ(IPA 生成)やデバイス向けビルド時に次のようなメッセージで失敗します。

Resources rules file 'Platforms/iOS/Entitlements.plist' not found

あるいは、CodeSign の直前で「entitlements を読み込めない」「ファイルが存在しない」といった趣旨のエラーが記録されます。多くの場合、Windows 側で <CodesignEntitlements> を設定したにもかかわらず、Mac ビルド ホストに正しいパスで渡せていないことが原因です。

結論(最短解)

  1. 物理配置Platforms/iOS/Entitlements.plist に置く(大文字小文字を厳密に)。
  2. ビルド アクションBundleResource に設定する。
  3. csproj<CodesignEntitlements>Platforms/iOS/Entitlements.plist</CodesignEntitlements>スラッシュ/)で記述する。
  4. クリーンbin / obj を削除してから再ビルド。
  5. Pair to Mac:接続状態とコピー結果(Mac 側ログ)を必ず確認。

まずは全体像(なぜ起きる?)

このエラーは、CodeSign が参照する Entitlements.plist実ファイルプロジェクト設定の間で、下記のいずれかがズレると発生します。

  • フォルダ/ファイル名の大文字小文字が一致していない(iOSiosEntitlement.plistEntitlements.plist など)。
  • Windows 由来のバックスラッシュ\)で csproj に書いたパスが、Mac 上で解釈できずに無視される。
  • ビルド アクションが不適切で、アプリ バンドルに含まれず、CodeSign 時に見つからない。
  • 旧ビルド成果物や中間生成物(obj)に残ったキャッシュが、新しい設定を上書きしている。
  • Windows→Mac のリモート ビルド同期で、最新ファイルがコピーされていない/古いファイルが参照されている。

早見表:原因と対処

症状/原因見分け方対処
大文字小文字の不一致ソリューション内のフォルダ名・ファイル名を目視。Git の差分でも要確認。Platforms/iOS/Entitlements.plist に統一。厳密に一致させる。
csproj のパス区切りが \csproj をテキストで開き、CodesignEntitlements の値を見る。必ず / に修正(例:Platforms/iOS/Entitlements.plist)。
ビルド アクションが不適切Solution Explorer → Properties → Build ActionBundleResource を選択。
キャッシュの影響直近でファイル名やパスを変更した。bin / obj を削除後、Clean → Rebuild。
Mac への同期不全Pair to Mac 直後/回線不安定/一部ファイルだけが古い。接続を張り直し、Mac 側のビルドログでコピー結果を確認。

正しい配置と設定(手順詳細)

物理配置

Entitlements.plist はプロジェクト ルート直下にある Platforms/iOS フォルダに配置します。必ず以下の階層と綴りを守ってください。

(ProjectRoot)/
  Platforms/
    iOS/
      Entitlements.plist

フォルダ名 iOSi, O, S は大文字です。小文字化した ios や、スペルミス(Entitlement.plist など)は不可です。

ビルド アクション

Solution Explorer で Entitlements.plist を選択し、PropertiesBuild ActionBundleResource に設定します。これにより MSBuild はファイルをバンドルに含め、CodeSign が参照できる状態になります。

csproj の設定(CodesignEntitlements)

プロジェクト ファイル(.csproj)に次のように追記します。区切りはスラッシュ(/のみを使用してください。

&lt;PropertyGroup&gt;
  &lt;CodesignEntitlements&gt;Platforms/iOS/Entitlements.plist&lt;/CodesignEntitlements&gt;
&lt;/PropertyGroup&gt;

構成やターゲットごとに異なる entitlements を使う場合は、条件付きで指定します。

&lt;PropertyGroup Condition="'$(Configuration)'=='Debug' and '$(TargetFramework)'=='net8.0-ios'"&gt;
  &lt;CodesignEntitlements&gt;Platforms/iOS/Entitlements.plist&lt;/CodesignEntitlements&gt;
&lt;/PropertyGroup&gt;
&lt;PropertyGroup Condition="'$(Configuration)'=='Release' and '$(TargetFramework)'=='net8.0-ios'"&gt;
  &lt;CodesignEntitlements&gt;Platforms/iOS/Entitlements.plist&lt;/CodesignEntitlements&gt;
&lt;/PropertyGroup&gt;

注意: マルチターゲットで net8.0-android なども含む場合、iOS 向けの PropertyGroup にだけ設定するのが安全です。

クリーン & リビルド

  • Visual Studio の Clean を実行。
  • bin / obj手動で削除(フォルダごと)。
  • その後 Rebuild で再生成。

キャッシュに古いメタデータが残っていると、新しい設定が反映されず同じエラーが再発します。

Pair to Mac(リモート ビルド)の確認

  • Visual Studio の Pair to Mac で接続状態が緑(正常)になっているか。
  • 接続を一度切り、再接続後にビルドしてファイルコピーが走ることをログで確認。
  • Mac 側のビルドログで Entitlements.plist のパスが Platforms/iOS になっているか。

リモート同期は「最新のファイルがコピーされている」ことが前提です。特にファイル名やパスを変更した直後は、古い中間生成物を参照していないか注意してください。

パス表記の落とし穴(\/

Windows ではつい Platforms\iOS\Entitlements.plist と書きがちですが、csproj の CodesignEntitlementsスラッシュ(/)で統一してください。Mac 側で \ を正しく解釈できず、存在しないパスとして扱われる場合があります。

記述評価結果
Platforms/iOS/Entitlements.plistOS 非依存で解決◎ 正常
Platforms\iOS\Entitlements.plistMac で無効解釈の可能性× エラー要因

Entitlements.plist の基礎知識

Entitlements.plist は、アプリに付与する権限(Push 通知、iCloud、App Groups、Keychain 共有など)を宣言するファイルです。不要な権限を含めると審査で指摘される可能性が高まるため、必要最低限のみを記載してください。

最小サンプル(開発用 Push のみ):

&lt;plist version="1.0"&gt;
  &lt;dict&gt;
    &lt;key&gt;aps-environment&lt;/key&gt;
    &lt;string&gt;development&lt;/string&gt;
  &lt;/dict&gt;
&lt;/plist&gt;

本番用では aps-environment の値を production に切り替えます。構成(Debug/Release)で値を変えたい場合は、別ファイルに分けるか、ビルド前に置換するスクリプト/ターゲットを用意するのが確実です。

.NET MAUI と Xamarin.iOS での注意点

  • 二重設定禁止: 同じ権限を Info.plistEntitlements.plist の両方に書かない。基本は Entitlements.plist に集約。
  • ターゲット フレームワークごとの指定: net8.0-iosnet7.0-ios など、TFM ごとに PropertyGroup を分ける。
  • XAML Hot Reload 等の開発時支援機能は、アーカイブ工程の CodeSign とは無関係。署名エラーはビルド設定の問題に集約して考える。

検証のしかた(「設定できたか」を証明する)

MSBuild でプロパティを可視化

ビルド ログに CodesignEntitlements の評価結果を明示的に出力すると把握が速くなります。例えば、カスタム ターゲットを追加して値を出力します。

&lt;Target Name="PrintCodesignEntitlements" BeforeTargets="Build"&gt;
  &lt;Message Text="CodesignEntitlements=$(CodesignEntitlements)" Importance="High" /&gt;
&lt;/Target&gt;

これでビルド出力に最終的なパスが表示されます。想定と違う場合は、条件(Condition)の書き方を見直してください。

binlog の取得

問題が再発する場合、binlog を取ると手がかりが増えます。

dotnet build -c Release -f net8.0-ios -bl:build.binlog

binlog を解析すると、いつ・どのターゲットで CodesignEntitlements が変更されたかが追えます。

Mac 側で実物を確認

アーカイブ生成後、Mac で CodeSign に埋め込まれた実際の entitlements を確認します。

codesign -d --entitlements :- "MyApp.app" | plutil -p -

想定のキーが含まれていれば、CodeSign は正しく entitlements を読めています。

Windows→Mac リモート ビルド特有の注意点

  • 同期の整合性: ファイル名の大小文字を変更した場合、Git やエクスプローラーの挙動で意図通りに変更が反映されないことがあります。いったん別名にリネーム → コミット → 正しい大文字小文字にリネーム → コミットと段階を踏むと安全です。
  • 古いファイルの残留: Mac 側の ~/Library/Caches/Xamarin や一時領域に古い中間生成物があり、最新の Entitlements.plist が反映されないケースがあります。ビルドや接続をやり直してクリアにします。
  • 接続の品質: ネットワークが不安定だと一部ファイルだけコピーに失敗し、再利用されたキャッシュでビルドが進みます。エラーが断続的に出る場合はまず回線品質を疑うと近道です。

設定の「正しさ」をダブルチェック:チェックリスト

確認項目期待値判定
ファイルの物理配置Platforms/iOS/Entitlements.plistOK / NG
フォルダ/ファイル名の大小文字iOS は大文字、Entitlements.plist は綴り一致OK / NG
ビルド アクションBundleResourceOK / NG
csproj のパス区切り/(スラッシュ)OK / NG
クリーン後の再ビルドbin/obj を削除済みOK / NG
Pair to Mac接続緑/ログでコピー成功を確認OK / NG

よくある勘違いと対処

  • 勘違い: Info.plist に権限を書けば良い。
    正解: 署名時に使われるのは Entitlements.plistInfo.plist はアプリのメタ情報で役割が異なります。
  • 勘違い: CodesignEntitlements を設定すればビルド アクションは不要。
    正解: ビルド アクションが不適切だとバンドルに含まれず、CodeSign が参照できません。BundleResource に。
  • 勘違い: Windows のパス(\)でも自動で直してくれる。
    正解: Mac 側では解釈できず「存在しない」扱いになりがち。スラッシュ固定が安全です。

トラブル事例別の対処

ビルドは通るが、実機で Push が届かない

  • aps-environment の値(development/production)と証明書の環境が一致しているか。
  • 同一 App ID/プロビジョニング プロファイルに Push が有効化されているか。
  • Release と Debug で別 entitlements を使っていないか。

「署名の有効期限切れ/認証に失敗」系のエラー

  • Mac の Xcode で Apple ID を再ログイン。
  • プロビジョニングを Automatic に切り替えて再生成。
  • Mac の日付/時刻を自動設定にしてタイムスタンプの不整合を解消。

実践テンプレート(そのまま流用可)

ディレクトリ構成

MyApp/
  MyApp.csproj
  Platforms/
    iOS/
      Entitlements.plist
    Android/
    MacCatalyst/

csproj(単一 TFM の例)

<Project Sdk="Microsoft.NET.Sdk">


net8.0-ios
Platforms/iOS/Entitlements.plist






 

Entitlements.plist(最小構成)

&lt;plist version="1.0"&gt;
  &lt;dict&gt;
    &lt;!-- 必要なキーだけを最小限で --&gt;
  &lt;/dict&gt;
&lt;/plist&gt;

原因切り分けのフロー

  1. ファイルの実在確認: エクスプローラーで Platforms/iOS/Entitlements.plist を目視。
  2. ビルド アクション: BundleResource になっているか。
  3. csproj のパス: / 区切りになっているか。
  4. キャッシュ掃除: bin / obj を削除後、再ビルド。
  5. Pair to Mac: 接続やコピーに失敗していないかログで確認。
  6. 実物検証: Mac で codesign -d --entitlements :- の結果を照合。

MAUI プロジェクトでのベストプラクティス

  • 権限の最小化: 審査観点からも、使うものだけを列挙する。
  • 設定の一元化: 権限は Entitlements.plist のみに寄せ、重複・矛盾を避ける。
  • 構成別ファイル: Debug/Release で値が変わるキー(例:aps-environment)はファイルを分けると安全。
  • レビュー用タスク: PR 時に Entitlements.plist の差分を必ずレビューする運用を取り入れる。

「それでも解決しない」時の追加ポイント

  • ファイルのエンコーディング: UTF-8 で保存されているか。不可解なパースエラーを避けるため、BOM なしが無難。
  • 隠れた拡張子: エディタによっては .plist.txt のように保存される誤りに注意。
  • 重複定義: プロジェクトに複数の Entitlements.plist が存在していないか(古いファイルが残っている)。
  • CI とローカルの乖離: CI 側の環境変数/キャッシュをクリアし、ローカルと同じ msbuild コマンドで比較。

まとめ

Resources rules file 'Platforms/iOS/Entitlements.plist' not found は、配置パス区切りビルド アクションキャッシュリモート同期のいずれかが崩れると必ず起きる、原因がシンプルなエラーです。以下の 5 点を守れば確実に解消できます。

  1. Platforms/iOS/Entitlements.plist に正しく配置(大小文字も含めて厳密一致)。
  2. Build Action を BundleResource にする。
  3. csproj の CodesignEntitlements/ 区切りで指定。
  4. bin / obj を削除してからクリーン&リビルド。
  5. Pair to Mac の接続状態とコピー結果を確認。

これで Windows から Mac へのリモート アーカイブでも安定してビルドが通り、不要なハマりを避けられます。権限は最小限に保ち、構成・ターゲットごとに整然と管理する運用へ移行しておきましょう。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次