iOS シミュレータと実機の Data Container を操作するアプリを作った
はじめに
先日の記事で、iOS の plist を書き戻したあとに cfprefsd を SIGTERM して反映させる手順を整理しました。
ただ、書き戻しのたびにシェルで plutil を叩いて plist を書き換え、sqlite3 で SQLite を開き、最後に xcrun simctl spawn ... を打つ、という流れを毎回繰り返すのは手間で、これでは自分でも使わなそう、というのが今回作ったアプリの出発点です。
シミュレータと、Xcode (または Device Hub) で実機から取り出した Data Container を GUI で開いて、plist や SQLite をその場で編集できる macOS デスクトップアプリ AppForceps を公開しました。配布は AppForceps-releases です。
できること
主な機能は次の通りです。
- シミュレータの Data Container をその場で開く
- Xcode (または Device Hub) で実機から取り出した Data Container を開いて編集する (
.xcappdataパッケージもネイティブで開ける) - 任意のローカルフォルダを登録して、その配下の
.xcappdataや Data Container を一気に開く - plist (XML / Binary 自動判定) と SQLite (テーブル一覧 + セル単位の更新) を内蔵エディタで編集
- 編集前に自動でバックアップを取り、直近 20 件まで取り消せる
- ファイル名 / plist キー / SQLite テーブル名を全ソース横断で検索
- Firebase Remote Config の
main_active一括編集とlastSuccessfulFetchTime凍結をひと操作で適用
UI は Finder の 4 ペイン横長レイアウトで、Devices → Apps → Files → Editor の順に矢印キーで降りていけます。

xcappdata と Data Container
混同しがちですが、両者は別物です。AppForceps が編集するのは Data Container 本体で、.xcappdata はその搬送パッケージとして扱います。
Data Container はアプリのサンドボックス内に作られるデータ保存用のディレクトリで、Documents/ / Library/ / tmp/ を含む実体を指します (サンドボックス自体はアプリ本体の .app を持つ Bundle Container と Data Container を並べた隔離環境)。一方の .xcappdata は Xcode がその Data Container を Info.plist と一緒に包んだパッケージ形式 (Info.plist + AppData/) で、AppData/ の中身が Data Container 相当です。
シミュレータの場合は Mac のファイルシステム上に Data Container が直接生えているので、AppForceps はそこをその場で触ります。実機の場合は Xcode で一度 Mac に書き出してから、本アプリで Data Container を編集する流れになります。

SQLite はテーブル一覧から行を選んでセル単位で更新できます。BLOB セルはテキスト (UTF-8) と base64 のどちらでも編集できるので、Firebase Remote Config の main_active テーブルのように value 列が BLOB 型ながら UTF-8 文字列をそのまま格納しているケースでも、テキストモードでそのまま読み書きできます。
対応ソース
扱えるソースは次の 4 種です。
| ソース | 編集 | 列挙 |
|---|---|---|
| シミュレータ | 起動中の Data Container の書き込み | xcrun simctl |
.xcappdata | 開いたパッケージへの書き戻し | ファイル選択 / ドラッグ&ドロップ |
| ローカル参照フォルダ | フォルダ配下の .xcappdata / Data Container 風サブディレクトリをその場で編集 | 永続化された登録一覧 |
| 実機 | Data Container の編集は可能 (Xcode または Device Hub で取り出して本アプリで開く)。実機への書き戻しは Xcode または Device Hub に委譲 | xcrun devicectl |
実機の Data Container も本アプリで編集できます。流れは「Xcode または Device Hub の Download Container... で取り出し → AppForceps で Data Container を編集 → Xcode または Device Hub の Replace Container... で実機に書き戻し」です。
CLI (devicectl) で実機に Container を書き戻すと現状ハングする問題があるため、実機への差し替えだけは Xcode または Device Hub に任せる運用にしています。本アプリ単体で実機に直接送るのは、列挙と cfprefsd 再起動の 2 つだけです。
実機での運用フロー
実機の Container を編集する流れは次の図の通りです。
ポイントは次の 3 つです。
- Data Container の取り出しと書き戻しは Xcode または Device Hub の
Replace Container...に任せる - 取り出した Data Container を AppForceps で開き、内部の plist / SQLite を編集する
- 書き戻しのあと、plist を反映させる場合は AppForceps の上部ツールバーから
cfprefsdを再起動する
cfprefsd 再起動の中身は前回の記事で書いた xcrun devicectl device process terminate で、これだけは実機に直接送っています。
インストール
Homebrew tap から入れられます。
brew tap kusumotoa/tap
brew install --cask appforceps
DMG が必要な場合は AppForceps-releases の最新タグから直接取得できます。 macOS 13 以上が動作対象です。
まとめ
- iOS シミュレータと実機の Data Container を GUI で開く macOS アプリを作りました
- plist / SQLite を内蔵エディタで編集でき、編集前のバックアップと取り消し履歴を備えています
- 実機の Data Container も本アプリで編集できます。実機への書き戻しだけは CLI でハングする問題があるため Xcode または Device Hub の
Replace Container...に任せる運用です cfprefsd再起動はアプリ内のボタンから実機にも送れます
実機からシミュレータへ Data Container を引き継ぐような場面でも、中にどんなディレクトリ構造でどんなファイルが並んでいるかを GUI で覗けると、転送のたびに何が動いたのかを確認しやすくなります。今後 Data Container を転送する機会があれば、よければ使ってみてください。