I'm having some difficulties with my interfaces fr...
# multiplatform
s
I'm having some difficulties with my interfaces from common dependencies getting renamed when built for iOS. I'm basically trying to do some super simple di...a shared kotlin module has a class implementation that I'm trying to pass as a dependency in iOS land to other classes/interfaces defined in other kotlin modules. so for an example that's a bit complicated, I have some common Kotlin modules,
moduleA
and then
moduleB
which has A as a dependency.
moduleA
has
InterfaceA
and a class that returns this type,
class A { fun getInterfaceA(): InterfaceA = SomeImpl() }
, and in
moduleB
, I have a class that takes this interface as a param, so
class B(interfaceA: InterfaceA)
. Now over in iOS land, I have a class
Foo
with an instance of class
B
like so,
let var beeClass: B = B(interfaceA: interfaceA)
where
interfaceA
is a member variable assigned during init, so
var interfaceA: InterfaceA
and
init(interfaceA: InterfaceA) { self.interfaceA = interfaceA }
. Lastly, when I try to create in instance of
Foo
with the help of an instance of class
A
like so,
lazy var foo: Foo = Foo(a.getInterfaceA())
, I get complaints from xcode about the argument types not conforming to the expected types because
InterfaceA
is now called
AInterfaceA
. Moreover, if I go to the definition of class
B
in xcode,
InterfaceA
is named something like
BAInterfaceA
. Casting only seems to cause the app to crash and that's what xcode is suggesting I do. not sure if anyone followed that and has some idea what is going on. is there maybe some way to help the kotlin compiler with binding names or something? This doesn't really feel like a situation where the compiler should be changing the name of this interface and almost wonder if this could be a bug
e
every Kotlin/Native frameworks is its own universe. are you creating a single umbrella framework to export to iOS (👍), or multiple that you expect to work when linked together (👎)? https://touchlab.co/multiple-kotlin-frameworks-in-application/
s
things have changed a bit since this article. I'm using cocoapods and haven't had too many issues using multiple pods from kotlin. this particular naming thing seems odd to me
g
By default, the class & interface exported to objC start with the name of the module AFAIK, I suspect this is your "renaming" issue but it's the default behaviour, and I presume it's "required" due to the absence of package/namespace in objC. But I don't understand why you need to cast / how it's not already handled by the compiler. Are you generating objC code using Kotlin names?
s
what's weird is that I get access to the unchanged name in some cases. the class isn't changing packages or modules...it's just referenced/used in the second module. it's like every module that has the module as a dependency gets a new version of the class or something. if i try to go to the definition of the renamed class in xcode it can't find it so i can't tell anything about it. xcode is suggesting that i cast since the interfaces don't match I guess. it obviously doesn't work. I'm not doing anything special with respect to generating the native code...just letting the kotlin cocoapods plugin do everything
ah, I think I might be able to use the fully qualified name to help avoid some of these renamed classes. i'll have to check for sure later but I have a good feeling about it
ok I got this sorted out. by adding
Copy code
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>{
        binaries.withType<org.jetbrains.kotlin.gradle.plugin.mpp.Framework>{
            export(project(":moduleA"))
        }
    }
to my build script, the resulting framework doesn't have any prefixes derived from the module name, and my interface gets exported correctly. https://kotlinlang.org/docs/multiplatform-build-native-binaries.html#export-dependencies-to-binaries