https://kotlinlang.org logo
#ios
Title
# ios
a

Anthony Pages

05/04/2021, 2:01 PM
Hi ! I'm having some dependencies issues with KMP and iOS Framework. I have the following architecture: 2 KMP modules: • KMPlibAPI: contains only interfaces • KMPlib: contains implementations and usages of KMPlibAPI When I build the KMPlib, the header include the KMPlibAPI definition. But I didn't wanted to be included in my KMPlib framework, I just wanted to have a needed references to KMPlibAPI. Exemple of what I have:
Copy code
//KMPlibAPI.h
@protocol KMPAPIFoo
@required
- (void)bar __attribute__((swift_name("bar()")));
@end;


//KMPlib.h
@protocol KAFoo  // <----- here we have a redefinition of the protocol.
@required
- (void)bar __attribute__((swift_name("bar()")));
@end;

@interface Baz
- (void)injectFoo:(KAFoo)foo  __attribute__((swift_name("injectFoo(foo:)"))); // <----- and here we are using it, instead of using KMPAPIFoo
@end;
I've tried to put the dependencies in
compileOnly
into gradle, but nothing changed. Anyone is confortable with gradle compilation option for Kotlin native and dependencies ?
l

louiscad

05/04/2021, 5:21 PM
Hello,
compileOnly
isn't supported in Kotlin/Native. The solution is to set the visibility of implementation details to
internal
a

Anthony Pages

05/05/2021, 8:19 AM
Hello Louis, What do you mean by "set the visibility of implementation details to `internal`" ? The aim of splitting the API and the injection is to have the following behavior : 2 ios Project: • 1 swift package • 1 iOS app the swift package have the following implementation :
Copy code
import KMPlibAPI

public class SampleFoo: NSObject, Foo {
   func bar() { } 
}
and into the app
Copy code
import KMPlib
import MySwiftPackage

let foo = SampleFoo()

let baz = Baz()
baz.injectFoo(foo)
As you can see, I can't set
injectFoo
to
internal
here, otherwise I won't be able to call it through the iOS app. I'm not sure if I made it clear ?
l

louiscad

05/05/2021, 8:23 AM
Then don't make
injectFoo
internal, but make the rest
internal
?
a

Anthony Pages

05/05/2021, 8:24 AM
What do you call the rest ? the
baz
class ?
l

louiscad

05/05/2021, 8:25 AM
Whatever you don't want to expose to Swift.
a

Anthony Pages

05/05/2021, 8:27 AM
Yes but as soon as I expose
injectFoo(foo:Foo)
into the KMPlib, it will include the Foo protocol into the KMPlib.h and that's my point, I don't want to have the protocol exposed in the KMPlib.h but have a reference to the KMPlibAPI.h (which contain the
Foo
protocol)
l

louiscad

05/05/2021, 8:29 AM
I think what you want to do with what you have is simply impossible. Even in pure Kotlin, it's impossible to have a public declaration exposing an internal or private type.
a

Anthony Pages

05/05/2021, 8:30 AM
yes yes, none of them are private or internal, everything is public here
l

louiscad

05/05/2021, 8:32 AM
Then, that's it, right?
a

Anthony Pages

05/05/2021, 8:41 AM
Hmmm not really. In kotlin I can do what I wanted. For example:
Copy code
// API project
public interface Foo

// libA project
public class Bar {
    fun doSomething(foo: Foo)
}

// libB project
import API

public class FooImpl: Foo { }

// android app
import libA
import libB

var foo = FooImpl()
var bar = Bar()
bar.doSomething(foo) // <----- Everything is fine here
but in iOS I can't:
Copy code
// ios app
import libA
import libB

var foo = FooImpl()
var bar = Bar()
bar.doSomething(foo) // <----- Error here : FooImpl is of type APIFoo but here LibAAPIFoo is excpected
because I have the folowing headers :
Copy code
/// API.h
@protocol APIFoo
Copy code
// libA.h
@protocol LibAAPIFoo

@interface Bar
- (void)injectFoo:(LibAAPIFoo)foo
@end;
l

louiscad

05/05/2021, 8:49 AM
So much "foo", I have a really hard time wrapping my head around to be honest.
a

Anthony Pages

05/05/2021, 8:51 AM
Haha I understand, maybe I can host it on a github, it will probably be clearer.
l

louiscad

05/05/2021, 8:52 AM
I don't think I'll take the time, but I can tell you one thing: Swift protocols are not a 100% translation of interfaces in Kotlin (or Java), so that can explain some differences in the semantics. You might be able to work that around by using an abtract class with all abstract functions/properties.
a

Anthony Pages

05/05/2021, 8:56 AM
Ok, thank you for your time
8 Views