Swift REPLでiOS SDKを使う
ときには Xcode や Playground で Swift コードを実行するのではなく、Swift REPL で実行したい場合がある。
しかし、Swift REPL は iOS をサポートしていないようです。swift -sdk
や xcrun --sdk
を試してみたが、ダメです。
1> import UIKit
expression failed to parse:
error: repl.swift:2:8: error: no such module 'UIKit'
import UIKit
^
いろいろ調べてみて、一つの方法として、Xcode で iOS プロジェクトを開いて、ブレークポイントで停止状態になったときに、デバッグコンソールで表示された lldb プロンプトに repl
を入力すると、UIKit をインポートできる。
もう一つの方法は、lldb を使用して iOS アプリケーションのプロセスにアタッチすることで、repl で UIKit をインポートできる。
以下は手順です。
Xcode で Product -> Show Build Folder in Finder
を選択する。.app ファイルは表示された Build フォルダ内の Products/Debug-iphonesimulator/ にある。そして、このアプリのパスをコピーする(Option キーを押しながら右クリックすると「パス名をコピー」が表示される)。
パスを xcrun lldb
に渡す。
$ xcrun lldb -- <AppPath>
platform select ios-simulator
を実行すると、iOS シミュレータの UUID が表示される。platform connect
コマンドでシミュレータに接続する。
(lldb) platform select ios-simulator
(lldb) platform connect <UUID>
プロセス名を指定して、プロセスにアタッチする。
プロセス名でアタッチする場合、--waitfor
オプションを付けることで、iOS アプリが実行されるのを待ってから、そのプロセスにアタッチすることができる。
(lldb) process attach --name 'AppName' --waitfor
ここでエラーが発生した。
error: attach failed: debugserver is x86_64 binary running in translation, attached failed.
原因は、Xcode は Rosetta を使っていないので、ターミナルアプリは Rosetta を使わずに開く必要がある。
次に、Xcode から iOS シミュレータを起動し、iOS アプリを実行する。
そして、lldb でプロセスを中断し、repl を実行する。 以下の Swift コードを実行すると、Xcode のデバッグコンソールにフォントファミリ一覧が表示されることを確認できる。
(lldb) continue
Process 20380 resuming
(lldb) process interrupt
Process 20380 stopped
(lldb) repl
1> import UIKit
2> print(UIFont.familyNames)
3> :
(lldb)
REPL を終了して lldb に戻すには、コロンを入力するだけです。