https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
j

jamieadkins95

03/04/2021, 4:25 PM
Hey everyone, we are looking to convert our internal sdks into multiplatform sdks so that the iOS team can use them as well. Our existing sdks are modularised by feature and by layer, so we have something that looks like this:
Copy code
content-data           football-data
     |                       |
     v                       v
content-domain         football-domain
     \                       /
       \                   /
         \               /
           v           v
              common
(In reality we have 25+ sdks that sorta follow this dependency structure, and 15+ apps that use them to varying levels) When converted to KMM modules this works fine on Android. We declare the dependency on content-data and gradle will see the transitive dependency on content-domain and download that too. However on iOS when they bring the content-data framework in, ‘duplicate’ classes get prefixed with the library name. For example content-domain defines a
DispatcherProvider
interface that content-data provides an implementation of called
DispatcherProviderImpl
. In the iOS frameworks,
DispatcherProvider
gets generated as 2 different protocols:
Copy code
__attribute__((swift_name("DispatcherProvider")))
@protocol Content_domain_kmmDispatcherProvider
@required
- (Content_domain_kmmKotlinx_coroutines_coreCoroutineDispatcher *)computation __attribute__((swift_name("computation()")));
- (Content_domain_kmmKotlinx_coroutines_coreCoroutineDispatcher *)io __attribute__((swift_name("io()")));
- (Content_domain_kmmKotlinx_coroutines_coreCoroutineDispatcher *)ui __attribute__((swift_name("ui()")));
@end;
and
Copy code
__attribute__((swift_name("Content_domain_kmmDispatcherProvider")))
@protocol Content_data_kmmContent_domain_kmmDispatcherProvider
@required
- (Content_data_kmmKotlinx_coroutines_coreCoroutineDispatcher *)computation __attribute__((swift_name("computation()")));
- (Content_data_kmmKotlinx_coroutines_coreCoroutineDispatcher *)io __attribute__((swift_name("io()")));
- (Content_data_kmmKotlinx_coroutines_coreCoroutineDispatcher *)ui __attribute__((swift_name("ui()")));
@end;
Anywhere in content-domain that asks for a DispatcherProvider can’t take the implementation provided by content-data because it now implements a different interface/protocol This issue is also described in this post under subtitle ‘How well do the modules talk to each other?’ https://dev.to/touchlab/multiple-kotlin-frameworks-in-an-application-34e9 Q: Is the multiple sdk setup I’ve described possible with KMM? Is there any way around this, maybe by combining all the source sets into one before generating the iOS framework?
r

russhwolf

03/04/2021, 5:15 PM
Yes, if you have just a single framework instead of a separate one per module, then you'll be able to more freely interact between them
a

Anders

03/04/2021, 8:24 PM
One umbrella module — that exports everything you need into a monolithic ObjC framework product — is indeed the only working configuration today. Having binary libraries to depend on one another isn't supported by today's K/N. So for example, offering a modularized setup like Firebase iOS SDKs as binary frameworks is impossible today. Also because of this, there is also no interoperability between copies of the same type across K/N framework products, aside from primitives supported by Objective-C interoperability. So, e.g., each linked copy of Kotlin Coroutines can only work with itself. also touched on this today when replying to a Stack Overflow question 🙂 The relevant issue: https://youtrack.jetbrains.com/issue/KT-42250
j

jamieadkins95

03/05/2021, 10:05 AM
Thanks both! Have spoke to some of the iOS guys this morning, we think we’ll end up with 1 bespoke and empty kmm module per app, that just brings in all the KMM dependencies that that app needs
👍 1
4 Views