Chapters

Hide chapters

Kotlin Multiplatform by Tutorials

First Edition · Android 12, iOS 15, Desktop · Kotlin 1.6.10 · Android Studio Bumblebee

B. Appendix B: Debugging Your Shared Code From Xcode
Written by Carlos Mota

Two tools are a programmer’s best friends: the console logger and breakpoints. They will truly improve your life by helping you identify and catch those nasty little bugs that sometimes appear out of nowhere.

You’ve used the logger throughout this book. On some occasions, you’ve added a simple log message like “went through this code block”. On other occasions, you’ve printed all the variables in a method. Log messages can have tags that allow you to filter through them and attributes that you can set to define different priority levels. This can help you easily understand where something went wrong.

Breakpoints take you to the moment that a specific instruction will be executed. You can see all the steps that lead to this stop and all that will succeed. Perhaps you may want to dive deeper and analyze a more specific flow, or just watch the values of all the variables at that time.

Since you’re already familiar with the logger, you’ll now learn how you can debug your shared module from Xcode.

Debugging the shared module

Both Android Studio and Xcode have great debugging capabilities. The native code is simple to debug on both IDEs. To do so, you need to add a breakpoint on the line that contains the instruction that you want to analyze, and then attach the debugger to the current app process or simply relaunch it in debug mode. For both options, the app halts before executing that instruction.

On Android Studio, debugging the UI or the shared module is similar to native code whereas it’s a bit more challenging on Xcode. Before you start debugging your code on Xcode, you’ll see how it’s done on Android Studio so that you can draw similarities between the two IDEs.

Debugging in Android Studio

The steps required to debug the shared module are the exact steps described earlier — but instead of adding a breakpoint on the Android app, you need to add it on the shared module.

Fig. B.1 - Android Studio Debugger Window
Fig. B.1 - Android Studio Debugger Window

Before reaching a breakpoint, the app halts. You’ll see a screen similar to the one in the image. Here’s a step-by-step description of what you can do in debug mode:

  1. Relaunches the app in debug mode.
  2. Attaches the debugger to the app, without relaunching it.
  3. Line breakpoint. Identifies where the app should suspend. This instruction will only be executed if you continue the debug process.
  4. If you want to resume the app, you can click on this green arrow. The app will halt again at the next breakpoint.
  5. Stops the app.
  6. Shows the list of breakpoints that you’ve set.
  7. Mutes breakpoints. While enabled, the app won’t suspend on any breakpoint.
  8. Step over this instruction. Allows you to navigate to the next instruction inside the same scope.
  9. Step into. Shows you the next method that’s going to be invoked. It doesn’t need to be at the same level as this line of code if the next instruction is a call to another class. This is contrary to step over, which would jump to the next instruction inside the same method.
  10. Force step into the next instruction. This action is similar to the previous one. The difference is that if the next method that’s going to be invoked is from a third-party library. It navigates into that specific call if you have its source code or shows you the generated stubs if you don’t. Step into would probably skip it and halt only on your next instruction.
  11. Step out from the current instruction. The rest of the code will execute, and the debugger will halt again when the method that was suspended executes.
  12. Add a new watch. With this option, you can inspect any property or run any method that’s available on the current running scope.
  13. The list of watchers. When the app halts, a list of variables that you can analyze is immediately shown. All the watchers that you add in the previous point will also be displayed here.

And that’s it! You can find the final project of the book in this appendix materials. Open it in Android Studio, add a breakpoint and run the app in debug mode. Try out the actions that you have available, follow a network request and inspect its response — and have fun. :]

Debugging in Xcode

As you can see, debugging the shared module from Android Studio is simple. If you want to do the same thing in Xcode, it’s more…challenging. :]

If you want to debug the iOS UI, it uses the process you’re already familiar with. You just need to set a breakpoint, and the next time the app goes through that instruction it will halt.

But if you want to debug the shared module, it will take you a couple more steps. First, you’ll need to install the Kotlin Native Xcode Support plugin. You can find it on Touchlab GitHub repository or in the materials section of this appendix.

Note: The last version of this plugin is from December 2020. Although Touchlab is currently providing support to the newest Xcode versions, there’s no guarantee, for now, that it will support future versions. Moreover, there are a couple of people reporting issues with Xcode 13.1 — although at the time of this writing, everything is working without any issue on that specific version.

Installing the Kotlin Native Xcode Support plugin

To install the plugin, you need to first close Xcode. Then, open the command line and go to the repository root folder. There, enter:

./setup.sh

Here’s what you’ll see in the console:

Creating new Kotlin plugin
Creating new Kotlin language spec

This indicates you’ve installed the plugin successfully.

Note: According to the plugin documentation, if you’re using Xcode 11, you need to change the path to the xcode11 directory and run instead:

./setup-xcode11.sh

The next time you open Xcode, you’ll see the following prompt:

Note: The “Kotlin.ideplugin” code bundle is not provided by Apple. Loading code not provided by Apple can have a negative effect on the safety and stability of Xcode or related tools.

Every time you install a third-party plugin, you’ll see a similar notification. Since Apple didn’t release or validate it, they cannot guarantee its behavior.

Until there’s direct support on the IDE, you need to use this plugin — so click on Load Bundle. When this process ends, open the project from materials.

Compile and install the app to guarantee that everything is working as expected. Before running the app, don’t forget to generate the shared framework by executing the following code:

./gradlew createSwiftPackage

Now that you have the project up and running, on the left side panel of Xcode, below the Pods folder, right-click on the empty area and select “New Group”. This will add a new folder to the project. Rename it to Shared.

You’re going to add the source code of the shared module that your iOS app uses. Once again, right-click over the newly added Shared folder and select “Add Files…”.

A new window will open. Navigate backward to the shared module, and in this folder select the commonMain and iosMain directories. Select the option Create folder references for any added folder to avoid copying those files to the project.

Your screen will be similar to this one:

Fig. B.2 - Xcode Folder Hierarchy
Fig. B.2 - Xcode Folder Hierarchy

The Kotlin classes now have syntax highlight, which makes it easier to read the code. Open FeedPresenter.kt and identify the method’s visibility, strings, for cycle, nullability, etc.

Time to test the debugging. In this file, add a breakpoint on the call to fetchFeed inside the for cycle of fetchAllFeeds.

Note: To add a breakpoint on Xcode, you just need to click on the line number. Here, it can have two different states: disabled if it has a transparency and enabled in case it doesn’t. To remove a breakpoint, click on it and drag it to the right.

Compile and run the app.

Fig. B.3 - Xcode Halt At a Breakpoint
Fig. B.3 - Xcode Halt At a Breakpoint

Xcode suspends your app just before running this instruction.

Debugging your iOS app

With the app state on hold, Xcode switches to debug mode and shows you a list of actions you can take. As you can see, they’re similar to the ones that Android Studio offers:

Fig. B.4 - Xcode Debugger Window
Fig. B.4 - Xcode Debugger Window

  1. This action compiles and runs the application.
  2. As soon as you add a breakpoint, the next time that line is about to be executed, the app will automatically halt. You don’t necessarily need to relaunch or attach the debugger.
  3. By dragging this action up, you can move the app execution to a previous line.
  4. This action allows you to disable all breakpoints.
  5. When the app reaches a breakpoint, it suspends. No more code will be executed without a user action. This one allows the app to resume and continue until it finds another breakpoint.
  6. Step over. You can go to the next instruction without needing to add another breakpoint.
  7. With the step into action, you can access the method that’s going to be invoked.
  8. Step out from the current execution. The app will continue to run until this method returns.
  9. By right-clicking in this area, you can select “Add Expression…” and the instruction that you want to monitor will be displayed in this list.

As you can see, the Kotlin Native Xcode Support Plugin is a great tool to debug your business logic from Xcode.

Uninstalling the Kotlin Native Xcode Support plugin

There isn’t an option to uninstall a plugin directly from Xcode. The best solution is to close the IDE and go directly to the directory where they’re installed:

~/Library/Developer/Xcode/Plug-ins/

Remove the ones that are no longer needed. In this case, it’s the Kotlin.ideplugin.

Where to go from here?

Well done! Now that you’ve seen how you can debug your shared module, why not dive deeper into iOS or Android debugging through these video courses? Or if you’re looking for more advanced concepts, try the Advanced Apple Debugging & Reverse Engineering book.

In the next appendix, you can learn how to reuse your UI between Android and desktop. Now that you know how to share your business logic, see how you can also share your Compose UI.

See you there. :]

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.