本文へスキップ

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 の順に矢印キーで降りていけます。

AppForceps の 4 ペイン構成。左から Devices、Apps、Files、plist Editor が並び、UserDefaults のキーと値が型付きで編集できる

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 を編集する流れになります。

Firebase Remote Config の SQLite を AppForceps で開き、セルを更新するモーダルで値を BLOB / テキストとして編集している様子

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 を編集する流れは次の図の通りです。

実機の Data Container を AppForceps で編集する運用フロー

ポイントは次の 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 を転送する機会があれば、よければ使ってみてください。

参考リンク