【iOS】ソースコードの編集内容を起動中のアプリにリアルタイムに反映させるiOS Runtime Previewを作りました

ソースコードで編集した内容を起動中のアプリにリアルタイムに反映させるiOS Runtime Previewというツールを作りました。

まるでインタプリタで実行しているかのように動的にアプリの挙動を書き換えることができます。

iOS Runtime Preview from Yuuki Furuyama on Vimeo.

addsict/iOSRuntimePreview

使い方

  1. iOS Runtime PreviewをGitHubからダウンロードします。

    $ git clone https://github.com/addsict/iOSRuntimePreview.git

  2. XcodeiOSアプリを実行します。シミュレータでも実機でもokです。

    img1

  3. デバッグエリアのポーズボタンを押して実行を一時停止します。

    img2

  4. 本ツールのスクリプトpreview.pyをLLDBのセッションにロードします。

    img3

  5. previewコマンドを使用して、リアルタイムに編集したいコードを指定します。これで準備完了です。

    コマンド: preview <プロジェクトディレクトリからのファイルパス>

    img4

  6. 上記で指定したコードを編集すると、起動中のアプリにリアルタイムに反映されます。

仕組み

LLDBのデバッグセッションの裏で対象ファイルの監視スレッドを動かし、アプリ起動以降にファイルに変更があれば前後のdiffを取ります。
diff情報を元に

  • コードが追加された場合
    • 追加されたラインにブレークポイントを張り、そこにヒットしたら追加されたコードをLLDBで評価して実行します。
  • コードが削除された場合
    • 削除されたラインにブレークポイントを張り、そこにヒットしたらPC(プログラムカウンタ)を次の命令のアドレスにセットし、削除されたコードは実行しないようにスキップします。
  • 同一ラインのコードが変更された場合
    • コードの削除とコードの追加が同時に行われたと判断し、上記の2つの処理を行います。

現状の制限

現状リアルタイムに反映できるソースファイルの変更には以下の制限があります。

  • 新しいif文やfor文などの制御構文は実行できません
  • 新しいメソッドを書き足すことはできません
  • 新しい変数宣言は行えません

まとめ

LLDBでコードを評価したりプログラムカウンタを直接いじったりと、けっこう強引な作りとなっています(そのため場合によってはメモリアクセス違反が容易に起こり得ます)が、 UIの微妙な変更や、少しコードをいじって様子を見たい、といった場面で手軽に使えるかなと思います。

不具合報告や機能追加などはこちらまで!