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

dazza5000

10/27/2020, 10:02 PM
i am having an issue where platform api's are not being recognized
Copy code
plugins {
    id("com.android.library")
    id("org.jlleitschuh.gradle.ktlint")

    kotlin("multiplatform")
    kotlin("plugin.serialization")

    jacoco
}

kotlin {
    android()

    ios {
        binaries {
            framework {
                baseName = "shared"
                transitiveExport = true
            }
        }
    }

    js {
        browser {
            dceTask {
                /**
                 * Keep JS modules that will be used from calling code
                 * Otherwise the tree-shaking algorithm will cull them out
                 */
                keep("InstorePlugins-Plugins.com.fivestars.instore.battery.Battery")
                keep("InstorePlugins-Plugins.com.fivestars.instore.bluetoothserial.BluetoothSerial")
                keep("InstorePlugins-Plugins.com.fivestars.instore.device.Device")
                keep("InstorePlugins-Plugins.com.fivestars.instore.dgram.Dgram")
                keep("InstorePlugins-Plugins.com.fivestars.instore.display.Display")
                keep("InstorePlugins-Plugins.com.fivestars.instore.file.File")
                keep("InstorePlugins-Plugins.com.fivestars.instore.metadata.Metadata")
                keep("InstorePlugins-Plugins.com.fivestars.instore.kardreader.KardReader")
                keep("InstorePlugins-Plugins.com.fivestars.instore.ledcontroller.LedController")
                keep("InstorePlugins-Plugins.com.fivestars.instore.navigate.Navigate")
                keep("InstorePlugins-Plugins.com.fivestars.instore.networkaffinity.NetworkAffinity")
                keep("InstorePlugins-Plugins.com.fivestars.instore.networkalerts.NetworkAlerts")
                keep("InstorePlugins-Plugins.com.fivestars.instore.okpayplugin.OkPayPlugin")
                keep("InstorePlugins-Plugins.com.fivestars.instore.prop.Prop")
                keep("InstorePlugins-Plugins.com.fivestars.instore.remoteconfig.RemoteConfig")
                keep("InstorePlugins-Plugins.com.fivestars.instore.system.System")
                keep("InstorePlugins-Plugins.com.fivestars.instore.systemstats.SystemStats")
                keep("InstorePlugins-Plugins.com.fivestars.instore.thermal.Thermal")
            }

            testTask {
                useMocha()
            }
        }
    }

    val serializationVersion = "1.0.0"

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
                implementation("androidx.appcompat:appcompat:1.1.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9-native-mt")
                implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
            }
        }

        val jsMain by getting {
            dependencies {
                implementation(kotlin("stdlib-js"))
                implementation("org.jetbrains.kotlin:kotlin-stdlib-js:1.4.10")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
                implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.7.2")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.3.9-native-mt")
            }
        }

        val jsTest by getting {
            dependencies {
                implementation(kotlin("test-js"))
                implementation(npm("istanbul-instrumenter-loader", "3.0.1"))
                implementation(npm("karma-coverage-istanbul-reporter", "3.0.3"))
            }
        }

        val androidMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7-1.4-M3")
                implementation("com.google.firebase:firebase-analytics-ktx:17.5.0")
                implementation("com.google.firebase:firebase-crashlytics:17.1.1")
            }
        }

        val androidTest by getting {
            dependencies {
                implementation("junit:junit:4.13")
                implementation(kotlin("test-junit"))
                implementation("io.mockk:mockk:1.10.0")
                implementation("org.powermock:powermock-reflect:2.0.7")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.6")
            }
        }

        val iosMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9-native-mt")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
            }
        }
    }
}

android {
    compileSdkVersion(29)
    defaultConfig {
        minSdkVersion(23)
        targetSdkVersion(25)
    }
    sourceSets {
        getByName("main") {
            assets.srcDirs(file("src/androidMain/assets"))
            manifest.srcFile("src/androidMain/AndroidManifest.xml")
            java.srcDirs(file("src/androidMain/kotlin"))
            res.srcDirs(file("src/androidMain/res"))
        }
    }
}

ktlint {
    verbose.set(true)
    outputToConsole.set(true)
}

tasks.register("buildDebug") {
    dependsOn("buildDebugJs")
    dependsOn("buildDebugAar")
    dependsOn("sourcesJar")
}

tasks.register("buildDebugJs") {
    finalizedBy("copyJs")
    dependsOn("jsBrowserProductionWebpack")
    dependsOn("cleanupJs")
}

tasks.register("buildDebugAar") {
    mustRunAfter("copyJs")
    dependsOn("copyJs")
    dependsOn("bundleDebugAar")
}

tasks.register("copyJs") {
    doLast {
        copy {
            from("build/distributions")
            into("src/androidMain/assets/js")
        }
    }
}

tasks.register("cleanupJs") {
    doLast {
        delete(fileTree("src/androidMain/assets/js").matching {
            include("**/*.js", "**/*.map")
        })
    }
}

tasks.register<Jar>("sourcesJar") {
    classifier = "sources"
    this.from("src/androidMain/kotlin", "src/commonMain/kotlin")
}

tasks.getByName("clean").dependsOn("cleanupJs")

tasks.register<JacocoReport>("codeCoverageReport") {
    executionData(fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec"))
    sourceDirectories.setFrom(files(kotlin.sourceSets["androidMain"].kotlin.srcDirs))
    classDirectories.setFrom(files(kotlin.android().compilations["debug"].output.allOutputs))

    reports {
        html.isEnabled = true
    }

    dependsOn(allprojects.map { it.tasks.named<Test>("testDebugUnitTest") })
}

tasks.register<JacocoCoverageVerification>("verifyCodeCoverage") {
    val minCodeCoveragePercent: Int = 95

    val codeCoverageReport: JacocoReport by tasks
    val basePackage = "com.fivestars.instore"

    // FIXME(INSTORE-799) Remove these as packages reach minCodeCoveragePercent
    // As you add tests, please update these numbers as appropriate.  when a
    // package hierarchy reaches 95% line coverage, delete it from this map.
    // When this map is empty, you can delete it and everything that references
    // it!
    val coverageOverrides = mapOf(
        ".battery*" to 0,
        ".bluetoothserial*" to 0,
        ".device*" to 0,
        ".dgram*" to 0,
        ".file*" to 0,
        ".kardreader*" to 0,
        ".ledcontroller*" to 0,
        ".message*" to 0,
        ".metadata*" to 0,
        ".navigate*" to 0,
        ".networkaffinity*" to 0,
        ".networkalerts*" to 0,
        ".prop*" to 0,
        ".system*" to 0,
        ".systemstats*" to 0,
        ".systemstats.util" to 11,
        ".util" to 0,
        ".util.messaging" to 0,
        ".util.webview" to 0,
        ".util.device" to 80,
        "" to 0 // base package
    ).mapKeys { (name, _) ->
        basePackage + name
    }

    executionData.setFrom(codeCoverageReport.executionData)
    sourceDirectories.setFrom(codeCoverageReport.sourceDirectories)
    classDirectories.setFrom(codeCoverageReport.classDirectories)

    doLast {
        logger.warn(
            "The following package hierarchies have reduced test coverage:\n" +
                    coverageOverrides.map { "${it.key} = ${it.value}%" }
                        .joinToString("\n")
        )
    }

    violationRules {
        rule {
            element = "PACKAGE"
            // FIXME(INSTORE-799) Remove all excludes once all code is covered
            excludes = listOf(
                basePackage,
                "$basePackage.*model*"
            ) + coverageOverrides.keys
            limit {
                counter = "LINE"
                minimum = BigDecimal(BigInteger("$minCodeCoveragePercent"), 2)
            }
        }

        // FIXME(INSTORE-799) Remove this once all packages have reached minCodeCoveragePercent
        coverageOverrides.forEach { (pkg, percentage) ->
            rule {
                element = "PACKAGE"
                includes = listOf(pkg)
                limit {
                    counter = "LINE"
                    value = "COVEREDRATIO"
                    minimum = BigDecimal(BigInteger("$percentage"), 2)
                }
            }
        }
    }

    dependsOn("codeCoverageReport")
}

val packForXcode by tasks.creating(Sync::class) {
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + "Arm64"
    val framework = kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(targetName).binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from({ framework.outputDirectory })
    into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)
this is my build.gradle.kts
i have an almost identical project setup that works and can't figure out what might be missing
what's crazy is the project builds just fine - I can run packForXcode and the framework is successfully built
d

darkmoon_uk

10/27/2020, 10:49 PM
It's a straw you've probably already grasped at... but 'Invalidate caches & restart' in IntelliJ can produce results...
d

dazza5000

10/27/2020, 10:49 PM
I wish it was one of those
d

darkmoon_uk

10/27/2020, 10:50 PM
Hmm. Using an up-to-date Gradle version i.e. >= 6.4 ?
Hey @dazza5000 try this; I notice you've got Android plugin applying before Multiplatform.
I seem to recall it's significant to apply Multiplatform first.
Try swapping their order.
d

dazza5000

10/27/2020, 11:15 PM
Will do. Thank you so much for the help
no luck
a

Artyom Degtyarev [JB]

10/28/2020, 7:33 AM
Hello, @dazza5000, could you please check if the flag described here is set correctly in this project?
t

Tijl

10/28/2020, 10:01 AM
@Artyom Degtyarev [JB] in my experience this flag is more often the cause than that it solves anything. Have there been fixes on the IDE side for this recently?
a

Artyom Degtyarev [JB]

10/28/2020, 10:33 AM
Hi, @Tijl! In this particular case, the flag presence is important because of
ios()
target shortcut use. Its implementation relies on HMPP, so it has to be enabled to make everything work correctly. AFAIK, problems around its use are among the most prioritized tasks now. Could you refer to a couple of bugs on YT, just to let me check their state?
t

Tijl

10/28/2020, 10:35 AM
@Artyom Degtyarev [JB] for me it’s good to know there is awareness, I will save you the time to check and wait to see what is fixed in 1.4.20 when it’s out
👍 1
d

dazza5000

10/28/2020, 5:34 PM
will check the flag - thank you
10 Views