💻️
Xcode: デバッガでの表示文字列をカスタマイズする
はじめに
ことの起こりは以下のTweet。
Xcode のデバッガだと日付が UTC 表示されちゃうけれど、これカスタマイズして日本時間に変更する方法って無いんかな?
ちょっと調べてみました。
Xcodeのデバッグインスペクタに文字列を表示する
Xcode 16から、@DebugDescription
というマクロが使えるようになっています。
このマクロ、_lldb_summary
というスタティック変数を定義して、そこにLLDB用の文字列(StringProtocol
)をUTF8で入れるんですね。
入れる値はvar debugDescription: String
のものです。
debugDescription
は、CustomDebugStringConvertible
というプロトコルで定義されているようなので、それに準拠するようにします。
ただし、この@DebugDescription
を付けた場合、debugDescription
で式を実行してはいけないらしく、"\(変数)"
以外の形式の式(例えば"\(変数.formatted())"
など)を入れると以下のエラーになります。
デバッグ時に重い処理や危険な処理を実行したらダメ、ということでしょうか。@DebugDescription
を付けなければ式を入れても大丈夫です。
例えば自分の日付型(?)を定義する
以下のように定義します。
#if DEBUG
@DebugDescription
struct MyDate: CustomDebugStringConvertible {
var value: Date {
didSet {
self.dateString = MyDate.makeDateString(date: self.value)
}
}
var dateString: String
init(_ dateValue: Date) {
self.value = dateValue
self.dateString = MyDate.makeDateString(date: dateValue)
}
static func makeDateString(date: Date) -> String {
return date.formatted(
Date.FormatStyle(date: .numeric, time: .shortened)
.year(.defaultDigits)
.month(.twoDigits)
.day(.twoDigits)
.hour(.twoDigits(amPM: .omitted))
.minute(.twoDigits)
.second(.twoDigits)
.timeZone(.genericName(.short))
)
}
var debugDescription: String {
return "日付: \(self.dateString)"
}
}
#else
struct MyDate: CustomDebugStringConvertible {
var value: Date
init(_ dateValue: Date) {
self.value = dateValue
}
var debugDescription: String {
return "日付: \(self.value)"
}
}
#endif
それで、以下のようなコードを実行し、Xcodeでデバッグします。
var date = MyDate(Date.now)
print("date: \(date)")
date.value.addTimeInterval(6 * 60 * 60)
print("added date: \(date)")
以下のように、デバッガのインスペクタに値が文字列で表示されます。
Dateのextensionにできるのか?
これでDate
のextension
にできたら良かったんですが、できなかったですね。
何か方法があるのかしら。
12/14追記)
リリース版コンパイルできなかったので修正しました。済みません。
12/14追記)
Xのほうで、~/.lldbinitを使う方法が投稿されていました!
Discussion