Breakpoints: Debugging like a Pro

A image with some workers tools, like a hammer and pencils.
Summary
  • Conditional breakpoints allow you to pause execution only when specific criteria are met, avoiding the need to manually skip through irrelevant cases like every cell in a TableView.
  • Symbolic breakpoints trigger when a named function or method is called, making them useful for debugging code inside external libraries or pods where you don't know the exact location.
  • Breakpoints can be customized with actions such as AppleScript, CPU frame capture, LLDB commands, or shell commands — for example, using LLDB expressions to auto-fill login credentials and switching accounts by enabling or disabling breakpoints without rebuilding.
  • The article references WWDC 2017 and recommends Session 404 for learning about new debug tools in Xcode 9.

When I started as an iOS developer, my biggest problem was with app crashes, that’s because I really didn’t know how iOS, Swift, and Objective-C worked. Back then, I wrote a lot of bad code, not worrying about memory usage, memory access, ARC or GCD. That’s simply because I didn’t know about that stuff. I was a beginner, for God sakes.

Like most beginners, Stack Overflow community taught me a lot about “doing things the right way”. I’ve learned a lot of tricks that helped me improve my work process. In this article, I’ll share some of them about the most important tool used in this learning process: the breakpoints!

So, get your shovels and let’s go dig in 🙂

Breakpoints

The Xcode Breakpoints is a powerful tool and there is no doubt about it. Its main purpose is to debug code, but what if I say that they can offer more than that? Ok, let’s start with the tricks!

Conditioning breakpoints

Maybe you have already gotten yourself in a situation where your TableView is working so well for all users models, but there is a particular one that is causing some trouble. To debug this entity, the first thing that you may think is: “Ok, I will put a breakpoint on cell loading and see what is going on”. But for each cell, even the working ones, your breakpoint will be activated and you will have to skip it until you have reached one that you want to debug.

The Office TV show gif, saying "please god, no"

To solve this issue, you can go ahead and give your breakpoint a condition to stop, like I did for the user named “Charlinho”.
A conditional breakpoint screenshot

Symbolic Breakpoints

“Relax, I will use a pod, that should save us some work.”

Who never said that? But using a pod or an external library you are importing external code into your project and the way it was written might be unknown. Let’s say that you tracked an error occurring on some function on a pod, but you don’t know where the function is in the code. Just take a breath, keep it cool… you have Symbolic Breakpoints.

These breakpoints are activated when a previously declared symbol is called. This symbol can be any free functions, instance and class methods, whether in your own classes or not. So to add a breakpoint in a function, no matter who’s calling it, you just have to add a Symbolic Breakpoint observing the function that you want to debug. In my sample below, I observe the method UIViewAlertForUnsatisfiableConstraints. This method will be called every time that Xcode finds some Autolayout issue. You can see a more advanced tip on this post.

A Symbolic breakpoint option screenshot

Customizing breakpoints

Like I said previously, breakpoints are a powerful tool. Did you know that you can even add custom actions on a breakpoint? Yeah, you can do that! You can perform an AppleScript, Capture CPU Frame, use LLDB (Low-level Debugger) commands and even shell commands.

To do that you can simply click on the right button and select edit breakpoint

OK, you could be thinking: “Cool! But why?”

I’ll give you a good use case that will improve your work. The most common feature on an app is the Login, and sometimes testing it is a little bit boring. Having to type the user and password multiple times – if you are using an admin and a normal account – could make the process a little nasty. The common approach to “automate” the login screen is to create a mocked entity and use it into an if debug clause. Something like this:


struct TestCredentials {
    static let username = "robo1"
    static let password = "xxxxxx"
}

private func fillDebugData() {
     self.userNameTxtField.text = TestCredentials.username
     self.passwordTxtField.text = TestCredentials.password
}

But hey, you can use breakpoints to make things a little easier!

Go into your login screen, add a breakpoint and then add two LLDB expressions that will fill your user and password. Like I did in the example below:

A Custom breakpoint executing express commands.

With that in mind, you can add two breakpoints with different credentials. To switch between them, you just have to enable/disable the one that you want to test. There is no rebuild required once you are changing the user on the fly.

Pretty cool, huh?

COMBO BREAKER!

The WWDC 2017 was happening while I was writing this article. They launched some cool stuff like the new Xcode 9, for example. If you want to know what is new with debug tools on Xcode 9, I strongly recommend watching the Session 404.

That’s all folks! Now you know the basics Breakpoint tricks that helped me a lot when I was a beginner. Are there any cool tricks that I didn’t mention? Do you have any good ones too? Please feel free to share them in the comments!

See ya!

FAQ

What are conditional breakpoints and when should I use them?

Conditional breakpoints allow you to set a condition for the breakpoint to stop. They are useful when, for example, a TableView works well for most user models but a particular one is causing trouble. Instead of skipping the breakpoint on every cell, you can add a condition so it only activates for the specific entity you want to debug.

What are Symbolic Breakpoints used for?

Symbolic Breakpoints are activated when a previously declared symbol is called. This symbol can be any free function, instance method, or class method, whether in your own classes or not. They are helpful when you need to debug a function inside an external library or pod without knowing where the function is in the code. An example is observing the method UIViewAlertForUnsatisfiableConstraints, which is called whenever Xcode finds an Autolayout issue.

Can I customize actions on a breakpoint?

Yes. You can add custom actions to a breakpoint, including performing an AppleScript, capturing a CPU Frame, using LLDB (Low-level Debugger) commands, and even shell commands. To do that, right-click on the breakpoint and select edit breakpoint.

How can breakpoints help automate login testing?

Instead of creating a mocked entity inside an if debug clause, you can add a breakpoint on your login screen with two LLDB expressions that fill in the username and password fields. You can also create multiple breakpoints with different credentials and enable or disable them to switch between accounts on the fly, with no rebuild required.

Where can I learn about new debug tools in Xcode 9?

The article recommends watching Session 404 from WWDC 2017 to learn what's new with debug tools in Xcode 9.

About the author.

Alan Ostanik
Alan Ostanik

A video games addict, really likes to listen to good music and play guitar on his spare time. Currently in love with Swift, and a believer that one day robots will dominate the Earth.