Menu

Debugging

Skip generates fully native apps for both iOS and Android. That means you can utilize the power of each platform’s native debugging tools.

Using the Debugger

For bugs affecting the shared or iOS-only Swift portions of your app, use Xcode’s debugging tools just as you would for any other iOS app. Any fixes you make to shared logic written in Swift will of course fix the same logic bug in the translated Android code. And you can always write unit tests to help.

To debug an Android-specific problem, you can run your Android app right in Android Studio and utilize its own debugging tools. And because all Skip libraries are open source, you’ll be able to dig all the way into Skip’s internals if necessary.

Working in Android Studio also allows you to debug Android unit test failures.


Logging

Messages that you print do not appear in Android logging. Instead, SkipFoundation includes support for importing OSLog and using the standard OSLog.Logger API for dual-platform logging:

import OSLog
...
let logger = Logger(subsystem: "my.subsystem", category: "MyCategory")
...
logger.info("My message")

When you log a message in your app, the OSLog messages from the Swift side of the app will appear in Xcode’s console as usual. The Kotlin implementation of OSLog.Logger, on the other hand, forwards log messages to logcat, which is Android’s native logging mechanism. Using the logcat tab in Android Studio is a good way to browse and filter the app’s log messages on the Android side. You can also view logcat output in the Terminal using the command adb logcat, which has a variety of filtering flags that can applied to the default (verbose) output.


Accessing Transpiled Output

The location of your transpiled output differs for app and framework targets. We discuss how to access your generated Kotlin code in Xcode below. The Platform Customization documentation covers how to work with your Android code in Android Studio.

Framework Transpilation Browse Screenshot

Dual-Platform Apps

For dual-platform apps, Xcode places Skip’s generated Kotlin in a plugins directory deep within Xcode’s DerivedData folder. Skip surfaces this directory as the SkipStone/plugins group in your Xcode project.

Transpiled source location

The first time you transpile - and each first re-transpile after deleting DerivedData - Xcode may not allow you to expand the SkipStone/plugins group. Restarting Xcode fixes the issue, but you can fix it without restarting by explicitly marking SkipStone/plugins as a folder. Highlight the SkipStone/plugins group, then use Xcode’s right panel to set the group Type to Folder.

Transpiled source location

Skip includes the Create SkipLink command plugin to link to the transpiled output of your framework targets in Xcode. To invoke the command, control-click your Skip-ified package or highlight the package and use the File → Packages menu.

Framework SkipLink Screenshot

After running the Create SkipLink command, the new SkipLink Xcode group will allow you to access your framework’s generated Android project and Kotlin source.

Jumping to Kotlin Files

After linking to the transpiled Kotlin files using the instructions above, you can jump to Kotlin files using Xcode’s Open Quickly (cmd-shift-O) command, just as you can jump to Swift files. Transpiled Kotlin files have the same names as their Swift counterparts, but use the .kt file extension.

Keep in mind that in order to work around limitations on Kotlin extension properties and functions, Skip typically moves code from your Swift extensions into the declaring Kotlin class during transpilation. If you defined an extension in a separate file from its declaring type, you may find its transpilation in the Kotlin file of the declaring type rather than the Kotlin file for the extension.

You can also jump to the Kotlin file from an Xcode build error message. When the Kotlin compiler outputs an error message, Skip’s Xcode plugin surfaces it as an Xcode build error in both the Swift and Kotlin source files. Clicking the build error for the Kotlin file will jump to the offending Kotlin code.