Xcodeのブレークポイントを通知センターに表示する

Xcodeのブレークポイントで音を鳴らす」で耳デバッグを紹介されていますが、音を鳴らせない状況ではイヤホンをMacにつなぐと言われているように毎回気軽にデバッグをできないのが難点ではあります。

そこで最近、便利だなと思っているのが通知センターを使う方法です。

Xcodeから起動した際、該当箇所が実行されたかどうかを確認したいというニーズは満たしてくれます。

f:id:dealforest:20180112003713p:plain

通知センターがゴミ通知で溢れるという懸念もありますが、簡単に消せるのであまり気にしていません。

やり方に触れる前に通知を送信する方法に触れておきます。 Mavericks以降では Apple Script から送信することができます。

$ osascript -e 'display notification "[メッセージ]"'

簡単ですね。

それでは実際にXcode経由で通知を送信してみましょう。 通知を送信するにはいくつかの方法があります。

ブレークポイントアクションでApple Scriptを実行

先ほどの通知を送信するコマンドをそのままブレークポイントアクションに設定することで送信することができます。

f:id:dealforest:20180112004122p:plain

デメリットとしては display notification '[メッセージ]' を毎回タイピングしないといけません。 また複数箇所にブレークポイントを設定した場合、どこを通過したのか判別するためメッセージを都度変更する必要もあります。

LLDBコマンドを定義

先ほど述べたデメリットも辛いですが、ブレークポイントの設定箇所をメッセージに入れたくなるのが心情ではないでしょうか。

さらに、めんどくさいことが多いと使わなくなってしまうのは人の性です。 もっと手軽に実行できるようにするためLLDBコマンドにしましょう。

f:id:dealforest:20180112005208p:plain

ブレークポイントアクションと比べると簡単に送信できていますね。

ワンライナーで定義

~/.lldbinit に以下のコマンドを書いておけば d と実行すれば、ブレークポイントを設定しているファイル名と行数をテキストに入れて通知を送信します。

~/.lldbinit

command regex d "s/^[[:space:]]*$/script text='%s L:%d' % (lldb.frame.line_entry.file.basename, lldb.frame.line_entry.line); os.system(\"osascript -e 'display notification \\\"%s\\\"'\" % (text))/"

LLDBコマンドで定義

これくらいの処理でしたらワンライナーで定義しておいたほうが簡単でオススメですが、普段からLLDBコマンドを管理している人のためにLLDBコマンドにもしておきました。

pusher.py

#!/usr/bin/env python

import lldb
import commands
import os

def process(debugger, command, result, internal_dict):
    frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
    line_entry = frame.line_entry
    file_name = line_entry.file.basename
    line_number = line_entry.line
    text = '%s L:%d' % (file_name, line_number)
    cmd = 'display notification "%s"' % (text)
    os.system("osascript -e '%s'" % cmd)

def __lldb_init_module(debugger,internal_dict):
    debugger.HandleCommand("command script add -f pusher.process pusher")
    print "pusher command enabled."
~

~/.lldbinit

command script import path/to/pusher.py
command alias d pusher

これで AirPods を買わなくても済むのかもしれませんね