💻️

Xcode: デバッガでの表示文字列をカスタマイズする

2024/12/13に公開

はじめに

ことの起こりは以下のTweet。

https://x.com/tobi462/status/1867130989404991905?s=46&t=0nxR5yoUJ3frMlbGCzcEZA

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にできるのか?

これでDateextensionにできたら良かったんですが、できなかったですね。
何か方法があるのかしら。


12/14追記)

リリース版コンパイルできなかったので修正しました。済みません。


12/14追記)

Xのほうで、~/.lldbinitを使う方法が投稿されていました!

https://x.com/rintaro/status/1867703853745156356

Discussion