I´m complete new to Android Studio with multiplatform projects and Kotlin.
Actually I´m wondering because of two things.
After writing the logic in Kotlin shared/src/commonMain/... I wanted to test it by writing an Activity on the Android part. I made a new one in shared/src/AndroidMain/... by rightclick on the folder.
The new Activity has been generated in shared/src/Main/... - a new folder hirachy. Why??
After that, my gradle.build in shared/ cannot be synced anymore. I´m getting the error:
Cocoapods Integration requires pod version to be specified.
Please specify pod version by adding 'version = ""' to the cocoapods block.
Alternatively, specify the version for the entire project explicitly.
Pod version format has to conform podspec syntax requirements: https://guides.cocoapods.org/syntax/podspec.html#version
I´ve put 'version="1.0"' on every part of the gradle files where it could be right but the message still remains.
Can anybody explain me excactly where to put the version number? I´ve read a lot of pages, saying all the same but nothing works for my project.
Here my shared/build.gradle.kts
plugins {
kotlin("multiplatform")
id("org.jetbrains.gradle.apple.applePlugin") version "212.4638.14-0.13.1"
//kotlin("native.cocoapods")
id ("org.jetbrains.kotlin.native.cocoapods")
id("com.android.library")
id ("com.google.gms.google-services")
kotlin("plugin.serialization")
id("org.jetbrains.kotlin.android")
}
version = "1.0"
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
version = "1.0"
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
specRepos {
url("https://github.com/Kotlin/kotlin-cocoapods-spec.git")
}
pod("FirebaseAuth")
}
sourceSets {
val commonMain by getting{
dependencies{
implementation("dev.gitlive:firebase-database:1.6.1")
implementation ("dev.gitlive:firebase-auth:1.6.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0-RC")
}
version = "1.0"
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
version = "1.0"
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
compileSdk = 32
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 27
targetSdk = 32
}
buildFeatures {
viewBinding = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies{
implementation("dev.gitlive:firebase-database:1.6.1")
implementation ("dev.gitlive:firebase-auth:1.6.1")
implementation("com.google.android.material:material:1.4.0")
implementation("androidx.appcompat:appcompat:1.5.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.navigation:navigation-fragment-ktx:2.3.5")
implementation("androidx.navigation:navigation-ui-ktx:2.3.5")
//implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0-RC")
}
Any help would be highly appreciated :-)
Platform Windows 11
AndroidStudio 2021.2.1 Patch 2
Kotlin 1.7.10
Related
I am trying to add android() as a build target to a Kotlin Multiplatform library so that I can add a specific library for the android target. All the other targets (jvm, linux, ios) work fine, but android seems to have issues, because the KotlinSourceSet is not being create like the others.
That's where I get the error:
KotlinSourceSet with name 'androidMain' not found.
I wonder, do I have to add the SourceSet manually? Am I missing some crucial build step?
Here is my gradle.build.kts
plugins {
id("maven-publish")
kotlin("multiplatform") version "1.8.0"
}
buildscript {
repositories {
google()
}
dependencies {
classpath ("com.android.tools.build:gradle:4.2.2")
classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
}
}
group = "zzz.xxxx"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
kotlin {
jvm()
linuxX64("linux")
ios()
android()
sourceSets {
val commonMain by getting {
dependencies {
implementation("...")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val jvmMain by getting {
dependencies {
implementation("...")
}
}
val androidMain by getting {
dependencies {
implementation ("...")
}
}
val jvmTest by getting
}
}
I tried adding a androidMain folder, but it is not getting recognized as a KotlinSourceSet. Non of the resources online seem to help either.
To add android as a build target your need to setup android-gradle-plugin first.
With example setting of android plugin gradle.build.kts will be:
plugins {
id("maven-publish")
kotlin("multiplatform") version "1.8.0"
id("com.android.library") version "7.3.0" // (1) add plugin
}
//...
// (2) setup plugin
android {
compileSdk = 33
defaultConfig {
minSdk = 24
multiDexEnabled = true
}
sourceSets {
getByName("main") {
manifest.srcFile("src/androidMain/AndroidManifest.xml")
}
}
}
UPDATE
Before you are adding Android Gradle plugin:
Check that Google Maven repository is listed in your settings.gradle(.kts) file
Check the Android Gradle plugin is added to the project build.gradle(.kts) file
Check the Android Gradle plugin is compatible with your Gradle version
I am trying to read/write files in the commonMain module.
I created a new Kotlin Multiplatform App for Android and iOS using the Android Studio Wizard. (New -> New Project ... -> Koltin Multiplatform App)
Then I added okio as dependency to common in the shared/build.gradle.kts file.
sourceSets {
val okio = "3.3.0"
val commonMain by getting {
dependencies {
implementation("com.squareup.okio:okio:$okio")
}
}
...
In the module commonMain I cannot access FileSystem.SYSTEM (Unresolved Reference: SYSTEM) and therefore not read or write any files.
In the module iOSMain and androidMain I can access FileSystem.SYSTEM. Is this expected behaviour? This would require me to write an expected/actual mapping for all okio apis. Or is there an other way?
Or do I need to configure my project differently to be able to access FileSystem.SYSTEM inside the commonMain-Module?
shared/build.gradle
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
}
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
}
sourceSets {
val okio = "3.3.0"
val commonMain by getting {
dependencies {
implementation("com.squareup.okio:okio:$okio")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
namespace = "de.pixel.kmmpodstryout"
compileSdk = 32
defaultConfig {
minSdk = 21
targetSdk = 32
}
}
Greetings.kt in commonMain from the sample app generated by the wizard:
package de.pixel.kmmpodstryout
import okio.FileSystem
import okio.Path.Companion.toPath
class Greeting {
private val platform: Platform = getPlatform()
fun greet(): String {
val path = "helloworld.txt".toPath()
FileSystem.SYSTEM <--- "Unresolved Reference SYSTEM"
return "Hello, ${platform.name} ${readFile()}!"
}
}
We are trying to build single business logic with kmm to share it with ios and android and react project
IOS Project contains
swiftUI
cocoapods
react
typescript and react framework
package.json
the ios and react project doesn't include any kotlin code the business logic is compiled to .framework library and configured by default how do the same? build business logic as js library?
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
kotlin("plugin.serialization") version "1.7.21"
id("com.android.library")
}
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
js {
browser {
webpackTask {
output.libraryTarget = "commonjs2"
}
}
binaries.executable()
}
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "14.1"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(Coroutines.coroutinesCore)
implementation(Ktor.ktorCore)
implementation(Ktor.ktorContentNegotiation)
implementation(Ktor.ktorLogging)
implementation(Ktor.ktorSerializationJson)
implementation(SLF4j.slf4j)
implementation(Koin.koinCore)
implementation(MultiplatformSettings.settings)
implementation(Json.gson)
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting {
dependencies {
implementation(Ktor.ktorAndroid)
}
}
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
dependencies {
implementation(Ktor.ktorIos)
}
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
val jsMain by getting {
dependsOn(commonMain)
dependencies {
implementation(Ktor.ktorJs)
}
}
}
}
android {
namespace = "com.sample.kmm"
compileSdk = 33
defaultConfig {
minSdk = 21
targetSdk = 33
}
}
Kotlin Multiplatform share business logic with react project like ios
Hey I am working in kotlin multiplatform. When I am create KMM module it will create automatically my .podspec file inside
app
| kotlinmultiplatformsharedmodule
| build
| src
| build.gradle.kts
| kotlinmultiplatformsharedmodule.podspec
| libs
| src
| //more file
like this type of structure. I want to change the directory of kotlinmultiplatformsharedmodule.podspec to root directory. I don't know how to do that. Can someone suggest me How can I achieved this. My Github project link.
Actually I am doing this because I am getting this weird issue in my ios project. I got suggestion of my some friends to do this approach.
Well, I would like to recommend you to try the following approach then.
Put .podspec file and a prebuilt framework to the git repository, make sure that the .podspec can be found in the repo's root directory and the framework is where your vendored_framework option points to, and depend on this repo from your iOS project. The error message in your clearly states that the CocoaPods was unable to locate the podspec(its three folders deep into the repository right now, so this might be expected).
build.gradle.kts
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
}
version = "1.0"
kotlin {
android()
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
ios.deploymentTarget = "14.1"
framework {
baseName = "kotlinmultiplatformsharedmodule"
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val androidMain by getting
val androidTest by getting
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}
android {
compileSdk = 32
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 21
targetSdk = 32
}
}
Can someone suggest me. How to do that this. I am totally new in KMM. Thanks
I have created a demo project to integrate cocoapods into the KMM project. I have followed this link from the official website. At step 3 while reimporting the project, I am receiving the following error.
Project already has a CocoaPods dependency with name SDWebImage , after which I am unable to even import this lib in KMM.
Can anyone please help with this?
Update: Adding build.gradle.kts
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
id("com.android.library")
kotlin("native.cocoapods")
}
// CocoaPods requires the podspec to have a version.
version = "1.0"
kotlin {
android()
ios {
cocoapods {
// Configure fields required by CocoaPods.
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
pod("SDWebImage")
// You can change the name of the produced framework.
// By default, it is the name of the Gradle project.
frameworkName = "shared"
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("com.google.android.material:material:1.2.1")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13")
}
}
val iosMain by getting
val iosTest by getting
}
}
android {
compileSdkVersion(29)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
}
}
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" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework = kotlin.targets.getByName<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)
When you’re using cocoapods plugin you don’t need to manually declare packForXcode target, maybe that’s the problem. Try to remove everything after val packForXcode
cocoapods section should be inside kotlin, not inside ios