WWDC 2014: Debugging in Xcode 6で発表されたカスタムQuick Lookが面白そうなので今更ですが触ってみました。
Quick Lookとは
オブジェクト変数の現在の状態を、ポップアップ表示でグラフィカルに表示してくれる機能です。クイックルックボタンをクリックするか、Xcode下部のデバッグアリアで変数を選択した状態でスペースキーを押せば見ることができます。
クイックルックで見ることができるオブジェクトタイプは次の通りです(Quick Look Data Typesから抜粋)。
上記に当てはまらないタイプだったとしてもデフォルトのクイックルックは表示されます。
自分が作ったオブジェクトクラスでもレンダリングメソッドを追加することでクイックルックを拡張させて使うことができます。今回はその方法を書きます。
独自クラスでQuick Lookを使う
debugQuickLookObjectメソッド
クイックルックを使うには独自クラス内でdebugQuickLookObject
という名のメソッドを実装します。この関数はブレークポイントで止めてクイックルックボタンをタップされた時に呼ばれます。
func debugQuickLookObject() -> AnyObject? {
// 色々やる
return [オブジェクト]
}
戻り値には表現したいデータのオブジェクトを渡すのですが、何でも返せばいいというわけではありません。以下のうちのどれかにする必要があります。
※Get QuickLook Preview of Swift objects in XCodeから抜粋
注意点
このメソッドは一時停止しているアプリのデバッグ時に走るメソッドであるため、実装の無駄をなくして必要なコードだけを書くべきだということです。実行中のアプリに影響が出る可能性を考慮し、もし可能であれば戻り値をキャッシュすることも考えます。
実装
では実際に試してみます。試しにこんなviewを作って
こんな実装をしておきます。
class CustomView : UIView {
@IBOutlet var customView: UIView!
@IBOutlet weak var viewTitle: UILabel!
@IBOutlet weak var photoTitle: UILabel!
@IBOutlet weak var imageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
self.comminInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.comminInit()
}
private func comminInit() {
let view = Bundle(for: type(of: self)).loadNibNamed("CustomView", owner: self, options: nil)?.first as! UIView
self.addSubview(view)
customView.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
}
func debugQuickLookObject() -> AnyObject? {
return "viewTitle = \(viewTitle.text), photoTitle = \(photoTitle.text)" as AnyObject?
}
}
この状態で呼び出し側でブレークポイントをかけてクイックルックを見るとこうなります。
ちゃんとStringで取れてます。
もちろん次のようなコードにすれば
func debugQuickLookObject() -> AnyObject? {
return imageView
}
ちなみに無理やりですがこのようなコードを書くと
func debugQuickLookObject() -> AnyObject? {
let urlStr:String = "https://www.google.co.jp/"
let url:NSURL = NSURL(string:urlStr)!
return url as AnyObject?
}
webページが表示されます。文字も入力できます。
ちなみにEnter押して検索実行したらこんな表示が出てきました。
openにするとSafariでgoogleが表示されました。
思ったこと
以前Javaを書いていた時にtoStringをオーバーライドして各プロパティの値を出力していたときがあり、それと同じようなものかなと思いました。
わざわざこれを仕込んでおく必要がある場面がどれくらいあるかわかりませんが、グラフィカルに状態を表示してくれるのは良いことですし見たい値を一気に見られるように設定しておけば楽になることもあるので覚えておいても損はない機能かなと思いました。