Tiến Đức Nguyễn
Tiến Đức Nguyễn

Reputation: 133

Can not build ios app into device because "embedded framework 'SharedCode.framework' was built for iOS Simulator."

I use Kotlin Native (multiplatform) and I have create a TestKotinNative app, but only work when run on simulator. When I run on my device (iphone 7, 13.4.1), xcode show error "TestKotlinNative.xcodeproj Building for iOS, but the linked and embedded framework 'SharedCode.framework' was built for iOS Simulator." My Xcode version: 11.4.1 Please help me! Thank

This is my build.gradle.kts (same with https://play.kotlinlang.org/hands-on/Targeting%20iOS%20and%20Android%20with%20Kotlin%20Multiplatform/06_SettingUpKotlinFramework)

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    kotlin("multiplatform")
}

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "SharedCode"
            }
        }
    }

    jvm("android")

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }

}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    /// selecting the right configuration for the iOS
    /// framework depending on the environment
    /// variables set by Xcode build
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets
        .getByName<KotlinNativeTarget>("ios")
        .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)

    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\n"
                + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
                + "cd '${rootProject.rootDir}'\n"
                + "./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}

tasks.getByName("build").dependsOn(packForXcode)

enter image description here

Upvotes: 4

Views: 1975

Answers (2)

Dimitris.Dimitriadis
Dimitris.Dimitriadis

Reputation: 21

A dirty way to keep using the new versions of xCode with Kotlin multiplatform framework is... Before change the platform (simulator and iphone) to run your project just go in frameworks location and delete the framework file. XCode will re-built your framework and app will deploy on your choosen platform

Upvotes: 2

Artyom Degtyarev
Artyom Degtyarev

Reputation: 2888

In your script, you declare the iOSTarget variable to be always set for iosX64 target, which is a simulator. In the hands-on example, the idea was to choose targets depending on the Xcode build settings. but in your code, this part is commented leaving the only simulator set by default. Try fixing it to be exactly as in the hands-on final version(see it here)

Upvotes: 0

Related Questions