Hi again everyone! We’ve got KMMBridge setup using...
# touchlab-tools
b
Hi again everyone! We’ve got KMMBridge setup using cocoapods integration. Everything works ok, except that we’re seeing crashes when trying to view SwiftUI previews in our app in Xcode. This Stack Overflow post matches what we are seeing exactly: https://stackoverflow.com/questions/74016288/kmm-and-preview-for-swift-ui The accepted answer on that post is to NOT make the framework static (i.e. in the cocoapods configuration, set
isStatic = false
). I tried that, but that leads to additional (worse) problems. My framework cannot be found at all. Has anyone else run into this? Is there a solution/workaround?
k
I wouldn't think that's a kmmbridge problem. Using a dynamic framework should work fine so if that's failing I'd try to debug that. I've heard swiftui previews can't use static frameworks, and assuming that hasn't changed, you'll probably need to figure that out.
b
Thanks @kpgalligan. To debug it, I enabled the “local dev flow” for cocoapods, which caused more problems initially, then I went back through the kmmbridge docs to make sure I had everything setup right, which is when I was reminded:
Note: It is highly recommended that you run
linkPodDebugFrameworkIosX64
or
linkPodDebugFrameworkIosSimulatorArm64
, depending on your Mac architecture, before you run
pod install
, due to a minor issue with the Kotlin CocoaPods integration.
(That leads me to another question, but I’ll post that separately) Once I did that, it fixed those other problems and my previews are working in xcode too. I’m publishing a new version of my library with dynamic linking enabled right now and we’ll see if that takes care of it. 🤞
k
I’m publishing a new version of my library with dynamic linking enabled right now and we’ll see if that takes care of it.
This is kind of a special case as you're using previews in dev, but using KMMBridge to publish, which defaults to more of a "release" use case. The build defaults to RELEASE. that kind of thing. That should work fine, but I'm starting to think through maybe different KMMBridge config for dev vs release uses. In production, I generally prefer static frameworks. It's not a huge deal, but I could see wanting dynamic in dev, to get SwiftUI previews, and static in release builds.
> Note: It is highly recommended that you run
linkPodDebugFrameworkIosX64
or
linkPodDebugFrameworkIosSimulatorArm64
, depending on your Mac architecture, before you run
pod install
, due to a minor issue with the Kotlin CocoaPods integration.
That's a Kotlin thing, just FYI. Has nothing to do with KMMBridge.
b
but I’m starting to think through maybe different KMMBridge config for dev vs release uses
That would seem like a good idea. if I understand things correctly, a statically linked framework loads faster, which would be nice in a release build. So being able to do dynamically linked debug builds and statically linked release builds might be desireable.
k
a statically linked framework loads faster
Yes, generally. There's also the potential for a smaller overall binary size if the compiler can do some more DCE, although in practice, that is usually not significant, assuming you don't have tons of code that never gets called.
b
I see. So how would you do that? Maybe setup the cocoapods configuration with
isStatic = true
by default, and then in the podspec that is genertated for the local dev flow, set it up to pass in a property to the gradle task it runs to build the framework, and use that to set
isStatic = false
??
k
I'd probably just have a Gradle property that you pass in from the command line for production builds. It could check that in Gradle and set
isStatic=prodBuild
and
Copy code
kmmbridge {
  buildType.set(if(prodBuild){RELEASE}else{DEBUG})
}
b
ah
k
Then have a different CI script for "release" builds. You'd need to keep track of version numbers to know which is which, though.
b
so, kind of the inverse of what I suggested :D
k
Or, you could create a GH release for prod builds, maybe. Something like that.
I'd have to think through your plan. I'm doing like 3 things at once right now. CocoaPods is more flexible than SPM (and more brittle as a result), so you can do some custom things, but the gradle and CI approach seems like it would be simple to implement.
b
makes sense
Speaking of build types. I have a large block in my config to set the build type like so:
Copy code
xcodeConfigurationToNativeBuildType["TS-DEBUG"] = NativeBuildType.DEBUG
        xcodeConfigurationToNativeBuildType["DK-DEBUG"] = NativeBuildType.DEBUG
        xcodeConfigurationToNativeBuildType["KS-DEBUG"] = NativeBuildType.DEBUG
        xcodeConfigurationToNativeBuildType["OA-DEBUG"] = NativeBuildType.DEBUG
        xcodeConfigurationToNativeBuildType["BA-DEBUG"] = NativeBuildType.DEBUG
        xcodeConfigurationToNativeBuildType["TS-PROD"] = NativeBuildType.RELEASE
        xcodeConfigurationToNativeBuildType["DK-PROD"] = NativeBuildType.RELEASE
        xcodeConfigurationToNativeBuildType["KS-PROD"] = NativeBuildType.RELEASE
        xcodeConfigurationToNativeBuildType["OA-PROD"] = NativeBuildType.RELEASE
        xcodeConfigurationToNativeBuildType["BA-PROD"] = NativeBuildType.RELEASE
I tried and tried to figure out a way to do something effectively like:
Copy code
if (configuration.endsWith("DEBUG")) {
   NativeBuildType.DEBUG
} else {
   NativeBuildType.RELEASE
}
But I couldn’t come up anything. Any ideas?
k
So,
configuration
would be one of the values listed in the keys for
xcodeConfigurationToNativeBuildType
? Does the
xcodeConfigurationToNativeBuildType
map work? If so, I don't see why
if (configuration.endsWith("DEBUG"))
wouldn't be correct. Try logging out
configuration
.
b
yeah, using
xcodeConfigurationToNativeBuildType
does work, it’s just verbose, and everytime I add a new “product flavor”, I have to remember to add it to the library config as well. Assuming
configuration
has what I need, would I then just set the build type in the kmmbridge config block, like this?
Copy code
kmmbridge {
    buildType.set( if(configuration).... )
  
    ...
}
k
Oh, I'm not sure what
configuration
is. That's what I was asking. Where is that coming from? What's the value? I don't see why your if statement wouldn't work, so I'm trying to figure this out.
b
oh I see. 😄 I’m not sure where it comes from either.