Kotlinx.serialization: serializer issue in building ios project

Created on 1 Mar 2019  Â·  19Comments  Â·  Source: Kotlin/kotlinx.serialization

Hi, I know similar issue has been discussed here many times, I have gone through all of them for example
https://github.com/Kotlin/kotlinx.serialization/issues/264
https://github.com/Kotlin/kotlinx.serialization/issues/231
and others, but for some reason I am not able to solve it.

I also can run my project ok for android, but when I build it for iOS, I get following error

src/commonMain/kotlin/data/Models/User.kt:3:16: error: unresolved reference: serialization
import kotlinx.serialization.SerialId
               ^
src/commonMain/kotlin/data/Models/User.kt:4:16: error: unresolved reference: serialization
import kotlinx.serialization.SerialName
               ^
src/commonMain/kotlin/data/Models/User.kt:5:16: error: unresolved reference: serialization
import kotlinx.serialization.Serializable
               ^
src/commonMain/kotlin/data/Models/User.kt:7:2: error: cannot access 'Serializable': it is internal in 'kotlin.io'
@Serializable
 ^

My code structure is as follow

Project
-app
-native
-shared
--androidMain
--commonMain
--iOSMain

My App: build.gradle looks like


apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "au.com.rhinocrm"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {
        exclude 'META-INF/common.kotlin_module'
        exclude 'META-INF/ktor-http.kotlin_module'
        exclude 'META-INF/kotlinx-io.kotlin_module'
        exclude 'META-INF/atomicfu.kotlin_module'
        exclude 'META-INF/ktor-utils.kotlin_module'
        exclude 'META-INF/kotlinx-coroutines-io.kotlin_module'
        exclude 'META-INF/ktor-client-json.kotlin_module'
        exclude 'META-INF/ktor-client-logging.kotlin_module'
        exclude 'META-INF/ktor-client-core.kotlin_module'
    }

    dataBinding {
        enabled = true
    }

    tasks.lint.enabled = false

}

dependencies {
    implementation project(':SharedLibrary')

    implementation "com.github.bumptech.glide:glide:$glide_version"
    kapt "com.github.bumptech.glide:compiler:$glide_version"

    implementation 'com.android.support:multidex:1.0.3'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
    implementation "io.ktor:ktor-client-okhttp:$ktor_version"
    implementation "io.ktor:ktor-client-json-jvm:$ktor_version"

    implementation "com.android.support:recyclerview-v7:$support_library_version"
    implementation "com.android.support:design:$support_library_version"
    implementation "com.android.support:cardview-v7:$support_library_version"
    implementation "com.android.support:appcompat-v7:$support_library_version"
    implementation "com.android.support:support-v4:$support_library_version"


    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
    implementation 'androidx.core:core-ktx:1.1.0-alpha04'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.2-alpha01'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.2-alpha01'


    implementation "android.arch.lifecycle:extensions:$lifecycle_libraries"
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_libraries"
    kapt "android.arch.lifecycle:compiler:$lifecycle_libraries"

    implementation 'com.google.android.gms:play-services-auth:16.0.1'

    // AWS Mobile SDK for Android
    implementation('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
    implementation('com.amazonaws:aws-android-sdk-auth-userpools:2.6.+@aar') { transitive = true }
    implementation('com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar') { transitive = true }

    // Google SignIn
    implementation ('com.amazonaws:aws-android-sdk-auth-google:2.6.+@aar') { transitive = true }

    //Facebook SignIn
    implementation ('com.amazonaws:aws-android-sdk-auth-facebook:2.6.+@aar') { transitive = true }

    // Dependency Injection
    implementation "org.koin:koin-android:0.9.1"
    implementation 'org.koin:koin-androidx-viewmodel:1.0.2'

}

and my shared folder build.gradle is, I have tried remove this plugins, tried few other things from other online resources but always fail on same thing.. I have tried adding and removing
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

in iOS part but nothing has any effect, have tried invalidating caching, removing .idea and build folders.
tried different version combinations

plugins {
    id 'kotlin-multiplatform'
    id 'kotlinx-serialization'
}

kotlin {
    targets {
        fromPreset(presets.jvm, 'android')

        // Change to `presets.iosArm64` to deploy the app to iPhone
        fromPreset(presets.iosX64, 'ios') {
            compilations.main.outputKinds('FRAMEWORK')
        }
    }

    sourceSets {
        commonMain.dependencies {
            implementation 'org.jetbrains.kotlin:kotlin-stdlib'

            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-runtime:$serialization_version"

            implementation "io.ktor:ktor-client-core:$ktor_version"
            implementation "io.ktor:ktor-client-json:$ktor_version"
            implementation "io.ktor:ktor-client-logging:$ktor_version"
        }

        androidMain.dependencies {
            implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"


            implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
            implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
            implementation "io.ktor:ktor-client-logging-jvm:$ktor_version"
        }

        iosMain.dependencies {

            implementation "io.ktor:ktor-client-ios:$ktor_version"
            implementation "io.ktor:ktor-client-core-ios:1.0.1"
            implementation "io.ktor:ktor-client-json-ios:0.9.5"
        }


    }
}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
    compileClasspath
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'

    inputs.property "mode", mode
    dependsOn kotlin.targets.ios.compilations.main.linkTaskName("FRAMEWORK", mode)

    from { kotlin.targets.ios.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}

tasks.build.dependsOn packForXCode

inside setting.gralde file
also tried commenting and uncommenting Gradle_metada part..

pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == "kotlin-multiplatform") {
                useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
            }

            if (requested.id.id == "kotlinx-serialization") {
                useModule("org.jetbrains.kotlin:kotlin-serialization:${requested.version}")
            }
        }
    }
}

//enableFeaturePreview("GRADLE_METADATA")
include ':app', ':SharedLibrary'

although my understanding of entire Gradle build process is not expert level but I have tried all solutions available online, anything that made sense but still same error for iOS only.

question

Most helpful comment

Hi!

First of all, you need to uncomment the line enableFeaturePreview("GRADLE_METADATA") – it helps Gradle search for Native artifacts.

Secondly, in commonMain.dependencies you need to have implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version" , in iosMain.dependencies you need to have implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version", in android.main – implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

Hope this helps.

All 19 comments

Hi!

First of all, you need to uncomment the line enableFeaturePreview("GRADLE_METADATA") – it helps Gradle search for Native artifacts.

Secondly, in commonMain.dependencies you need to have implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version" , in iosMain.dependencies you need to have implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version", in android.main – implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

Hope this helps.

Hi, thanks for your reply, did not see it.
I had already tried what you suggested and tried again but still no luck. Although, there is another warning which could be causing the issue.

The Kotlin source set iosMain was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets

I did visit the page and also tried adding

dependsOn commonMain in iOS part but still nothing, still can't compile for iOS.

Says
Execution failed for task ':SharedLibrary:compileKotlinIOS'.
and does not compile anything, its not only serializer, even after removing data cases that had serializer it still can't compile for ktor-client or any other library.

now my share library build.gradle looks like this

apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
                              ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'iOS') {
            compilations.main.outputKinds('FRAMEWORK')
        }

        fromPreset(presets.jvm, 'android')
    }

    sourceSets {
        commonMain.dependencies {
            implementation 'org.jetbrains.kotlin:kotlin-stdlib'

            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"

            implementation "io.ktor:ktor-client-core:$ktor_version"
            implementation "io.ktor:ktor-client-json:$ktor_version"
            implementation "io.ktor:ktor-client-logging:$ktor_version"
        }

        androidMain.dependencies {
            implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

            implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
            implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
            implementation "io.ktor:ktor-client-logging-jvm:$ktor_version"
        }

        iosMain.dependencies {

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-ios:$ktor_version"
                implementation "io.ktor:ktor-client-json-ios:$ktor_version"
            }
    }
}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
    compileClasspath
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'

    inputs.property "mode", mode
    dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode)

    from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}

tasks.build.dependsOn packForXCode

When I added dependsOn commonMain it looked like

iosMain {
dependsOn commonMain
dependencies {

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-ios:$ktor_version"
                implementation "io.ktor:ktor-client-json-ios:$ktor_version"
            }
}

@ForteInformationSolutions Im having the exact same problem as you, and also tried and tried without any luck. Please post if you manage to resolve this (I will too of course).

@sandwwraith Building the Xcode frameworks for iOS works fine when writing pure Kotlin code. However, the problem myself and many others face is once we add external dependencies such as ktor or kotlinx.serialization/coroutines, the iOS framework build fails without any helpful stack trace. It seems like its not able to find the dependencies

After adding the dependencies in such as fashion

sourceSets {
        commonMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'

                implementation "io.ktor:ktor-client:1.1.3"
                implementation "io.ktor:ktor-client-json:1.1.3"

                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:0.10.0"
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
            }
        }
        androidMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib'

                implementation "io.ktor:ktor-client-core-jvm:1.1.3"
                implementation "io.ktor:ktor-client-json-jvm:1.1.3"

                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.10.0"

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"

                implementation 'io.ktor:ktor-client-okhttp:1.1.3'
                implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
            }
        }
        iosMain {
            dependencies {
                implementation "io.ktor:ktor-client-ios:1.1.3"

                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.1.1"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.10.0"
            }
        }
    }

We can build the iOS frameworks using as shown in the official tutorial by calling
./gradlew :SharedCode:packForXCode

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.iOS.binaries.getFramework("SharedCode", mode)

    inputs.property "mode", mode
    dependsOn framework.linkTask

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}
tasks.build.dependsOn packForXCode

However, that causes it to fail because it can't find any of the dependencies

> Configure project :SharedCode
Kotlin Multiplatform Projects are an experimental feature.

The Kotlin source set iosMain was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets

> Task :SharedCode:linkSharedCodeDebugFrameworkIOS FAILED
SharedCode/src/commonMain/kotlin/Facade.kt:10:8: error: unresolved reference: io
import io.ktor.client.HttpClient
       ^
SharedCode/src/commonMain/kotlin/common.kt:3:8: error: unresolved reference: io
import io.ktor.client.HttpClient
       ^
SharedCode/src/commonMain/kotlin/common.kt:4:8: error: unresolved reference: io
import io.ktor.client.request.get
       ^
SharedCode/src/commonMain/kotlin/common.kt:5:8: error: unresolved reference: io
import io.ktor.client.request.url
       ^
SharedCode/src/commonMain/kotlin/common.kt:6:16: error: unresolved reference: coroutines
import kotlinx.coroutines.*
               ^
SharedCode/src/commonMain/kotlin/common.kt:7:8: error: unresolved reference: io
import io.ktor.http.*
       ^
SharedCode/src/commonMain/kotlin/common.kt:23:44: error: expected property 'ApplicationDispatcher' has no actual declaration in module 
The following declaration is incompatible because return type is different:
    internal actual val ApplicationDispatcher: [ERROR : CoroutineDispatcher]

internal expect val ApplicationDispatcher: CoroutineDispatcher
                                           ^
SharedCode/src/commonMain/kotlin/common.kt:23:44: error: unresolved reference: CoroutineDispatcher
internal expect val ApplicationDispatcher: CoroutineDispatcher
                                           ^
SharedCode/src/commonMain/kotlin/common.kt:25:22: error: unresolved reference: HttpClient
private val client = HttpClient()
                     ^
SharedCode/src/commonMain/kotlin/common.kt:27:15: error: unresolved reference: Url
var address = Url("https://tools.ietf.org/rfc/rfc1866.txt")
              ^
SharedCode/src/commonMain/kotlin/common.kt:30:3: error: unresolved reference: GlobalScope
  GlobalScope.apply {
  ^
SharedCode/src/commonMain/kotlin/common.kt:31:5: error: unresolved reference: launch
    launch(ApplicationDispatcher) {
    ^
SharedCode/src/commonMain/kotlin/common.kt:33:9: error: unresolved reference: url
        url(address.toString())
        ^
SharedCode/src/iosMain/kotlin/actual.kt:3:16: error: unresolved reference: coroutines
import kotlinx.coroutines.CoroutineDispatcher
               ^
SharedCode/src/iosMain/kotlin/actual.kt:4:16: error: unresolved reference: coroutines
import kotlinx.coroutines.Runnable
               ^
SharedCode/src/iosMain/kotlin/actual.kt:21:44: error: actual property 'ApplicationDispatcher' has no corresponding expected declaration
The following declaration is incompatible because return type is different:
    internal expect val ApplicationDispatcher: [ERROR : CoroutineDispatcher]

internal actual val ApplicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
                                           ^
SharedCode/src/iosMain/kotlin/actual.kt:21:44: error: unresolved reference: CoroutineDispatcher
internal actual val ApplicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
                                           ^
SharedCode/src/iosMain/kotlin/actual.kt:23:81: error: unresolved reference: CoroutineDispatcher
internal class NsQueueDispatcher(private val dispatchQueue: dispatch_queue_t) : CoroutineDispatcher() {
                                                                                ^
SharedCode/src/iosMain/kotlin/actual.kt:24:3: error: 'dispatch' overrides nothing
  override fun dispatch(context: CoroutineContext, block: Runnable) {
  ^
SharedCode/src/iosMain/kotlin/actual.kt:24:59: error: unresolved reference: Runnable
  override fun dispatch(context: CoroutineContext, block: Runnable) {
                                                          ^

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':SharedCode:linkSharedCodeDebugFrameworkIOS'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 4s
1 actionable task: 1 executed

Probably the trick is in this warning message on top:

The Kotlin source set iosMain was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets

@sandwwraith Thanks for the reply, but Ive tried it before without any change.

However, I have managed to solve the problem, seemingly a bit randomly. MPP Kotlin seems to be very fragile between versioning and exact dependency names (which seems to be constantly changing). For my I got it working by setting the following versions in my gradle.properties:

kotlin_version=1.3.21
coroutines_version=1.1.1
ktor_version=1.1.3
serialization_version=0.10.0

kotlin.incremental.multiplatform = true

Top level build.gradle:

buildscript {
    repositories {
        google()
        jcenter()
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
        maven { url "https://kotlin.bintray.com/kotlinx" }
        maven { url 'https://dl.bintray.com/jetbrains/kotlin-native-dependencies' }
        maven { url 'https://plugins.gradle.org/m2/' }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }

        maven { url "https://kotlin.bintray.com/ktor" }
        maven { url "https://kotlin.bintray.com/kotlinx" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

App level gradle SharedCode/build.gradle:

plugins {
    id 'kotlin-multiplatform'
    id 'kotlinx-serialization'
}

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
                              ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'iOS') {
            binaries {
                framework('SharedCode')
            }
        }
        fromPreset(presets.jvm, 'android')
    }

    sourceSets {
        commonMain {
            dependencies {
                api 'org.jetbrains.kotlin:kotlin-stdlib-common'
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"

                implementation "io.ktor:ktor-client-core:$ktor_version"
                implementation "io.ktor:ktor-client-json:$ktor_version"
            }
        }
        androidMain {
            dependencies {
                api 'org.jetbrains.kotlin:kotlin-stdlib'
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"

                implementation "io.ktor:ktor-client-android:$ktor_version"
                implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
                implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
            }
        }
        iOSMain {
            dependsOn commonMain
            dependencies {
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                implementation "io.ktor:ktor-client-ios:$ktor_version"
            }
        }
    }
}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
    compileClasspath
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.iOS.binaries.getFramework("SharedCode", mode)

    inputs.property "mode", mode
    dependsOn framework.linkTask

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}

However, after completing the iOS framework build, and importing it in Xcode, any call to my functions cause a null pointer error in Xcode. Maybe someone is able to figure out why with this help..

I have the same issue when I try to compile my native lib for iOS (for Android it works like a charm).
My build.gradle file inside the native lib:

buildscript {
    ext.build_gradle_version = '3.3.2'
    ext.kotlin_version = '1.3.21'
    ext.compile_sdk_version = 28
    ext.min_sdk_version = 21
    ext.target_sdk_version = 28
    ext.coroutines_version = '1.1.1'
    ext.ktor_version = '1.1.3'
    ext.serialization_version = '0.10.0'

    repositories {
        google()
        jcenter()
        maven { url "https://kotlin.bintray.com/kotlinx" }
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$build_gradle_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://kotlin.bintray.com/kotlinx" }
    }
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'

android {
    compileSdkVersion compile_sdk_version
    defaultConfig {
        minSdkVersion min_sdk_version
        targetSdkVersion target_sdk_version
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        exclude 'META-INF/*.kotlin_module'
        exclude 'META-INF/ktor-http.kotlin_module'
    }
}

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos")    \
                                 ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'ios') {
            binaries {
                framework('Kotlin_Native')
            }
        }

        fromPreset(presets.android, 'androidLib')
    }

    sourceSets {
        commonMain.dependencies {
            api 'org.jetbrains.kotlin:kotlin-stdlib-common'
            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
            implementation "io.ktor:ktor-client-core:$ktor_version"
            implementation "io.ktor:ktor-client-json:$ktor_version"
        }
        iosMain {
            dependsOn commonMain
            dependencies {
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-native:$ktor_version"
                implementation "io.ktor:ktor-client-json-native:$ktor_version"
            }
        }
        androidLibMain.dependencies {
            api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
            api "io.ktor:ktor-client-android:$ktor_version"
            api "io.ktor:ktor-client-json-jvm:$ktor_version"
            api "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
        }
    }
}

// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
    compileClasspath
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.ios.binaries.getFramework("Kotlin_Native", mode)

    inputs.property "mode", mode
    dependsOn framework.linkTask

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}
tasks.build.dependsOn packForXCode

But there are unresolved references to ktor packages and to the serialization package:

Task :linkKotlin_NativeDebugFrameworkIos
src/commonMain/kotlin/common.kt:3:8: error: unresolved reference: io
import io.ktor.client.HttpClient
^
src/commonMain/kotlin/common.kt:9:16: error: unresolved reference: coroutines
import kotlinx.coroutines.GlobalScope
^

I don't know what else I can try.

I've done gradle setup exactly like above and still get nothing linked - no coroutines, no ktor, no serialization.

error: unresolved reference: coroutines import kotlinx.coroutines.CoroutineScope

etc.

Looking for ideas how to solve it.

All my issues were resolved after using Gradle 4.10.1 (and the kotlin versions as above).

So this is resolved? If you have any questions left, feel free to reopen.

A pity, cos this is not working yet.

I don't know how to help more than recommend to check all the compiler and libs versions, make sure that Gradle metadata is enabled and Gradle version is in a compatible range (4.10+), and take a look at the working example of setup here: https://github.com/Kotlin/kotlinx.serialization/tree/master/examples/example-multiplatform , here: https://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html or here: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html

Checked with gradle 4.10 and 5.4. Same problem but it seems to be related more to ktor than to serialisation.
So maybe we can close this one.

Hi, I am having a message saying.

The Kotlin source set iosMain was configured but not added to any Kotlin compilation. You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.

My gradle configuration is the same as RBIrkeland just without the other library, such as ktor and etc.
How to fix this warning message? Can I just ignore this message? Thanks

@avjiang You haven't set up ios target properly. I think you need

fromPreset(iOSTarget, 'iOS') {
            binaries {
                framework('SharedCode')
            }
        }

part.

Might be a silly question but I just found out you cant run Multiplatform on windows yet (for ios in project). Are you running on windows?

Hi, I know similar issue has been discussed here many times, I have gone through all of them for example

https://github.com/Kotlin/kotlinx.serialization/issues/264

https://github.com/Kotlin/kotlinx.serialization/issues/231

and others, but for some reason I am not able to solve it.

I also can run my project ok for android, but when I build it for iOS, I get following error


src/commonMain/kotlin/data/Models/User.kt:3:16: error: unresolved reference: serialization

import kotlinx.serialization.SerialId

               ^

src/commonMain/kotlin/data/Models/User.kt:4:16: error: unresolved reference: serialization

import kotlinx.serialization.SerialName

               ^

src/commonMain/kotlin/data/Models/User.kt:5:16: error: unresolved reference: serialization

import kotlinx.serialization.Serializable

               ^

src/commonMain/kotlin/data/Models/User.kt:7:2: error: cannot access 'Serializable': it is internal in 'kotlin.io'

@Serializable

 ^

My code structure is as follow

Project

-app

-native

-shared

--androidMain

--commonMain

--iOSMain

My App: build.gradle looks like




apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'



android {

    compileSdkVersion 28

    defaultConfig {

        applicationId "au.com.rhinocrm"

        minSdkVersion 23

        targetSdkVersion 28

        versionCode 1

        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        multiDexEnabled true

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

        }

    }



    packagingOptions {

        exclude 'META-INF/common.kotlin_module'

        exclude 'META-INF/ktor-http.kotlin_module'

        exclude 'META-INF/kotlinx-io.kotlin_module'

        exclude 'META-INF/atomicfu.kotlin_module'

        exclude 'META-INF/ktor-utils.kotlin_module'

        exclude 'META-INF/kotlinx-coroutines-io.kotlin_module'

        exclude 'META-INF/ktor-client-json.kotlin_module'

        exclude 'META-INF/ktor-client-logging.kotlin_module'

        exclude 'META-INF/ktor-client-core.kotlin_module'

    }



    dataBinding {

        enabled = true

    }



    tasks.lint.enabled = false



}



dependencies {

    implementation project(':SharedLibrary')



    implementation "com.github.bumptech.glide:glide:$glide_version"

    kapt "com.github.bumptech.glide:compiler:$glide_version"



    implementation 'com.android.support:multidex:1.0.3'

    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

    implementation "io.ktor:ktor-client-okhttp:$ktor_version"

    implementation "io.ktor:ktor-client-json-jvm:$ktor_version"



    implementation "com.android.support:recyclerview-v7:$support_library_version"

    implementation "com.android.support:design:$support_library_version"

    implementation "com.android.support:cardview-v7:$support_library_version"

    implementation "com.android.support:appcompat-v7:$support_library_version"

    implementation "com.android.support:support-v4:$support_library_version"





    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'

    implementation 'androidx.core:core-ktx:1.1.0-alpha04'

    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'androidx.test:runner:1.1.2-alpha01'

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.2-alpha01'





    implementation "android.arch.lifecycle:extensions:$lifecycle_libraries"

    implementation "android.arch.lifecycle:viewmodel:$lifecycle_libraries"

    kapt "android.arch.lifecycle:compiler:$lifecycle_libraries"



    implementation 'com.google.android.gms:play-services-auth:16.0.1'



    // AWS Mobile SDK for Android

    implementation('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }

    implementation('com.amazonaws:aws-android-sdk-auth-userpools:2.6.+@aar') { transitive = true }

    implementation('com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar') { transitive = true }



    // Google SignIn

    implementation ('com.amazonaws:aws-android-sdk-auth-google:2.6.+@aar') { transitive = true }



    //Facebook SignIn

    implementation ('com.amazonaws:aws-android-sdk-auth-facebook:2.6.+@aar') { transitive = true }



    // Dependency Injection

    implementation "org.koin:koin-android:0.9.1"

    implementation 'org.koin:koin-androidx-viewmodel:1.0.2'



}



and my shared folder build.gradle is, I have tried remove this plugins, tried few other things from other online resources but always fail on same thing.. I have tried adding and removing

implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

in iOS part but nothing has any effect, have tried invalidating caching, removing .idea and build folders.

tried different version combinations


plugins {

    id 'kotlin-multiplatform'

    id 'kotlinx-serialization'

}



kotlin {

    targets {

        fromPreset(presets.jvm, 'android')



        // Change to `presets.iosArm64` to deploy the app to iPhone

        fromPreset(presets.iosX64, 'ios') {

            compilations.main.outputKinds('FRAMEWORK')

        }

    }



    sourceSets {

        commonMain.dependencies {

            implementation 'org.jetbrains.kotlin:kotlin-stdlib'



            implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"

            implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-runtime:$serialization_version"



            implementation "io.ktor:ktor-client-core:$ktor_version"

            implementation "io.ktor:ktor-client-json:$ktor_version"

            implementation "io.ktor:ktor-client-logging:$ktor_version"

        }



        androidMain.dependencies {

            implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"





            implementation "io.ktor:ktor-client-core-jvm:$ktor_version"

            implementation "io.ktor:ktor-client-json-jvm:$ktor_version"

            implementation "io.ktor:ktor-client-logging-jvm:$ktor_version"

        }



        iosMain.dependencies {



            implementation "io.ktor:ktor-client-ios:$ktor_version"

            implementation "io.ktor:ktor-client-core-ios:1.0.1"

            implementation "io.ktor:ktor-client-json-ios:0.9.5"

        }





    }

}



// workaround for https://youtrack.jetbrains.com/issue/KT-27170

configurations {

    compileClasspath

}



task packForXCode(type: Sync) {

    final File frameworkDir = new File(buildDir, "xcode-frameworks")

    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'



    inputs.property "mode", mode

    dependsOn kotlin.targets.ios.compilations.main.linkTaskName("FRAMEWORK", mode)



    from { kotlin.targets.ios.compilations.main.getBinary("FRAMEWORK", mode).parentFile }

    into frameworkDir



    doLast {

        new File(frameworkDir, 'gradlew').with {

            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"

            setExecutable(true)

        }

    }

}



tasks.build.dependsOn packForXCode

inside setting.gralde file

also tried commenting and uncommenting Gradle_metada part..


pluginManagement {

    resolutionStrategy {

        eachPlugin {

            if (requested.id.id == "kotlin-multiplatform") {

                useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")

            }



            if (requested.id.id == "kotlinx-serialization") {

                useModule("org.jetbrains.kotlin:kotlin-serialization:${requested.version}")

            }

        }

    }

}



//enableFeaturePreview("GRADLE_METADATA")

include ':app', ':SharedLibrary'



although my understanding of entire Gradle build process is not expert level but I have tried all solutions available online, anything that made sense but still same error for iOS only.

Was this page helpful?
0 / 5 - 0 ratings