Bradleycorn
08/15/2024, 12:34 PMDuplicate JVM class name 'com/my/org/network/config/NetworkConfigKt' generated from: NetworkConfigKt, NetworkConfigKtAnyone seen this before? There is actually a general KMP issue filed a long time ago on you track describing the same issue. So I guess maybe this behavior is expected (see what I did there? 😉), but like I said, when I build my kmp repo on it's own I don't get this error at all, so I'm not sure what the difference is.
Bradleycorn
08/15/2024, 12:36 PMkpgalligan
08/15/2024, 1:00 PMproject
type vs a binary. Perhaps in a library, the compiler will merge the two and "erase" the expect
one as a distinct build artifact, but it can't (or won't) when used as a project
dependency. To avoid changing anything on the consuming side, you'd want to rename the expect
file, and leave the actual
. If you don't care, rename the actual
. I usually do NetworkConfigJvm.kt
or similar.kpgalligan
08/15/2024, 1:00 PMkpgalligan
08/15/2024, 1:00 PMkpgalligan
08/15/2024, 1:01 PMBradleycorn
08/15/2024, 1:06 PMBradleycorn
08/15/2024, 1:20 PMkpgalligan
08/15/2024, 2:59 PMkpgalligan
08/15/2024, 3:01 PMkpgalligan
08/15/2024, 3:02 PM... CocoaPods is in maintenance mode.
Bradleycorn
08/15/2024, 3:17 PMBradleycorn
08/15/2024, 4:29 PMaddGithubPackagesRepository()
) in them:
And since those same modules are pulled into my android/ios apps as source, I have to add the kmmbridge plugin to the android app as well, so it can find that extension method. Currently I'm using a project property that only exists in my kmp repo to control whether or not that method gets called:
if (project.property("BUILD_MODE") == "library") {
addGithubPackagesRepository()
}
That's good enough to get me up and running. But it feels wrong to have the kmmbridge plugin in my android app, even though it's not really being used there. In the long term, I'm going to look for a way to not have to do that.kpgalligan
08/15/2024, 7:05 PMThat's the main allure of gitportal to me at the moment.For GitPortal in unidirectional mode, that would be the only benefit in my mind. If the iOS devs aren't going to browse and debug Kotlin, publishing binaries is much easier to deal with.
kpgalligan
08/15/2024, 7:10 PMSETUP_GITHUB_PACKAGES_REPOSITORY
which KMMBridge would read and do the equivalent of addGithubPackagesRepository()
internally might work. Then if you're pulling in the KMP modules directly from the Android repo's root setup.gradle.kts
file, the KMP repo's gradle.properties
file would simply be ignored.kpgalligan
08/15/2024, 7:10 PMkpgalligan
08/15/2024, 7:12 PMBradleycorn
08/15/2024, 7:24 PMSomeRepo.fetchSomeData()
.. and the data is returned. It doesn't know or care where it comes from. And more importanly, the app can't call some network api method directly. With the gitportal setup, there's nothing to stop an unruly dev from getting an instance of the network object directly and start making api calls with it. It's not a huge deal in my case, because the same devs who are writing the app code are also the devs who are managing the kmp code as well and they have pretty detailed knowledge of all of it. But that was one of the nice things about using binaries. I could enforce that abstraction and "protect the developer from himself".kpgalligan
08/15/2024, 8:27 PMboth the ios and android app's used the umbrella module as the point of entry for the kmp provided api'sI also definitely use this pattern, which would make my unconsidered solution above "not great". Then again. While you'd need to include KMMBridge as
apply false
in the root build.gradle.kts
file, because the umbrella absolutely needs it applied regardless, you could avoid the extra declarations in the other modules with the above solution. I hope you didn't just type that out towards the end as I'm replying as I read...kpgalligan
08/15/2024, 8:33 PMTo me, it goes back to the conversation that the KMP code IS part of my app sourceAh. Conceptual nuance here. GitPortal bidirectional is designed such that you consider the KMP as part of your app source. GitPortal unidirectional simply mimics the way a published library works, but with source instead of binaries. Since the unidirectional flow explicitly prohibits (or is supposed to prohibit) KMP changes being committed from the apps' repos, it's conceptually a separate library. I'm thinking this is a near term post topic. I don't remember if the following concept made it into my published posts or not. Paraphrased something like the following:
Now that we have the unidirectional flow set up, you might find it frustrating and unnecessary that the KMP code is right there, yet you're not allowed to change it. I agree. It seems dumb. Well, it is. After writing early versions of the tool and using them, I found the whole concept weirdly formal. That feeling is more obvious because with a binary, you don't directly experience it. It serves to highlight just how bad a library flow can be for KMP and feature editing. That's why there's a bidirectional mode...
kpgalligan
08/15/2024, 8:37 PMIt's not a huge deal in my case, because the same devs who are writing the app code are also the devs who are managing the kmp code as well and they have pretty detailed knowledge of all of itI would say this supports the argument of "try it out". Kind of depends on how many devs and if that's likely to disrupt anybody's workflow, but I can summarize the real/conceptual differences and what "trying it" and "rolling it back" would mean.
kpgalligan
08/15/2024, 8:37 PMBradleycorn
08/16/2024, 12:14 PMBradleycorn
08/20/2024, 4:26 PMBradleycorn
08/20/2024, 4:32 PMKMP_BUILD_MODE=library
When I compile from source in the android and ios apps, I pass a different value ("android", or "ios"). On android, I just set the same property in it's gradle.properties file with a value of "android". On iOS I pass in the property via the Run Script build phase the builds the source:
-PKMP_BUILD_MODE=ios
My KMP repo was already setup using a convention plugin to apply common configuration logic to each of it's modules. I refactored and extended that a bit. Now I have 2 convention plugins, one for all of the modules, and another that is used only for the "umbrella" module. Those plugins read the KMP_BUILD_MODE property. When I'm not doing a library build, I can exclude KmmBridge and all of it's configuration entirely, so no need to include kmmbridge in my android project. When I'm doing an android build, I can exclude all of the ios targets/sourceSets, which allows me to pull in my umbrella module.
Not sure I'd call the solution "elegant", but it works, keeps things encapsulated in the right places, and is pretty easy to work with and reason about.kpgalligan
08/22/2024, 12:06 AM