icerockdev / moko-kswift

Swift-friendly api generator for Kotlin/Native frameworks
https://moko.icerock.dev
Apache License 2.0
348 stars 21 forks source link

Ks classes were not generated ? Why? #55

Open RageshAntony opened 1 year ago

RageshAntony commented 1 year ago

Why LoginViewModelActionKs is not generated ? I am getting

Cannot find 'LoginViewModelActionKs' in scope

I added everything in the gradle . But still no Ks classes generated .

My gradle files:

project gradle

buildscript {
    val compose_version by extra("1.1.0-beta01")
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
        classpath("com.android.tools.build:gradle:7.2.1")
        classpath("dev.icerock.moko:kswift-gradle-plugin:0.5.0")
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

tasks.register("clean", Delete::class) {
    delete(rootProject.buildDir)
}

shared module gradle

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    id("com.android.library")
    id("dev.icerock.moko.kswift")
}

version = "1.0"
val mokoMvvmVersion = "0.13.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"
        podfile = project.file("../iosApp/Podfile")
        framework {
            baseName = "MultiPlatformLibrary"
            export("dev.icerock.moko:mvvm-core:$mokoMvvmVersion")
            export("dev.icerock.moko:mvvm-flow:$mokoMvvmVersion")
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation ("com.badoo.reaktive:reaktive:1.2.2")
                implementation ("com.badoo.reaktive:reaktive-annotations:1.2.2")
                api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1-native-mt")
                api("dev.icerock.moko:mvvm-core:$mokoMvvmVersion")
                api("dev.icerock.moko:mvvm-flow:$mokoMvvmVersion")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val androidMain by getting {
            dependencies {
                api("dev.icerock.moko:mvvm-flow-compose:$mokoMvvmVersion")
            }
        }
        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
    }
}

kswift {
    install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature)
}
dependencies {
    commonMainApi("dev.icerock.moko:kswift-runtime:0.5.0") // if you want use annotations
}

**shared Module Class:**

class LoginViewModel : ViewModel() {
    val login: CMutableStateFlow<String> = MutableStateFlow("").cMutableStateFlow()
    val password: CMutableStateFlow<String> = MutableStateFlow("").cMutableStateFlow()

    private val _isLoading: MutableStateFlow<Boolean> = MutableStateFlow(false)
    val isLoading: CStateFlow<Boolean> = _isLoading.cStateFlow()
    val isButtonEnabled: CStateFlow<Boolean> =
        combine(isLoading, login, password) { isLoading, login, password ->
            isLoading.not() && login.isNotBlank() && password.isNotBlank()
        }.stateIn(viewModelScope, SharingStarted.Eagerly, false).cStateFlow()
    private val _actions = Channel<Action>()
    val actions: CFlow<Action> get() = _actions.receiveAsFlow().cFlow()
    fun onLoginPressed() {
        _isLoading.value = true
        viewModelScope.launch {
            delay(1000)
            _isLoading.value = false
            _actions.send(Action.LoginSuccess)
        }
    }
     @SwiftInclude
    sealed interface Action { // not generated ????
        object LoginSuccess : Action
    }
}

please help me

Alex009 commented 1 year ago

try this steps:

  1. ./gradlew clean
  2. Run build from xcode (at this step build can failed). gradle should execute syncFramework task, that should execute link** task to create framework and kswift will create swift files with framework. then syncFramework task will move framework and kswift files to directory build/cocoapods
  3. run pod install - at this step cocoapods will see generated sources and successful add this files to pods project
  4. run build again - at this step build should be successful
RageshAntony commented 1 year ago

try this steps:

  1. ./gradlew clean
  2. Run build from xcode (at this step build can failed). gradle should execute syncFramework task, that should execute link** task to create framework and kswift will create swift files with framework. then syncFramework task will move framework and kswift files to directory build/cocoapods
  3. run pod install - at this step cocoapods will see generated sources and successful add this files to pods project
  4. run build again - at this step build should be successful

Still same

I executed ./gradlew clean command and went to xcode and then executed "clean build folder" and then "build"

Then executed "pod install"

Then executed "Rebuild project" in studio

Still Ks Files not generated ?

burakeregar commented 1 year ago

I am having the same issue.

I have got a very simple sealed class like below which is located in shared/src/commonMain/kotlin/com/..

sealed class ResultType<out T : Any> {
    data class Success<out T : Any>(val value: T) : ResultType<T>()
    data class Error(val message: String, val cause: Exception? = null) : ResultType<Nothing>()
}

also tried with an interface, it's still the same:

sealed interface ResultType<out T : Any> {
    data class Success<out T : Any>(val value: T) : ResultType<T>
    data class Error(val message: String, val cause: Exception? = null) : ResultType<Nothing>
}

Implementation: shared - build.gradle.kts

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    kotlin("plugin.serialization") version "1.6.10"
    id("com.android.library")
    id("dev.icerock.moko.kswift") version "0.6.0"
}

kswift {
    install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature)
}
RageshAntony commented 1 year ago

I am having the same issue.

I have got a very simple sealed class like below which is located in shared/src/commonMain/kotlin/com/..

sealed class ResultType<out T : Any> {
    data class Success<out T : Any>(val value: T) : ResultType<T>()
    data class Error(val message: String, val cause: Exception? = null) : ResultType<Nothing>()
}

also tried with an interface, it's still the same:

sealed interface ResultType<out T : Any> {
    data class Success<out T : Any>(val value: T) : ResultType<T>
    data class Error(val message: String, val cause: Exception? = null) : ResultType<Nothing>
}

Implementation: shared - build.gradle.kts

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    kotlin("plugin.serialization") version "1.6.10"
    id("com.android.library")
    id("dev.icerock.moko.kswift") version "0.6.0"
}

kswift {
    install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature)
}

@burakeregar

Please refer this link

https://github.com/Alex009/moko-mvvm-compose-swiftui/issues/2#issuecomment-1216170718

Fixed it

hoc081098 commented 1 year ago

My workaround

import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink

tasks.withType<KotlinNativeLink>()
  .matching { it.binary is Framework }
  .configureEach {
    doLast {
      val kSwiftGeneratedDir = destinationDirectory.get()
        .dir("${binary.baseName}Swift")
        .asFile

      val kSwiftPodSourceDir = buildDir
        .resolve("cocoapods")
        .resolve("framework")
        .resolve("${binary.baseName}Swift")

      kSwiftGeneratedDir.copyRecursively(kSwiftPodSourceDir, overwrite = true)
      println("[COPIED] $kSwiftGeneratedDir -> $kSwiftPodSourceDir")
    }
  }