How To Debug App In Xcode
What is Debugging?
Debugging is the process of finding bugs in your apps and removing them. A bug can be considered anything from a simple semicolon error to a whole logical mistake in your code.
Why do you need to learn debugging
It is a known fact that every developer spends more time figuring out why things aren’t working in their code rather than developing it.
If you learn the art of debugging, you will be able to considerably reduce your time spent on fixing things… Sounds Perfect!.
Lets Start
Go Ahead and download the basic project i have setup for you which we will follow along from the github repository.
Its developed in Xcode 7.3 and swift 2, so make sure to have them ready.
The folder contains both the apps to be debugged and the working example for you to go through. Its a really simple two view Controllers code. The first calls the itunes search api to find list of games with keyword fifa and the next view controller just loads the game image.
Time to debug
Xcode Debugging Panel
I have shown the main interface provided by Xcode for debugging your app. It is divided into three parts; Debug panel, Variables panel and the Console.
Debug Panel
Breakpoints
Breakpoint are used to break/pause your code at a certain point of condition (can be a line or a complex expression). They are extremely useful as you can pause your code and inspect the values to find any mistakes in your logic/program.
- Toggle Breakpoints This is a easy switch to disable all breakpoints/enable them at once.
- Play/Pause This button lets you pause your code at a certain time and once you are ready to continue, just press it again to continue execution.
- Step Over Step over is the most important and most used tool in debugging for me. What it does is process the current line of code and then stop the thread at the next line, so essentially you use it to execute and debug your code line by line.
Variables Inspector
Variables Inspector as the name suggest allow you to check and inspect values. The variables are categorized by scope (auto and local). Primitive data types show the value right next to them while the Objects inner variables can be checked by using the dropdown right next to them.
Console
Console shows all the logs you have added in your code using print()
function. Moreover you can use po <varName> in console to output any variable which is currently in scope (A really handy thing).
Running the Project
Open the project and press Run.
Well, there you go. Your first error in action.
So how to proceed ? The error points to a mutating member on a immutable object. If you already know the error and its fix, just go ahead and fix it yourself. However, in case if you dont know how to fix, its time for you to Google!.
This is the most used debugging technique used by programmers i.e Googling the error for a possible solution.
From a novice to a experienced programmer, everyone has to take help of google to find the cause of the error.
Go ahead and copy paste cannot use mutating member on immutable value; is a let constant
into google search.
You would have seen that i removed appList
from my search. Since google would try to search for the string and the possibility exist that the other sources might not have the same variable name, it is advised to remove any string from your search which might be dynamic (different to each user).
Reading Result
First few results include a link to this Stackoverflow thread. From the answers, you will find that
When you use let you cannot change or append or add new things to this variable. change let to var
Thats it. Change the declaration of appList
variable from let to var and your project should run this time.
After running, you should be seeing many rows with fifa in their title. Click any of them and you will be treated with another error.
Stack Traces
First thing to do would be searching for the SIGBART error but you will soon realise that the error is vague and you wont really be able to solve this with this less info.
You switch to stack traces this time. Stack trace is the stack of method calls that the program took to reach current function call. It helps to really see how the program logic has been executed by checking the function calls.
Luckily, in this crash, you already got the exception and the stack trace in the console.
If you will read from bottom to top. you will see that loadView
method is called and then during UIRuntimeOutletConnection
class method a crash occurs.
This is why stack trace is helpful as it gives you hint to proceed further by telling you the method calls that took place.
The current exception points to class is not key value coding-compliant for the key randomLabelOutlet
With this much info, we are ready to solve this one. If you will google for the exception error, you will come across many threads that also points to some outlet connection being broken.
To solve this, we are going to search for randomLabelOutlet
in our project.
And there it is.
Remove the broken outlet and now clicking the first row in tableview would work in the app.
Logical Errors
These are the creepy ones and we have one in our project :D
Run the project and try clicking any of the bottom rows in the list. This time you will be faced with this
A simple google search will show that you need to use if let for optionals unwrapping but the point here is that why is our imageURL nil in the first place!. It definitely works for the first result of the table.
App Flow
Here is a basic recap of what the app does. The first VC downloads the app results for the tag fifa and in the second VC we just download the image from the app icon url and set it in a imageView.
How to proceed
1) Set breakpoint on the print(imageURL)
line
Run the code and try any of the last rows in the table or the first few rows.
For the first few rows, the value in values inspector shows like
___
For the last few rows : ___
2) Checking the source
As you can see image url is for some weird reason nil for the last rows.
To solve it, we need to think back in our code and check where is the image url set from.
Our code sets it in the prepareForSegue
method in firstVC
Seems nothing wrong here, it just get the data from the appList variable and set the url. This forces us to check if our appList variable actually contains proper data. Search for the appList variable and you will soon come to source
There it is.. you see if(index <10) .. that is the culprit and removing that if condition will make this project work as it was intended to.
Conclusion
Thank you for reading this far. Hopefully you would have learned some helpful tips from this tutorial and are a debug ninja now. For any questions you are welcome to ask in our chat room.
For further info
Next Steps
Please take a look at our other tutorials :)