I have an existing KMP framework that we use in iO...
# swift-export
n
I have an existing KMP framework that we use in iOS, previously we exported module :swift (with SKIE). It used
api(libs...)
and exports in the
binaries.framework {}
when being created. Now we want to switch to swift export; But I am unsure of the fundamental declaration and exports: • My exporting module is an iOS only module that holds code to access classes through koin • The only other module that we will be consuming in the iOS app is
:domain
which hold use cases and classes; as well as Koin-Modules; which are used in a :di module called from :swift • What should I declare in :swift build.gradle • Do I need to export koin in some way, since koin Module and KoinApplication is available in the common API? • Do I need to export the :di module • Do I need to export the :domain module (with moduleName and flattenPackage) • In the gradle modules below :swift there are also connections to :old_export, the old framework with SKIE. Do I need to handle that for swiftExport in any way? The issues when trying to export, running xcode Build
Copy code
Showing Recent Issues
/Users/.../  /...stuff.../build/SPMPackage/iosArm64/Debug/Sources/StatelyConcurrency/StatelyConcurrency.swift:1:19:
   no such module 'ExportedKotlinPackages'
  @_exported import ExportedKotlinPackages
                    ^


Showing Recent Issues
  The following build commands failed:

  	SwiftEmitModule normal arm64 Emitting\ module\ for\ StatelyConcurrency (in target 'StatelyConcurrency' from project 'Chronos')

  	SwiftCompile normal arm64 /Users/nik/dev/MobileWatchApp/Android/chronos/build/SPMPackage/iosArm64/Debug/Sources/StatelyConcurrency/StatelyConcurrency.swift (in target 'StatelyConcurrency' from project 'Chronos')

  	SwiftEmitModule normal arm64 Emitting\ module\ for\ KotlinxCoroutinesCore (in target 'KotlinxCoroutinesCore' from project 'Chronos')

  	SwiftCompile normal arm64 /Users/nik/dev/MobileWatchApp/Android/chronos/build/SPMPackage/iosArm64/Debug/Sources/KotlinxCoroutinesCore/KotlinxCoroutinesCore.swift (in target 'KotlinxCoroutinesCore' from project 'Chronos')
a
Hi 🙂
no such module 'ExportedKotlinPackages'
The only time I have seen this error is in this ticket: https://youtrack.jetbrains.com/issue/KT-80346 Basically the problem was - user tried to build a library(not an application) with a kotlin/native module exported through swift export. Can you please confirm, that that is your case(that you are not building an application)?
But I am unsure of the fundamental declaration and exports
Basically, the dsl remains the same - everything that was explicitly
export
ed when you used Objective-C export - should remain exported with Swift Export. And one should export only those modules, which public APIs one would like to get access in the swift code. There are also the same transitive export that was with Objective-C export, but with a nicer names 🙂
d
Hi @Artem Olkov, I work on the same project as @Niklas Wintrén . Thanks for the reply, that hint let us progress! It was the case that we did have a (kind of phony) framework-target in our Xcode-project which built the underlying gradle project - and this got solved if we moved the call into the app, nice! Next issue we ran into is:
Copy code
.../iOS/AnimaWatch/  .../Android/.../build/SPMPackage/iosSimulatorArm64/Debug/Sources/IoInsertKoinKoinCore/IoInsertKoinKoinCore.swift:1253:44 type 'any org.koin.core.qualifier.Qualifier' cannot conform to 'Hashable'
Which is:
Copy code
public var scopeDefinitions: Swift.Set<any ExportedKotlinPackages.org.koin.core.qualifier.Qualifier> {
            get {
                return org_koin_core_registry_ScopeRegistry_scopeDefinitions_get(self.__externalRCRef()) as! Swift.Set<any ExportedKotlinPackages.org.koin.core.qualifier.Qualifier>
            }
        }
Is this something known somehow? Or Is it a problem with the koin project?
n
Hi! (forgot that part before ^^) And thank you for your response 🙂 The entire swift part we want to export is different than before, but some of the underlying modules are the same. In this new module that we want to use swiftExport for - there's basically just 2 exported modules (other utility modules for 'time' etc. might be added in the future). I am getting quite a lot of issues that involve missing dependencies and modules.
Copy code
/.../build/SPMPackage/iosArm64/Debug/Sources/Atomicfu/Atomicfu.swift:1:19: error: no such module 'ExportedKotlinPackages'
  @_exported import ExportedKotlinPackages
Copy code
/.../build/SPMPackage/iosArm64/Debug/Sources/StatelyConcurrency/StatelyConcurrency.swift:1:19: error: no such module 'ExportedKotlinPackages'
  @_exported import ExportedKotlinPackages
We have a setup with :domain and :data as the main part of our KMP library, and :data depends on :database which holds sqldelight (touchlab) - which explains the
StatelyConcurrency/StatelyConcurrency.swift:1:19
But I don't want to export anything like that, so hopefully it's something else that's the issue. Adding exports for coroutines fixed some issues - but that feels weird as that's part of the export we want handled, right?
Copy code
swiftExport { 
    export(project(":di"))
    export(project(":domain"))
    export(libs.koin.core)
    export(libs.kotlinx.coroutines.core)
}
commonMain.dependencies { // might as well me iosMain
    api(project(":domain"))
    api(project(":di"))
    api(libs.koin.core)
    api(libs.kotlinx.coroutines.core)
}
How I would want the swiftExport and dependencies api(..) calls, should just be the public facing APIs and classes. How much do I need to adjust this build.gradle, and other build.gradle files I depend on to allow for this :database setup to work?
a
@David Everlöf
Copy code
type 'any org.koin.core.qualifier.Qualifier' cannot conform to 'Hashable'
Oh, that's something that's definitely worth a ticket. IIUC, this should be reproducible by the following snippet:
Copy code
interface Foo
val s: Set<Foo> = emptySet()
Thanks for the report, we'll look into it! In the meantime as a workaround - please don't export
Koin
through swift export 🙂 https://youtrack.jetbrains.com/issue/KT-81540
d
Alright, nice. Is https://youtrack.jetbrains.com/issue/KT-81540 a ticket you created for that? I can't view it
a
Oh, sorry, wrong visibility. Changed to public
1
👍 1
@Niklas Wintrén
```error: no such module 'ExportedKotlinPackages'
@_exported import ExportedKotlinPackages```
As I said before - you see this error because you are trying to use
embedSwiftExportForXcode
inside an xcode target that is not an application. If that is not the case - I would love to see a small reproducer that we can investigate internally, please file a ticket with a reproducer.
How I would want the swiftExport and dependencies api(..) calls, should just be the public facing APIs and classes. How much do I need to adjust this build.gradle, and other build.gradle files I depend on to allow for this :database setup to work?
Actually, for the setup you are describing you don't need to change the gradle. Just remove from current gradle coroutines and koin (the first we do not support at the moment, the latter causes us to fail as mentioned earlier). What you need is to hunt down the kotlin declarations in
:domain
and other your public modules, that are leaking your
:db
module. An example of such declaration:
Copy code
// module: DB
class Foo
// module: DOMAIN
fun bar(): Foo = TODO()
In this example, even if only DOMAIN is exported, the module DB would also be exported (because module DOMAIN leaked into its public surface class Foo, which is a part of public surface of module DB) To hunt down such declarations - please turn on explicit api mode on modules that you are exporting and review your public declarations.
n
Alright, thank you for all your input 😄 We'll jump on SKIE for now as we do want suspend and Flow's; and we will eagerly await swiftExport!