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

Deniz Tumer

02/29/2024, 11:20 PM
Hey there everyone my team and I have been running into some weird issues recently where when building and running our KMP project on our MacMini CI machines for iOS and running into build inconsistencies. We noticed this morning that a new version of the GoogleUtilities cocoapod was released (7.13.0), but it is not a direct dependency of any current cocoapods versions we have. In our build logs though it is referencing a
GoogleUtilities-GoogleUtilities_Privacy
package which seems to have been only created and referenced in the new 7.13.0 release today (link). We're wondering if there's something going on under the hood that is automatically updating cocoapods or not locking cocoapods to specific versions for KMP. It seems like the workaround at the moment is that all our dependencies and transitive dependencies need to call out the exact version of the pod needed so that they don't automatically update during the build in the CI machine and is registered in the
shared.podspec
file.
Copy code
spec.dependency 'GoogleUtilities', '7.12.0'
Is this a known issue or does this need to be reported as a bug?
☝️ 1
c

Chris Pierick

03/01/2024, 3:16 AM
This is happening with all of the Google deps as they update their privacy manifest. The key here is that these transitive dependencies become a problem when a kmp cocoapod dependency is using the same Google dependency as what a SPM dep is using. And yeah it's super weird that when you are using
embedAndSignAppleFrameworkForXcode
there are interaction from the app's SPM within the shared kmp module. Here is a non broken working example in a simple project. Test Kotlin versions 1.9.20, 1.9.21, 1.9.22 shared/build.gradle.kts
Copy code
kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
    }
    listOf(
        iosArm64(),
        iosSimulatorArm64()
    )

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "15"

        framework {
            baseName = "shared"
            isStatic = true // true vs false does not affect anything differently.
        }
        podfile = project.file("../iosApp/Podfile")
        pod("FirebaseCore") {
            version = "10.18.0"
            extraOpts = listOf("-Xforeign-exception-mode", "objc-wrap")
        }
        pod("FirebaseAuth") {
            version = "10.18.0"
            extraOpts = listOf("-Xforeign-exception-mode", "objc-wrap")
        }
    }
....
}
iosApp/Podfile
Copy code
platform :ios, '15.0'

target 'iosApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  pod 'Stripe', '22.18.0'
  # Another random dep
  pod 'libPhoneNumber-iOS', :git => '<https://github.com/iziz/libPhoneNumber-iOS.git>', :tag => '1.1'

end
Here is a Broken example Now if you move Stripe out of iosApp/Podfile to be SPM dependency you'll get the following error
Copy code
Showing All Messages
/Users/cpierick/dev/src/Dependencies/shared/build/cocoapods/synthetic/ios/build/Release-iphonesimulator/PromisesObjC/Stripe_StripeUICore.bundle: No such file or directory (in target 'PromisesObjC-FBLPromises_Privacy' from project 'Pods')
How to temporarily fix the breakage You can now get past that error by adding the transitive dependencies at previous versions to shared/build.gradle.kts. Note you chase down a few before you'll get all of them
Copy code
summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "15"

        framework {
            baseName = "shared"
            isStatic = true
        }
        podfile = project.file("../iosApp/Podfile")
        pod("FirebaseCore") {
            version = "10.18.0"
            extraOpts = listOf("-Xforeign-exception-mode", "objc-wrap")
        }
        pod("FirebaseAuth") {
            version = "10.18.0"
            extraOpts = listOf("-Xforeign-exception-mode", "objc-wrap")
        }
        pod("PromisesObjC") {
            version = "2.3.1"
        }
        pod("GoogleUtilities") {
            version = "7.12.0"
        }
        pod("GTMSessionFetcher/Core") {
            version = "3.2.0"
        }
The Larger issue This would seem not too big of a deal except it keeps happen in realtime as Google releases these updates. That means our CI/CD randomly goes down at anytime until we can trace down the deep, put up a PR and merge it.
Here is the project in the broken state. I'm using xCode 15.0.1.
👍 1
I've went ahead and created a bug for this. KT-66278
👍 1
20 Views