0.7.0
Improvements
Compilation speed optimizations
This release significantly reduces the compilation time overhead caused by SKIE. The improvements are most noticeable in medium and large projects or projects where SKIE generates a lot of Swift code.
The optimizations used to achieve this improvement also change what causes most of the overhead and how users can reduce it.
There are two fundamentally different primary sources of overhead in the SKIE compilation process:
- Overhead that is dependent on how many and which SKIE features are used.
- Overhead that is dependent on the number of exported declarations to Swift.
The first kind of overhead is mainly caused by generating and, more importantly, compiling the generated Swift code. The more features are used, the more code is generated, and the longer the compilation takes. The second kind of overhead is caused by SKIE having to iterate over all exported declarations and perform certain actions. The difference here is that these iterations and actions must be performed regardless of the feature configuration of those declarations.
The first kind of overhead can be reduced by configuring SKIE not to enhance certain declarations or by not exporting them to Swift. The second kind of overhead can be reduced only by limiting the number of exported declarations.
Previously, these two sources of overhead had a more or less similar impact on the compilation time. Therefore, it was effective to reduce the overhead by limiting the usage of SKIE features. However, the optimizations in this release changed the situation. Not only are both sources of overhead significantly reduced, but the first kind is now much less impactful than the second kind. The only exception are the default arguments, which were not effected by the optimizations.
This means that limiting the use of SKIE features is no longer that effective in reducing the compilation time overhead. Instead, focus on limiting the number of exported declarations to Swift. Technically speaking, this was always the better approach because it simultaneously reduced both sources of overhead. But more importantly, doing so improves the baseline compilation time because the Kotlin compiler also has to do a lot of additional work for exported declarations.
Automatic support for CocoaPods CInterop types
SKIE cannot directly generate code that uses types provided by custom CInterop bindings. The problem with these types is that SKIE doesn't know what framework will provide their implementation at runtime. Therefore, the correct framework names must be manually configured using the SKIE configuration.
Built-in CInterop types work out of the box because SKIE can derive the framework name from the class package.
For example, types from Foundation
, UIKit
, etc., are supported in this way.
Starting with this release, SKIE can also automatically configure CInterop bindings provided by the CocoaPods Gradle plugin.
Read more about support for CInterop types
Configurable Swift library evolution
Up until now, SKIE always compiled Swift code with Swift library evolution enabled. Due to the nature of the Kotlin Multiplatform project, having library evolution enabled is usually not necessary. For this reason, SKIE now compiles Swift code with library evolution disabled by default.
The only exception is when building XCFrameworks, which require the library evolution to be enabled. However, if this restriction is lifted in the future, SKIE will also disable library evolution for XCFrameworks. Therefore, do not rely on this behavior, and explicitly enable the library evolution if you need it.
The Swift library evolution can be enabled using the following Gradle configuration:
skie {
build {
enableSwiftLibraryEvolution.set(true)
}
}
This is a breaking change for projects with Frameworks that are built and updated separately from the Framework consumers. If you need Swift library evolution, explicitly enable it using the above-mentioned configuration.
Automatic configuration for SKIE coroutines features
In previous versions, SKIE automatically added SKIE Runtime dependency, which is needed for Coroutines interop features. This Runtime dependency transitively depends on the Kotlin Coroutines library, and therefore, the Coroutines library was also added to the project. This behavior didn't make a difference for projects that already used Coroutines, but it was not ideal for projects that didn't. The problem was that SKIE effectively added a large and unnecessary dependency for those projects. To avoid this issue, users had to disable the Coroutines interop manually using the SKIE Gradle configuration.
From now on, SKIE adds the runtime only if it detects that the Coroutines library is used in the project. If not, it will automatically disable the Coroutines features. Therefore, this configuration is no longer necessary to do manually unless you use Coroutines but don't want to use the SKIE Coroutines features.
Additionally, the Runtime dependency is now included only in the produced framework, not as a dependency of the final shared module. This way, the Runtime is no longer accidentally added to other modules that depend on the shared module.
Miscellaneous
- Support for Kotlin 1.9.24
- Add a warning/comment to every file generated by SKIE to prevent accidental modifications
- Improve error messages when the Kotlin framework uses a forbidden name like
Protocol
,framework
, etc.
Bug fixes
- Fix a compilation crash caused by a generated companion object accessor in enums with a case named
companion
- Fix that SKIE creates an invalid Swift header if there is no generated Swift code
- Fix a compilation crash caused by Hashable conformance of sealed classes that have supertypes with a CInterop type as a type argument
- Workaround a bug caused by conflicting Obj-C and Swift names between two classes (#69)
- Fix the issue of SKIE incorrectly overriding the minimum target OS version in some cases
- Fix some edge cases in the detection of the Kotlin Gradle plugin version
- Fix dependencies of the SKIE plugin and Runtime; specifically, remove Kotlin stdlib dependency to prevent unintended version conflicts