Skip to content

frankois944/Swift-Import-Interoperability-with-Kotlin-Multiplatform

Repository files navigation

Swift-Import Interoperability with Kotlin Multiplatform

This project is a playground demonstrating how to import Swift code into a Kotlin Multiplatform (KMP) project using the spmForKMP plugin.

It provides practical examples of Swift-Kotlin interoperability, specifically for iOS testing and development.

These examples are working with any other way to import Swift Code through cinterop.

Features and Examples

The project includes several test files, each focusing on a specific aspect of Swift-Kotlin integration:

1. Basic Interoperability (Basic.swift & BasicTest.kt)

  • Class Instantiation: Creating Swift class instances from Kotlin.
  • Methods: Calling instance, static, and class methods.
  • Properties: Accessing and modifying read-only and mutable properties.
  • Objective-C Name Overrides: Using Swift methods with custom @objc names.
  • Data Types: Passing standard types like NSNumber and handling optional values (nil).

2. Swift Concurrency (Concurrency.swift & ConcurrencyTest.kt)

  • Async/Await: Calling Swift async methods from Kotlin.
  • Coroutines Integration: Wrapping callback-based Swift APIs into Kotlin suspend functions using suspendCoroutine.
  • Error Handling: Managing errors returned via Swift callbacks.

3. Enums and Type Safety (Enums.swift & EnumTest.kt)

  • Swift Enums: Importing and using Swift enums in Kotlin.
  • Type-Safe Enums: Demonstrating the use of strictEnums configuration from the spmforkmp plugin to make imported enums type-safe in Kotlin.

4. Error Handling and Exceptions (Throws.swift, ThrowTest.kt)

  • Handling Throws: Intercepting Swift errors (throws) in Kotlin.

5. Wrapping Swift Native APIs (ObjectWrapper.swift & ObjectWrapperTest.kt)

  • Pure Swift Types: Handling Swift structs and classes that aren't directly compatible with Objective-C/Kotlin.
  • Bridging Pattern: Demonstrating how to expose Swift-only APIs (like third-party libraries) through Objective-C compatible interfaces.

Error Management Helper

The project includes a utility function, executeWithErrorHandling, designed to simplify error management when calling Swift methods that follow the Objective-C error pointer pattern.

Why it helps:

  • Idiomatic Kotlin: It transforms the lower-level Objective-C NSError** pointer pattern into idiomatic Kotlin exceptions (SwiftException).
  • Reduces Boilerplate: You don't need to manually manage memScoped, allocate an error pointer, and check if it's null every time you call a throwing Swift function.
  • Type-Safe Exceptions: It provides a consistent SwiftException type that wraps the underlying NSError, giving you easy access to its localizedDescription and other properties.
  • Better Debugging: Instead of having to inspect an error pointer after each call, you can use standard Kotlin try-catch blocks, making the code cleaner and easier to maintain.

Example usage:

val result = executeWithErrorHandling { errorPtr ->
    swiftInstance.throwingMethod(errorPtr)
}

Configuration

The project uses the spmforkmp plugin, configured in shared/build.gradle.kts. Key configuration highlights include:

Getting Started

To run the tests, you will need a Mac with Xcode and Kotlin Multiplatform setup.

  1. Clone the repository.
  2. Open the project in IntelliJ IDEA or Android Studio.
  3. Run the iOS tests from the shared module.

Feedback and Requests

If you have any feedback, encounter issues, or want to request new examples, please feel free to open an issue or a discussion on the GitHub repository.

Resources

About

A playground about importing Swift Code into a KMP project

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages