Skip to main content

0.5.0

Improvements

Suspend wrappers for methods from generic classes

This release improves the syntax used to call suspend methods from generic classes. Example of such method:

Kotlin
class A<T> {

suspend fun foo(bar: Int): Int = bar
}

In previous version, the method had to be called like this:

Swift with SKIE
try await __SkieSuspendWrappersKt.foo(A<NSString>(), bar: 1)

The new syntax introduces a special function skie that maps the receiver object in a generated Swift type, which can have the same suspend wrappers as non-generic classes. Example:

Swift with SKIE
try await skie(A<NSString>()).foo(bar: 1)

Note that this is a breaking change.

Suspend functions in enums

SKIE now generates the suspend wrapper for the original Kotlin enum. This Kotlin enum is usually hidden behind the enum generated by SKIE, but there are certain use-cases where it's necessary to access it.

Example:

Kotlin
enum class E {
E1;

suspend fun foo(): Int = 0
}
Swift with SKIE
// Previously possible
try await E.e1.foo()

// Now also possible
try await (E.e1 as __E).foo()

Generated code readability

We made several improvements to the generated code to make it more readable:

  • Each Kotlin type (for which SKIE generates Swift code) now has a corresponding Swift file that contains code generated for that type.
  • These generated files are now grouped into folders based on the name of the Kotlin module from which the Kotlin type originates.
  • The type aliases used to avoid name collisions are now simpler and shorter.
  • The style of the generated code is now more unified across SKIE features.

Miscellaneous

Bug fixes

Compiler crash because of a missing class used as Flow type argument

A previous version of SKIE had a bug in logic that determines which types have to be exposed to Swift. More specifically the code didn't look at type arguments of Flows used as a receiver in extension functions. For example the following code didn't compile if the SomeClass was not exposed by another declaration:

Kotlin
suspend fun Flow<SomeClass>.foo() { ... }

Missing pass-through for callback version of suspend functions in enums

Kotlin exposes suspend functions as a function with callbacks in Objective-C. In Swift these functions can also be called using the async/await - a syntax which SKIE uses for suspend interop. However, some projects do not use the async version. Therefore, turn off the SKIE suspend interop and call the callback version directly.

But due to a bug in SKIE, this was not possible for suspend functions from enums.

Example of such function call:

Kotlin
enum class E {
E1;

@SuspendInterop.Disabled
suspend fun foo(): Int = 0
}
Swift with SKIE
E.e1.foo(completionHandler: { result, error in
exit(result?.int32Value ?? 1)
})

Enum implementing interface hierarchy with mutable property

SKIE previously incorrectly generated a property for the following enum (it was marked as read-only):

Kotlin
interface I {

val foo: Int

}

interface MutableI : I {

override var foo: Int

}

enum class E : MutableI {
E1;

override var foo: Int = 0
}

Miscellaneous

  • Fix name collisions between types from different libraries. (#5)
  • Fix Gradle crash caused by SKIE Gradle plugin while building the project on unsupported (non-Macos) platforms. (#11)
  • Fix Flow configuration not being correctly applied for suspend functions. (#9)
  • Flow cancellation now correctly propagates to the parent Swift task.
  • Fix compiler crash caused by having two exposed files with the same name.
  • Fix compiler crash caused by using certain Swift keywords as class names.