Last active
June 2, 2022 02:02
-
-
Save kastiglione/d7fc5b3b3ebab1248333b858591e06b0 to your computer and use it in GitHub Desktop.
Swift helpers, and the lldb setup to use them. Presented @ SLUG https://speakerdeck.com/kastiglione/advanced-debugging-and-swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension UIView { | |
/// Example: call someView.nudge(0, 30) | |
func nudge(_ dx: CGFloat, _ dy: CGFloat) { | |
self.frame = self.frame.offsetBy(dx: dx, dy: dy) | |
CATransaction.flush() | |
} | |
} | |
extension UIView { | |
/// Example: po UIView.root | |
static var root: UIView { | |
return UIApplication.shared.keyWindow!.rootViewController!.view | |
} | |
} | |
extension UIViewController { | |
/// Example: po UIViewController.current | |
static var current: UIViewController { | |
var controller = UIApplication.shared.keyWindow!.rootViewController! | |
if let child = (controller as? UINavigationController)?.topViewController { | |
controller = child | |
} | |
if let container = (controller as? UITabBarController)?.selectedViewController { | |
controller = child | |
} | |
return controller | |
} | |
} | |
extension UIView { | |
/// Example: po UIView.current | |
static var current: UIView { | |
return UIViewController.current.view | |
} | |
} | |
extension UIView { | |
/// Utility used by others helpers. | |
func tree() -> UnfoldSequence<UIView, [UIView]> { | |
return sequence(state: [self]) { state in | |
guard let view = state.popLast() else { return nil } | |
state.append(contentsOf: view.subviews.reversed()) | |
return view | |
} | |
} | |
} | |
extension UIView { | |
func grep(_ pattern: String) -> [UILabel] { | |
return self.tree() | |
.compactMap { $0 as? UILabel } | |
.filter { $0.text?.range(of: pattern) != nil } | |
} | |
} | |
extension UIView { | |
/// Example: po UIButton.first(in: UIView.current) | |
static func first(in root: UIView) -> Self? { | |
return root.first { _ in true } | |
} | |
/// Example: po UIView.current.first { (b: UIButton) in b.currentTitle == "Tap Me" } | |
func first<T: UIView>(where match: (T) -> Bool) -> T? { | |
return self.tree() | |
.lazy | |
.compactMap { $0 as? T } | |
.filter(match) | |
.first | |
} | |
} | |
extension UIView { | |
func fillText(_ text: String) { | |
if let textField = UITextField.first(in: self) { | |
textField.text = text | |
CATransaction.flush() | |
} | |
} | |
} | |
extension UIView { | |
// Example: po someView.screenshot("/some/path.png") | |
// Example: shell open /some/path.png | |
func screenshot(_ path: String) { | |
let renderer = UIGraphicsImageRenderer(bounds: self.bounds) | |
let png = renderer.pngData { _ in | |
self.drawHierarchy(in: self.bounds, afterScreenUpdates: false) | |
} | |
do { | |
try png.write(to: URL(fileURLWithPath: path)) | |
} catch let e { | |
print("Failed to write \(path): \(e)") | |
} | |
} | |
} | |
// Example: someButton.sendActions(for: $touchUpInside) | |
let $touchUpInside = UIControl.Event(rawValue: 64) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# create the `alias` used below | |
command alias alias command alias | |
# to load python lldb commands | |
alias import command script import | |
# to run lldb "shell" scripts | |
alias source command source | |
# to run a shell command, like `open` | |
alias shell platform shell | |
# tell lldb to assume swift, not objc | |
settings set target.language swift | |
alias clear-lang settings clear target.language | |
# `load_swift` command is used to load helpers written in swift | |
import ~/load_swift.py | |
# load_swift path/to/helpers.swift | |
alias action breakpoint command add | |
alias autocontinue breakpoint modify --auto-continue true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lldb | |
import os | |
kNoResult = 0x1001 | |
@lldb.command("load_swift") | |
def load_swift(debugger, path, ctx, result, _): | |
with open(os.path.expanduser(path)) as f: | |
contents = f.read() | |
options = lldb.SBExpressionOptions() | |
options.SetLanguage(lldb.eLanguageTypeSwift) | |
error = ctx.frame.EvaluateExpression(contents, options).error | |
if error.fail and error.value != kNoResult: | |
result.SetError(error) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment