Debugging iOS with console

Yoni Vizel
3 min readDec 6, 2022

--

Hey there!
As a developer, I’m sure you know that debugging your iOS app can sometimes be a pain. But fear not, there are plenty of cool console commands and debug technics that can make your debugging process a lot easier.

Print and calculate data from your app

  • One of the most commonly used commands is po, which stands for "print object". This command allows you to print the description of an object in the console:
po myButton
// Output:
<UIButton: 0x7fcf8040b600; frame = (0 0; 100 50); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600003e9c840>>
  • Another useful command is p, which stands for "print". This command allows you to evaluate an expression and print its result in the console:
p myVariable
// Output:
(int) $0 = 42
  • To set a breakpoint, you can use the following command:
breakpoint set -n myFunction
// Output: This will set a breakpoint at the beginning of the myFunction function. Your app will pause when it reaches that point.
breakpoint set --file myFile.swift --line 42
// Output: This will set a breakpoint at line 42 in myFile.swift
  • Another advanced command is expression, which allows you to evaluate an expression and print its result in the console. This can be useful if you want to check the value of an expression that is not a simple variable, such as a complex calculation or a function call:
expression myFunction(1, 2)
// Output: pointer of the result
(id) $0 = 0x0000000105b7
// And then you can print it
p $0
// And receive the real result
(int) $1 = 3

You can use the po command to evaluate a function and its arguments, but it is only useful if the function returns an object value. If the function returns a non-object value, you should use the expression or print(or its shortcut: p) commands instead.

  • The frame variable command allows you to see the values of all the local variables in the current stack frame. This can be useful if you want to inspect the state of your app at a specific point in time, such as when it is paused at a breakpoint or an exception.
frame variable
(Bool) isSuccessed = true
(String) countryCode = "asia/jerusalem"
(@thick MyApp.MyClass.Type) self = ... // very detailed...

Until now we talked about how to print and understand your code. But, what if you want to change it on run time?

Change data in your app

  • The expr command is similar to the expression command that I mentioned earlier. It allows you to evaluate an expression and print its result in the console. The main difference between these two commands is that expr is more powerful and has more advanced features, such as function calls and conditional statements, and the ability to assign values to variables:
expr myVariable = 42 // myVariable is a variable from your app, and you just change it...

So if you know how to change your variables on run-time, the complementary command for getting full access on the run-time is to Move the instruction pointer. By doing that, you will able to check and improve your code again and again until you’ll receive the requested function…

  • To move the instruction pointer, you can use the thread jump command. This command allows you to jump to a specific line of code in your app, which can be useful if you want to change the execution flow of your app or skip over certain lines of code.
  • The thread jump command allows you to jump to a specific line of code in your app, which can be useful if you want to change the execution flow of your app or skip over certain lines of code:
thread jump --file myFile.swift --line 42
// Output: your instruction pointer will move to myFile.swift file, at line 42

The next time your app hits that line of code, it will continue executing from that point. Keep in mind that jumping to a specific line of code can cause your app to behave unexpectedly, so use this command with caution.

--

--