Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outdated/Incomplete README iOS installation #132

Closed
erickvelasco11 opened this issue Sep 12, 2024 · 3 comments · Fixed by #134
Closed

Outdated/Incomplete README iOS installation #132

erickvelasco11 opened this issue Sep 12, 2024 · 3 comments · Fixed by #134

Comments

@erickvelasco11
Copy link

erickvelasco11 commented Sep 12, 2024

Hi shepeliev
Thanks for your big effort to bring this library. This had been very helpfully in the development of our application. I have installed the library in my KMP project, and for Android it works like a charm, but for iOS have been really imposible.

I have followed the instructions in the README (add cocoapods section, add the library like api, add Podfile) but his is not working. I made this in a new project without other libraries but this not works.

I have found many different errors and I investigate each of them, trying to fix it, but is a endless loop, where I get a new error each time.

This is one of the errors when I try to run the app from Android Studio.

    ld: warning: search path '/Users/erickvelasco/Projects/KotlinProject/build/ios/Debug-iphonesimulator/XCFrameworkIntermediates/WebRTC-SDK' not found
    ld: warning: search path '/Users/erickvelasco/Projects/KotlinProject/iosApp/../shared/build/xcode-frameworks/Debug/iphonesimulator17.4' not found
    ld: framework 'WebRTC' not found
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is another different error when I try to run from XCode 15.3 (Opening the xcworkspace after install pods, after gradlew generate)

    error: Following dependencies exported in the podDebugFramework binary are not specified as API-dependencies of a corresponding source set:
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':composeApp:linkPodDebugFrameworkIosSimulatorArm64'.
    > Following dependencies exported in the podDebugFramework binary are not specified as API-dependencies of a corresponding source set:
      
    Files: [/Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-iossimulatorarm64/1.8.0/75aa968cd3c210038f6dc433a39d40e1ae97b744/kotlinx-coroutines-core.klib]
    Files: [/Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-iossimulatorarm64/1.8.0/75aa968cd3c210038f6dc433a39d40e1ae97b744/kotlinx-coroutines-core.klib]
    Files: [/Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-iossimulatorarm64/0.23.1/52cfff5ee717bd4824115bb8609b13ed51be203e/atomicfu.klib, /Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-iossimulatorarm64/0.23.1/577e14084dac4dbadcaf86db01f359b4939f5d5a/atomicfu-cinterop-interop.klib]
    Files: [/Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-iossimulatorarm64/0.23.1/52cfff5ee717bd4824115bb8609b13ed51be203e/atomicfu.klib, /Users/erickvelasco/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-iossimulatorarm64/0.23.1/577e14084dac4dbadcaf86db01f359b4939f5d5a/atomicfu-cinterop-interop.klib]
    
    Please add them in the API-dependencies and rerun the build.

I don't know why build the iOS app is not possible, but I think I'm miss something. I wanna share my build.gradle.kts and my podfile, maybe can give me some light about what I'm missing.

    import org.jetbrains.compose.desktop.application.dsl.TargetFormat
    import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
    import org.jetbrains.kotlin.gradle.dsl.JvmTarget
    import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
    import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
    import org.jetbrains.kotlin.konan.target.KonanTarget
    
    plugins {
        kotlin("multiplatform")
        id("com.android.application")
        kotlin("native.cocoapods")
    
        alias(libs.plugins.jetbrainsCompose)
        alias(libs.plugins.compose.compiler)
    }
    
    kotlin {
        //configureKotlinCompilerArgs()
    
        cocoapods {
            version = "1.0.0"
            summary = "Shared module"
            homepage = "not published"
            ios.deploymentTarget = "13.0"
    
            pod("WebRTC-SDK") {
                version = libs.versions.webrtc.ios.sdk.get()
                moduleName = "WebRTC"
                packageName = "WebRTC"
            }
    
            podfile = project.file("../iosApp/Podfile")
    
            framework {
                baseName = "ComposeApp"
            }
    
            xcodeConfigurationToNativeBuildType["CUSTOM_DEBUG"] = NativeBuildType.DEBUG
            xcodeConfigurationToNativeBuildType["CUSTOM_RELEASE"] = NativeBuildType.RELEASE
        }
    
        androidTarget {
            @OptIn(ExperimentalKotlinGradlePluginApi::class)
            compilerOptions {
                jvmTarget.set(JvmTarget.JVM_17)
            }
        }
        
        listOf(
            iosX64 { configureWebRtcCinterops() },
            iosArm64 { configureWebRtcCinterops() },
            iosSimulatorArm64 { configureWebRtcCinterops() }
        ).forEach { iosTarget ->
            iosTarget.binaries.framework {
                baseName = "ComposeApp"
                isStatic = true
                freeCompilerArgs += listOf("-Xbinary=bundleId=com.sweetmesoft.connit")
            }
        }
        
        sourceSets {
            
            androidMain.dependencies {
                implementation(compose.preview)
                implementation(libs.androidx.activity.compose)
            }
            commonMain.dependencies {
                implementation(compose.runtime)
                implementation(compose.foundation)
                implementation(compose.material)
                implementation(compose.ui)
                implementation(compose.components.resources)
                implementation(compose.components.uiToolingPreview)
                implementation(libs.androidx.lifecycle.viewmodel)
                implementation(libs.androidx.lifecycle.runtime.compose)
                api("com.shepeliev:webrtc-kmp:0.125.2")
            }
        }
    }
    
    android {
        namespace = "com.sweetmesoft.connit"
        compileSdk = libs.versions.android.compileSdk.get().toInt()
    
        sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
        sourceSets["main"].res.srcDirs("src/androidMain/res")
        sourceSets["main"].resources.srcDirs("src/commonMain/resources")
    
        defaultConfig {
            applicationId = "com.sweetmesoft.connit"
            minSdk = libs.versions.android.minSdk.get().toInt()
            targetSdk = libs.versions.android.targetSdk.get().toInt()
            versionCode = 1
            versionName = "1.0"
        }
        packaging {
            resources {
                excludes += "/META-INF/{AL2.0,LGPL2.1}"
            }
        }
        buildTypes {
            getByName("release") {
                isMinifyEnabled = false
            }
        }
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_17
            targetCompatibility = JavaVersion.VERSION_17
        }
        buildFeatures {
            compose = true
        }
        dependencies {
            debugImplementation(compose.uiTooling)
        }
    }
    
    
    fun KotlinNativeTarget.configureWebRtcCinterops() {
        val webRtcFrameworkPath = file("$buildDir/cocoapods/synthetic/IOS/Pods/WebRTC-SDK")
            .resolveArchPath(konanTarget, "WebRTC")
        compilations.getByName("main") {
            cinterops.getByName("WebRTC") {
                compilerOpts("-framework", "WebRTC", "-F$webRtcFrameworkPath")
            }
        }
    
        binaries {
            getTest("DEBUG").apply {
                linkerOpts(
                    "-framework",
                    "WebRTC",
                    "-F$webRtcFrameworkPath",
                    "-rpath",
                    "$webRtcFrameworkPath",
                    "-ObjC"
                )
            }
        }
    }
    
    fun File.resolveArchPath(target: KonanTarget, framework: String): File? {
        val archPaths = resolve("$framework.xcframework")
            .listFiles { _, name -> target.matches(name) }
            ?: return null
    
        check(archPaths.size == 1) { "Resolving framework '$framework' arch path failed: $archPaths" }
    
        return archPaths.first()
    }
    
    private fun KonanTarget.matches(dir: String): Boolean {
        return when (this) {
            KonanTarget.IOS_SIMULATOR_ARM64,
            KonanTarget.IOS_X64 -> dir.startsWith("ios") && dir.endsWith("simulator")
    
            KonanTarget.IOS_ARM64 -> dir.startsWith("ios-arm64") && !dir.contains("x86")
    
            else -> error("Unsupported target $name")
        }
    }

And this is my Podfile

    # Uncomment the next line to define a global platform for your project
    platform :ios, '13.0'
    
    target 'iosApp' do
      # Comment the next line if you don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for iosApp
      pod 'composeApp', :path => '../composeApp'
    end

I really appreciate your help or if someone has this same error, maybe we can document how can fix it.

Thanks everyone

@shepeliev
Copy link
Owner

Hi @erickvelasco11,

Readme for iOS is really little bit outdated, however it still should work. I'm going to improve it soon.

For now, please try this sample project that I've just created from AS wizard. It can be built without problems and there is example of calling WebRTC KMP from Koltin at iOS target and from Swift.

See files:

iOSApp.swift
Platform.ios.kt

MyApplication.zip

@erickvelasco11
Copy link
Author

Hi @shepeliev

Thanks for your support. With the demo you sent I make my project work. I've followed a step by step through all the configurations and files and it works.

If you want, I can make a pull request of README with iOS configuration updated. Let me know if it's fine for you.

Thanks again

@shepeliev
Copy link
Owner

@erickvelasco11, I'm glad it helped. And PRs are appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants