From 6848c32b00e00482f9fad966220509c6453070b4 Mon Sep 17 00:00:00 2001 From: Kuzmin <«vkuzmin@icerockdev.com»> Date: Tue, 18 Nov 2025 14:40:29 +0300 Subject: [PATCH 1/4] update versions --- gradle.properties | 5 +++-- gradle/libs.versions.toml | 15 +++++++-------- gradle/wrapper/gradle-wrapper.properties | 2 +- network-bignum/build.gradle.kts | 4 +++- .../moko/network/bignum/BigNumSerializer.kt | 2 ++ network-engine/build.gradle.kts | 4 +++- network-errors/build.gradle.kts | 8 ++++++-- .../MR => moko-resources}/base/strings.xml | 0 .../MR => moko-resources}/ru/strings.xml | 0 network-generator/build.gradle.kts | 8 +++++--- network-generator/settings.gradle.kts | 1 - network/build.gradle.kts | 7 ++++--- .../dev/icerock/moko/network/LanguageProvider.kt | 4 ++-- .../moko/network/plugins/ExceptionPlugin.kt | 5 +++-- .../dev/icerock/moko/network/LanguageProvider.kt | 2 +- .../moko/network/ThrowableToNSErrorMapper.kt | 10 +++++++--- .../dev/icerock/moko/network/LanguageProvider.kt | 4 ++-- sample/android-app/build.gradle.kts | 3 ++- sample/form-data-binary-server/build.gradle.kts | 10 +++++----- sample/mpp-library/build.gradle.kts | 16 +++++++++------- sample/websocket-echo-server/build.gradle.kts | 12 ++++++------ settings.gradle.kts | 3 --- 22 files changed, 71 insertions(+), 54 deletions(-) rename network-errors/src/commonMain/{resources/MR => moko-resources}/base/strings.xml (100%) rename network-errors/src/commonMain/{resources/MR => moko-resources}/ru/strings.xml (100%) diff --git a/gradle.properties b/gradle.properties index f8573ea..c30c5f4 100755 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ mobile.multiplatform.iosTargetWarning=false xcodeproj=./sample/ios-app -moko.android.targetSdk=33 -moko.android.compileSdk=33 +moko.android.targetSdk=35 +moko.android.compileSdk=35 moko.android.minSdk=16 moko.publish.name=MOKO network @@ -23,3 +23,4 @@ moko.publish.repo.org=icerockdev moko.publish.repo.name=moko-network moko.publish.license=Apache-2.0 moko.publish.developers=alex009|Aleksey Mikhailov|Aleksey.Mikhailov@icerockdev.com,Tetraquark|Vladislav Areshkin|vareshkin@icerockdev.com,Dorofeev|Andrey Dorofeev|adorofeev@icerockdev.com +kotlin.mpp.applyDefaultHierarchyTemplate=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7ac0147..7512071 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlinVersion = "1.8.10" +kotlinVersion = "2.0.20" # android lifecycleViewModelVersion = "2.6.1" @@ -12,11 +12,11 @@ openApiGeneratorVersion = "5.2.0" guavaVersion = "30.1-jre" # kotlinx -kotlinxSerializationVersion = "1.5.0" -coroutinesVersion = "1.6.4" +kotlinxSerializationVersion = "1.7.3" +coroutinesVersion = "1.9.0" # moko -mokoResourcesVersion = "0.21.2" +mokoResourcesVersion = "0.24.4" mokoMvvmVersion = "0.16.0" mokoErrorsVersion = "0.7.0" mokoTestVersion = "0.6.1" @@ -30,7 +30,7 @@ androidxTestVersion = "1.5.0" robolectricVersion = "4.9" # other -ktorClientVersion = "2.2.2" +ktorClientVersion = "3.0.0" kbignumVersion = "2.4.12" multidexVersion = "2.0.1" @@ -72,7 +72,6 @@ robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectr testRunner = { module = "androidx.test:runner", version.ref = "testRunnerVersion" } testRules = { module = "androidx.test:rules", version.ref = "testRunnerVersion" } testExtJunit = { module = "androidx.test.ext:junit", version.ref = "testExtJunitVersion" } -kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlinVersion" } kotlinTestAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlinVersion" } mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } @@ -83,6 +82,6 @@ guava = { module = "com.google.guava:guava", version.ref = "guavaVersion" } # gradle plugins kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlinVersion" } kotlinSerializationGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlinVersion" } -androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "7.4.2" } +androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.7.3" } mokoResourcesGradlePlugin = { module = "dev.icerock.moko:resources-generator", version.ref = "mokoResourcesVersion" } -mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.3.0" } +mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.5.1" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 31cca49..2fa91c5 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/network-bignum/build.gradle.kts b/network-bignum/build.gradle.kts index edf3dba..73258ce 100644 --- a/network-bignum/build.gradle.kts +++ b/network-bignum/build.gradle.kts @@ -14,6 +14,8 @@ android { } kotlin { + jvmToolchain(17) + jvm() } @@ -21,5 +23,5 @@ dependencies { commonMainImplementation(libs.kotlinSerialization) commonMainApi(libs.kbignum) - commonMainImplementation(projects.network) + commonMainImplementation(project(":network")) } diff --git a/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt b/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt index 2accd2a..e4c160a 100644 --- a/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt +++ b/network-bignum/src/commonMain/kotlin/dev/icerock/moko/network/bignum/BigNumSerializer.kt @@ -5,6 +5,7 @@ package dev.icerock.moko.network.bignum import com.soywiz.kbignum.BigNum +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializer import kotlinx.serialization.descriptors.PrimitiveKind @@ -12,6 +13,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = BigNum::class) object BigNumSerializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor( diff --git a/network-engine/build.gradle.kts b/network-engine/build.gradle.kts index d9fbf26..cb83b9d 100644 --- a/network-engine/build.gradle.kts +++ b/network-engine/build.gradle.kts @@ -15,6 +15,8 @@ android { } kotlin { + jvmToolchain(17) + jvm() sourceSets { @@ -39,6 +41,6 @@ kotlin { dependencies { commonMainImplementation(libs.coroutines) - commonMainApi(projects.network) + commonMainApi(project(":network")) iosMainApi(libs.ktorClientIos) } diff --git a/network-errors/build.gradle.kts b/network-errors/build.gradle.kts index 8537ff2..86fbeff 100644 --- a/network-errors/build.gradle.kts +++ b/network-errors/build.gradle.kts @@ -14,15 +14,19 @@ android { namespace = "dev.icerock.moko.network.errors" } +kotlin { + jvmToolchain(17) +} + dependencies { commonMainImplementation(libs.kotlinSerialization) commonMainApi(libs.mokoErrors) commonMainApi(libs.mokoResources) - commonMainImplementation(projects.network) + commonMainImplementation(project(":network")) } multiplatformResources { - multiplatformResourcesPackage = "dev.icerock.moko.network.errors" + resourcesPackage = "dev.icerock.moko.network.errors" } diff --git a/network-errors/src/commonMain/resources/MR/base/strings.xml b/network-errors/src/commonMain/moko-resources/base/strings.xml similarity index 100% rename from network-errors/src/commonMain/resources/MR/base/strings.xml rename to network-errors/src/commonMain/moko-resources/base/strings.xml diff --git a/network-errors/src/commonMain/resources/MR/ru/strings.xml b/network-errors/src/commonMain/moko-resources/ru/strings.xml similarity index 100% rename from network-errors/src/commonMain/resources/MR/ru/strings.xml rename to network-errors/src/commonMain/moko-resources/ru/strings.xml diff --git a/network-generator/build.gradle.kts b/network-generator/build.gradle.kts index e9c3fa6..25ed8ee 100644 --- a/network-generator/build.gradle.kts +++ b/network-generator/build.gradle.kts @@ -36,8 +36,8 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 withJavadocJar() withSourcesJar() } @@ -49,7 +49,9 @@ configure { } tasks.withType().configureEach { - kotlinOptions.jvmTarget = "1.8" + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) + } } gradlePlugin { diff --git a/network-generator/settings.gradle.kts b/network-generator/settings.gradle.kts index eb7a3f9..1f97078 100644 --- a/network-generator/settings.gradle.kts +++ b/network-generator/settings.gradle.kts @@ -1,7 +1,6 @@ /* * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { repositories { diff --git a/network/build.gradle.kts b/network/build.gradle.kts index 06a0437..82f67de 100644 --- a/network/build.gradle.kts +++ b/network/build.gradle.kts @@ -16,6 +16,7 @@ android { } kotlin { + jvmToolchain(17) jvm() sourceSets { @@ -27,6 +28,9 @@ kotlin { val androidMain by getting { dependsOn(commonJvmAndroid) + dependencies { + implementation(libs.appCompat) + } } val jvmMain by getting { @@ -46,10 +50,7 @@ dependencies { commonMainApi(libs.kotlinSerialization) commonMainApi(libs.ktorClient) - androidMainImplementation(libs.appCompat) - commonTestImplementation(libs.ktorClientMock) - commonTestImplementation(libs.kotlinTest) commonTestImplementation(libs.kotlinTestAnnotations) androidTestImplementation(libs.kotlinTestJUnit) diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 54eaa90..aeaaae8 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -4,7 +4,7 @@ package dev.icerock.moko.network -import dev.icerock.moko.network.plugins.LanguagePlugin +import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider @Suppress("EmptyDefaultConstructor") -expect class LanguageProvider() : LanguagePlugin.LanguageCodeProvider +expect class LanguageProvider() : LanguageCodeProvider diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt index 99fd63a..04bfd43 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/ExceptionPlugin.kt @@ -12,8 +12,9 @@ import io.ktor.client.plugins.plugin import io.ktor.client.statement.bodyAsChannel import io.ktor.http.isSuccess import io.ktor.util.AttributeKey -import io.ktor.utils.io.charsets.Charset +import io.ktor.utils.io.charsets.Charsets import io.ktor.utils.io.core.readText +import io.ktor.utils.io.readRemaining class ExceptionPlugin(private val exceptionFactory: ExceptionFactory) { @@ -36,7 +37,7 @@ class ExceptionPlugin(private val exceptionFactory: ExceptionFactory) { val call = execute(request) if (!call.response.status.isSuccess()) { val packet = call.response.bodyAsChannel().readRemaining() - val responseString = packet.readText(charset = Charset.forName("UTF-8")) + val responseString = packet.readText(charset = Charsets.UTF_8) throw plugin.exceptionFactory.createException( request = call.request, response = call.response, diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 22e846d..f09217c 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -10,7 +10,7 @@ import platform.Foundation.currentLocale import platform.Foundation.languageCode actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String { + override fun getLanguageCode(): String? { return NSLocale.currentLocale.languageCode } } diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt index f6ec739..2f613d3 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt @@ -7,19 +7,23 @@ package dev.icerock.moko.network import platform.Foundation.NSError -import kotlin.native.concurrent.AtomicReference +import kotlin.concurrent.atomics.AtomicReference +import kotlin.concurrent.atomics.ExperimentalAtomicApi object ThrowableToNSErrorMapper : (Throwable) -> NSError? { + @OptIn(ExperimentalAtomicApi::class) private val mapperRef: AtomicReference<((Throwable) -> NSError?)?> = AtomicReference(null) + @OptIn(ExperimentalAtomicApi::class) override fun invoke(throwable: Throwable): NSError? { @Suppress("MaxLineLength") - return requireNotNull(mapperRef.value) { + return requireNotNull(mapperRef.load()) { "please setup ThrowableToNSErrorMapper by call ThrowableToNSErrorMapper.setup() in iosMain or use dev.icerock.moko.network.createHttpClientEngine" }.invoke(throwable) } + @OptIn(ExperimentalAtomicApi::class) fun setup(block: (Throwable) -> NSError?) { - mapperRef.value = block + mapperRef.store(block) } } diff --git a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 624680b..cd35a63 100644 --- a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -4,10 +4,10 @@ package dev.icerock.moko.network -import dev.icerock.moko.network.plugins.LanguagePlugin +import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider import java.util.Locale -actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { +actual class LanguageProvider : LanguageCodeProvider { override fun getLanguageCode(): String? { return Locale.getDefault().displayLanguage } diff --git a/sample/android-app/build.gradle.kts b/sample/android-app/build.gradle.kts index 97fb190..187652d 100644 --- a/sample/android-app/build.gradle.kts +++ b/sample/android-app/build.gradle.kts @@ -18,6 +18,7 @@ android { versionCode = 1 versionName = "0.1.0" } + namespace = "com.icerockdev.app" } dependencies { @@ -25,5 +26,5 @@ dependencies { implementation(libs.appCompat) implementation(libs.mokoMvvmDataBinding) implementation(libs.multidex) - implementation(projects.sample.mppLibrary) + implementation(project(":sample:mpp-library")) } diff --git a/sample/form-data-binary-server/build.gradle.kts b/sample/form-data-binary-server/build.gradle.kts index 4955c36..aea0a47 100644 --- a/sample/form-data-binary-server/build.gradle.kts +++ b/sample/form-data-binary-server/build.gradle.kts @@ -11,12 +11,12 @@ application { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } dependencies { - implementation("io.ktor:ktor-server-netty:2.2.1") - implementation("io.ktor:ktor-server-core:2.2.1") - implementation("ch.qos.logback:logback-classic:1.2.11") + implementation("io.ktor:ktor-server-netty:3.3.2") + implementation("io.ktor:ktor-server-core:3.3.2") + implementation("ch.qos.logback:logback-classic:1.5.21") } diff --git a/sample/mpp-library/build.gradle.kts b/sample/mpp-library/build.gradle.kts index 4807cdd..8e79908 100644 --- a/sample/mpp-library/build.gradle.kts +++ b/sample/mpp-library/build.gradle.kts @@ -15,6 +15,10 @@ plugins { id("dev.icerock.moko.gradle.tests") } +android { + namespace = "com.icerockdev.library" +} + dependencies { commonMainImplementation(libs.coroutines) commonMainImplementation(libs.ktorClient) @@ -26,15 +30,14 @@ dependencies { commonMainApi(libs.mokoMvvmCore) commonMainApi(libs.mokoMvvmLiveData) - commonMainApi(projects.network) - commonMainApi(projects.networkEngine) - commonMainApi(projects.networkBignum) - commonMainApi(projects.networkErrors) + commonMainApi(project(":network")) + commonMainApi(project(":network-bignum")) + commonMainApi(project(":network-engine")) + commonMainApi(project(":network-errors")) androidMainImplementation(libs.lifecycleViewModel) commonTestImplementation(libs.ktorClientMock) - commonTestImplementation(libs.kotlinTest) commonTestImplementation(libs.mokoTest) commonTestImplementation(libs.kotlinTestAnnotations) @@ -42,7 +45,7 @@ dependencies { } multiplatformResources { - multiplatformResourcesPackage = "com.icerockdev.library" + resourcesPackage = "com.icerockdev.library" } mokoNetwork { @@ -125,4 +128,3 @@ tasks.withType() testResourcesDir.copyRecursively(destinationDirectory.get().asFile, overwrite = true) } } - diff --git a/sample/websocket-echo-server/build.gradle.kts b/sample/websocket-echo-server/build.gradle.kts index 53a3917..e32f4e4 100644 --- a/sample/websocket-echo-server/build.gradle.kts +++ b/sample/websocket-echo-server/build.gradle.kts @@ -11,13 +11,13 @@ application { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } dependencies { - implementation("io.ktor:ktor-server-netty:1.5.1") - implementation("io.ktor:ktor-server-core:1.5.1") - implementation("io.ktor:ktor-websockets:1.5.1") - implementation("ch.qos.logback:logback-classic:1.2.9") + implementation("io.ktor:ktor-server-netty:3.3.2") + implementation("io.ktor:ktor-server-core:3.3.2") + implementation("io.ktor:ktor-websockets:3.3.2") + implementation("ch.qos.logback:logback-classic:1.5.21") } diff --git a/settings.gradle.kts b/settings.gradle.kts index 336451e..e7c8bd1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,9 +2,6 @@ * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -enableFeaturePreview("VERSION_CATALOGS") -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") - dependencyResolutionManagement { repositories { mavenCentral() From 82198d3b6e02f8eb968b4f580cc849521a969332 Mon Sep 17 00:00:00 2001 From: Kuzmin <«vkuzmin@icerockdev.com»> Date: Tue, 18 Nov 2025 14:45:45 +0300 Subject: [PATCH 2/4] fix gradle properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c30c5f4..805bdda 100755 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.mpp.androidSourceSetLayoutVersion=2 +kotlin.mpp.applyDefaultHierarchyTemplate=false android.useAndroidX=true @@ -23,4 +24,3 @@ moko.publish.repo.org=icerockdev moko.publish.repo.name=moko-network moko.publish.license=Apache-2.0 moko.publish.developers=alex009|Aleksey Mikhailov|Aleksey.Mikhailov@icerockdev.com,Tetraquark|Vladislav Areshkin|vareshkin@icerockdev.com,Dorofeev|Andrey Dorofeev|adorofeev@icerockdev.com -kotlin.mpp.applyDefaultHierarchyTemplate=false From 48e235ad66a593ec2961332ad81057be2adecda7 Mon Sep 17 00:00:00 2001 From: Aleksey Mikhailov Date: Tue, 18 Nov 2025 23:30:19 +0700 Subject: [PATCH 3/4] review fixes --- .github/workflows/compilation-check.yml | 6 +-- .github/workflows/publish.yml | 19 +++++--- .gitignore | 1 + README.md | 10 ++--- build.gradle.kts | 12 ----- gradle.properties | 4 +- gradle/libs.versions.toml | 37 +++++++++------- network-bignum/build.gradle.kts | 4 +- network-engine/build.gradle.kts | 4 +- network-errors/build.gradle.kts | 11 ++--- network-generator/build.gradle.kts | 44 ++++++------------- network/build.gradle.kts | 8 ++-- .../icerock/moko/network/LanguageProvider.kt | 2 +- .../icerock/moko/network/LanguageProvider.kt | 4 +- .../icerock/moko/network/LanguageProvider.kt | 2 +- .../moko/network/ThrowableToNSErrorMapper.kt | 10 ++--- .../icerock/moko/network/LanguageProvider.kt | 2 +- .../form-data-binary-server/build.gradle.kts | 6 +-- .../com/icerockdev/server/Application.kt | 3 -- sample/ios-app/Podfile | 2 +- sample/ios-app/Podfile.lock | 4 +- .../TestProj.xcodeproj/project.pbxproj | 4 +- sample/mpp-library/build.gradle.kts | 18 +++++--- .../src/androidMain/AndroidManifest.xml | 2 - sample/websocket-echo-server/build.gradle.kts | 8 ++-- .../com/icerockdev/server/Application.kt | 29 ++++++------ settings.gradle.kts | 2 + 27 files changed, 120 insertions(+), 138 deletions(-) delete mode 100755 sample/mpp-library/src/androidMain/AndroidManifest.xml diff --git a/.github/workflows/compilation-check.yml b/.github/workflows/compilation-check.yml index 57bc947..a14cab1 100644 --- a/.github/workflows/compilation-check.yml +++ b/.github/workflows/compilation-check.yml @@ -8,14 +8,14 @@ on: jobs: build: - runs-on: macOS-11 + runs-on: macOS-latest steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Check plugin run: ./gradlew -p network-generator build publishToMavenLocal - name: Check runtime diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7dce356..8b6c3ca 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: Publish library at mavenCentral - runs-on: macOS-11 + runs-on: macOS-latest env: OSSRH_USER: ${{ secrets.OSSRH_USER }} OSSRH_KEY: ${{ secrets.OSSRH_KEY }} @@ -21,14 +21,21 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 - - name: Publish plugin - run: ./gradlew -p network-generator publishPlugins -Pgradle.publish.key=${{ secrets.GRADLE_PLUGIN_PORTAL_KEY }} -Pgradle.publish.secret=${{ secrets.GRADLE_PLUGIN_PORTAL_SECRET }} + java-version: 17 + - name: Prebuild plugin + run: ./gradlew -p network-generator publishToMavenLocal + - name: Prebuild library + run: ./gradlew publishToMavenLocal - name: Publish library - run: ./gradlew publish + run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository + - name: Publish plugin to maven central + run: ./gradlew -p network-generator publishToSonatype closeAndReleaseSonatypeStagingRepository + - name: Publish plugin to Gradle Plugin Portal + run: ./gradlew -p network-generator publishPlugins -Pgradle.publish.key=${{ secrets.GRADLE_PLUGIN_PORTAL_KEY }} -Pgradle.publish.secret=${{ secrets.GRADLE_PLUGIN_PORTAL_SECRET }} + release: name: Create release needs: publish diff --git a/.gitignore b/.gitignore index 77fd544..b0ee716 100755 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .classpath .vscode .idea +.kotlin build *.iml Pods diff --git a/README.md b/README.md index f4e0f89..3e977f9 100755 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ buildscript { } dependencies { - classpath "dev.icerock.moko:network-generator:0.21.2" + classpath "dev.icerock.moko:network-generator:0.22.0" } } @@ -53,10 +53,10 @@ project build.gradle apply plugin: "dev.icerock.mobile.multiplatform-network-generator" dependencies { - commonMainApi("dev.icerock.moko:network:0.21.2") - commonMainApi("dev.icerock.moko:network-engine:0.21.2") // configured HttpClientEngine - commonMainApi("dev.icerock.moko:network-bignum:0.21.2") // kbignum serializer - commonMainApi("dev.icerock.moko:network-errors:0.21.2") // moko-errors integration + commonMainApi("dev.icerock.moko:network:0.22.0") + commonMainApi("dev.icerock.moko:network-engine:0.22.0") // configured HttpClientEngine + commonMainApi("dev.icerock.moko:network-bignum:0.22.0") // kbignum serializer + commonMainApi("dev.icerock.moko:network-errors:0.22.0") // moko-errors integration } ``` diff --git a/build.gradle.kts b/build.gradle.kts index feae419..5dedbf9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ /* * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -import org.gradle.api.internal.artifacts.DefaultModuleVersionSelector buildscript { repositories { @@ -25,17 +24,6 @@ val mokoVersion = libs.versions.mokoNetworkVersion.get() allprojects { this.group = "dev.icerock.moko" this.version = mokoVersion - - configurations.configureEach { - resolutionStrategy { - val coroutines: MinimalExternalModuleDependency = rootProject.libs.coroutines.get() - val forcedCoroutines: ModuleVersionSelector = DefaultModuleVersionSelector.newSelector( - coroutines.module, - coroutines.versionConstraint.requiredVersion - ) - force(forcedCoroutines) - } - } } tasks.register("clean", Delete::class).configure { diff --git a/gradle.properties b/gradle.properties index 805bdda..39823b5 100755 --- a/gradle.properties +++ b/gradle.properties @@ -14,8 +14,8 @@ mobile.multiplatform.iosTargetWarning=false xcodeproj=./sample/ios-app -moko.android.targetSdk=35 -moko.android.compileSdk=35 +moko.android.targetSdk=34 +moko.android.compileSdk=34 moko.android.minSdk=16 moko.publish.name=MOKO network diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7512071..dc64c93 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ mokoResourcesVersion = "0.24.4" mokoMvvmVersion = "0.16.0" mokoErrorsVersion = "0.7.0" mokoTestVersion = "0.6.1" -mokoNetworkVersion = "0.21.2" +mokoNetworkVersion = "0.22.0" # tests espressoCoreVersion = "3.5.1" @@ -30,7 +30,7 @@ androidxTestVersion = "1.5.0" robolectricVersion = "4.9" # other -ktorClientVersion = "3.0.0" +ktorVersion = "3.0.0" kbignumVersion = "2.4.12" multidexVersion = "2.0.1" @@ -38,7 +38,7 @@ multidexVersion = "2.0.1" # android appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidAppCompatVersion" } glide = { module = "com.github.bumptech.glide:glide", version.ref = "glideVersion" } -lifecycleViewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelVersion" } +lifecycleViewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelVersion" } multidex = { module = "androidx.multidex:multidex", version.ref = "multidexVersion" } coreKtx = { module = "androidx.core:core-ktx", version.ref = "coreKtxVersion" } @@ -47,22 +47,26 @@ kotlinSerialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-js coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutinesVersion" } # ktor -ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktorClientVersion" } -ktorClient = { module = "io.ktor:ktor-client-core", version.ref = "ktorClientVersion" } -ktorClientLogging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorClientVersion" } -ktorClientWebSocket = { module = "io.ktor:ktor-client-websockets", version.ref = "ktorClientVersion" } -ktorClientMock = { module = "io.ktor:ktor-client-mock", version.ref = "ktorClientVersion" } -ktorClientIos = { module = "io.ktor:ktor-client-ios", version.ref = "ktorClientVersion" } +ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktorVersion" } +ktorClient = { module = "io.ktor:ktor-client-core", version.ref = "ktorVersion" } +ktorClientLogging = { module = "io.ktor:ktor-client-logging", version.ref = "ktorVersion" } +ktorClientWebSocket = { module = "io.ktor:ktor-client-websockets", version.ref = "ktorVersion" } +ktorClientMock = { module = "io.ktor:ktor-client-mock", version.ref = "ktorVersion" } +ktorClientIos = { module = "io.ktor:ktor-client-ios", version.ref = "ktorVersion" } + +ktorServerNetty = { module = "io.ktor:ktor-server-netty", version.ref = "ktorVersion" } +ktorServerCore = { module = "io.ktor:ktor-server-core", version.ref = "ktorVersion" } +ktorServerWebSockets = { module = "io.ktor:ktor-server-websockets", version.ref = "ktorVersion" } # korlibs -kbignum = { module = "com.soywiz.korlibs.kbignum:kbignum", version.ref = "kbignumVersion" } +kbignum = { module = "com.soywiz.korlibs.kbignum:kbignum", version.ref = "kbignumVersion" } # moko -mokoMvvmDataBinding = { module = "dev.icerock.moko:mvvm-databinding", version.ref = "mokoMvvmVersion" } +mokoMvvmDataBinding = { module = "dev.icerock.moko:mvvm-databinding", version.ref = "mokoMvvmVersion" } mokoResources = { module = "dev.icerock.moko:resources", version.ref = "mokoResourcesVersion" } mokoMvvmCore = { module = "dev.icerock.moko:mvvm-core", version.ref = "mokoMvvmVersion" } mokoMvvmLiveData = { module = "dev.icerock.moko:mvvm-livedata", version.ref = "mokoMvvmVersion" } -mokoErrors = { module = "dev.icerock.moko:errors", version.ref = "mokoErrorsVersion" } +mokoErrors = { module = "dev.icerock.moko:errors", version.ref = "mokoErrorsVersion" } # tests espressoCore = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCoreVersion" } @@ -72,16 +76,17 @@ robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectr testRunner = { module = "androidx.test:runner", version.ref = "testRunnerVersion" } testRules = { module = "androidx.test:rules", version.ref = "testRunnerVersion" } testExtJunit = { module = "androidx.test.ext:junit", version.ref = "testExtJunitVersion" } -kotlinTestAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlinVersion" } -mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } +kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlinVersion" } +mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } # jvm openApiGenerator = { module = "org.openapitools:openapi-generator-gradle-plugin", version.ref = "openApiGeneratorVersion" } guava = { module = "com.google.guava:guava", version.ref = "guavaVersion" } +logback = { module = "ch.qos.logback:logback-classic", version = "1.5.21" } # gradle plugins kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlinVersion" } kotlinSerializationGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlinVersion" } -androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.7.3" } +androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.5.2" } mokoResourcesGradlePlugin = { module = "dev.icerock.moko:resources-generator", version.ref = "mokoResourcesVersion" } -mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.5.1" } +mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.6.0" } diff --git a/network-bignum/build.gradle.kts b/network-bignum/build.gradle.kts index 73258ce..edf3dba 100644 --- a/network-bignum/build.gradle.kts +++ b/network-bignum/build.gradle.kts @@ -14,8 +14,6 @@ android { } kotlin { - jvmToolchain(17) - jvm() } @@ -23,5 +21,5 @@ dependencies { commonMainImplementation(libs.kotlinSerialization) commonMainApi(libs.kbignum) - commonMainImplementation(project(":network")) + commonMainImplementation(projects.network) } diff --git a/network-engine/build.gradle.kts b/network-engine/build.gradle.kts index cb83b9d..d9fbf26 100644 --- a/network-engine/build.gradle.kts +++ b/network-engine/build.gradle.kts @@ -15,8 +15,6 @@ android { } kotlin { - jvmToolchain(17) - jvm() sourceSets { @@ -41,6 +39,6 @@ kotlin { dependencies { commonMainImplementation(libs.coroutines) - commonMainApi(project(":network")) + commonMainApi(projects.network) iosMainApi(libs.ktorClientIos) } diff --git a/network-errors/build.gradle.kts b/network-errors/build.gradle.kts index 86fbeff..5c408fe 100644 --- a/network-errors/build.gradle.kts +++ b/network-errors/build.gradle.kts @@ -14,17 +14,18 @@ android { namespace = "dev.icerock.moko.network.errors" } -kotlin { - jvmToolchain(17) -} - dependencies { commonMainImplementation(libs.kotlinSerialization) commonMainApi(libs.mokoErrors) commonMainApi(libs.mokoResources) - commonMainImplementation(project(":network")) + commonMainImplementation(projects.network) + + // temporary workaround for + // e: KLIB resolver: Could not find "dev.icerock.moko:parcelize + // caused moko-errors + iosMainApi("dev.icerock.moko:parcelize:0.9.0") } multiplatformResources { diff --git a/network-generator/build.gradle.kts b/network-generator/build.gradle.kts index 25ed8ee..cf876ae 100644 --- a/network-generator/build.gradle.kts +++ b/network-generator/build.gradle.kts @@ -2,8 +2,11 @@ * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { - id("com.gradle.plugin-publish") version ("0.15.0") + id("com.gradle.plugin-publish") version ("1.3.1") id("java-gradle-plugin") } @@ -36,48 +39,29 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 withJavadocJar() withSourcesJar() } -configure { - publications.register("mavenJava", MavenPublication::class) { - from(components["java"]) - } -} - -tasks.withType().configureEach { +tasks.withType().configureEach { compilerOptions { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) + jvmTarget.set(JvmTarget.JVM_1_8) } } gradlePlugin { + website.set("https://github.com/icerockdev/moko-network") + vcsUrl.set("https://github.com/icerockdev/moko-network") + plugins { create("multiplatform-network-generator") { id = "dev.icerock.mobile.multiplatform-network-generator" + displayName = "MOKO network generator plugin" implementationClass = "dev.icerock.moko.network.MultiPlatformNetworkGeneratorPlugin" + description = "Plugin to provide network components for iOS & Android" + tags = listOf("moko-network", "moko", "kotlin", "kotlin-multiplatform") } } } - -pluginBundle { - website = "https://github.com/icerockdev/moko-network" - vcsUrl = "https://github.com/icerockdev/moko-network" - description = "Plugin to provide network components for iOS & Android" - tags = listOf("moko-network", "moko", "kotlin", "kotlin-multiplatform") - - plugins { - getByName("multiplatform-network-generator") { - displayName = "MOKO network generator plugin" - } - } - - mavenCoordinates { - groupId = project.group as String - artifactId = project.name - version = project.version as String - } -} \ No newline at end of file diff --git a/network/build.gradle.kts b/network/build.gradle.kts index 82f67de..d9dc954 100644 --- a/network/build.gradle.kts +++ b/network/build.gradle.kts @@ -16,7 +16,6 @@ android { } kotlin { - jvmToolchain(17) jvm() sourceSets { @@ -28,9 +27,6 @@ kotlin { val androidMain by getting { dependsOn(commonJvmAndroid) - dependencies { - implementation(libs.appCompat) - } } val jvmMain by getting { @@ -50,8 +46,10 @@ dependencies { commonMainApi(libs.kotlinSerialization) commonMainApi(libs.ktorClient) + androidMainImplementation(libs.appCompat) + commonTestImplementation(libs.ktorClientMock) - commonTestImplementation(libs.kotlinTestAnnotations) + commonTestImplementation(libs.kotlinTest) androidTestImplementation(libs.kotlinTestJUnit) } diff --git a/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index 0f02181..cf474ce 100644 --- a/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/androidMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -9,7 +9,7 @@ import androidx.core.os.ConfigurationCompat import dev.icerock.moko.network.plugins.LanguagePlugin actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String? { + actual override fun getLanguageCode(): String? { return ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)?.language } } diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index aeaaae8..1dfb36b 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -7,4 +7,6 @@ package dev.icerock.moko.network import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider @Suppress("EmptyDefaultConstructor") -expect class LanguageProvider() : LanguageCodeProvider +expect class LanguageProvider() : LanguageCodeProvider { + override fun getLanguageCode(): String? +} diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index f09217c..d3cdc94 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -10,7 +10,7 @@ import platform.Foundation.currentLocale import platform.Foundation.languageCode actual class LanguageProvider : LanguagePlugin.LanguageCodeProvider { - override fun getLanguageCode(): String? { + actual override fun getLanguageCode(): String? { return NSLocale.currentLocale.languageCode } } diff --git a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt index 2f613d3..3c03c91 100644 --- a/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt +++ b/network/src/iosMain/kotlin/dev/icerock/moko/network/ThrowableToNSErrorMapper.kt @@ -7,23 +7,19 @@ package dev.icerock.moko.network import platform.Foundation.NSError -import kotlin.concurrent.atomics.AtomicReference -import kotlin.concurrent.atomics.ExperimentalAtomicApi +import kotlin.concurrent.AtomicReference object ThrowableToNSErrorMapper : (Throwable) -> NSError? { - @OptIn(ExperimentalAtomicApi::class) private val mapperRef: AtomicReference<((Throwable) -> NSError?)?> = AtomicReference(null) - @OptIn(ExperimentalAtomicApi::class) override fun invoke(throwable: Throwable): NSError? { @Suppress("MaxLineLength") - return requireNotNull(mapperRef.load()) { + return requireNotNull(mapperRef.value) { "please setup ThrowableToNSErrorMapper by call ThrowableToNSErrorMapper.setup() in iosMain or use dev.icerock.moko.network.createHttpClientEngine" }.invoke(throwable) } - @OptIn(ExperimentalAtomicApi::class) fun setup(block: (Throwable) -> NSError?) { - mapperRef.store(block) + mapperRef.value = block } } diff --git a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt index cd35a63..56131de 100644 --- a/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt +++ b/network/src/jvmMain/kotlin/dev/icerock/moko/network/LanguageProvider.kt @@ -8,7 +8,7 @@ import dev.icerock.moko.network.plugins.LanguagePlugin.LanguageCodeProvider import java.util.Locale actual class LanguageProvider : LanguageCodeProvider { - override fun getLanguageCode(): String? { + actual override fun getLanguageCode(): String? { return Locale.getDefault().displayLanguage } } diff --git a/sample/form-data-binary-server/build.gradle.kts b/sample/form-data-binary-server/build.gradle.kts index aea0a47..07db3d0 100644 --- a/sample/form-data-binary-server/build.gradle.kts +++ b/sample/form-data-binary-server/build.gradle.kts @@ -16,7 +16,7 @@ java { } dependencies { - implementation("io.ktor:ktor-server-netty:3.3.2") - implementation("io.ktor:ktor-server-core:3.3.2") - implementation("ch.qos.logback:logback-classic:1.5.21") + implementation(libs.ktorServerNetty) + implementation(libs.ktorServerCore) + implementation(libs.logback) } diff --git a/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt b/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt index e8be909..ce554e9 100644 --- a/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt +++ b/sample/form-data-binary-server/src/main/kotlin/com/icerockdev/server/Application.kt @@ -8,14 +8,11 @@ import io.ktor.http.content.PartData import io.ktor.http.content.forEachPart import io.ktor.http.content.streamProvider import io.ktor.server.application.Application -import io.ktor.server.application.call import io.ktor.server.request.receiveMultipart import io.ktor.server.response.respondText import io.ktor.server.routing.post import io.ktor.server.routing.routing import java.io.File -import kotlin.collections.mutableMapOf -import kotlin.collections.set fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) diff --git a/sample/ios-app/Podfile b/sample/ios-app/Podfile index 04ec21c..0df9ade 100644 --- a/sample/ios-app/Podfile +++ b/sample/ios-app/Podfile @@ -12,6 +12,6 @@ install! 'cocoapods', :disable_input_output_paths => true target 'TestProj' do # MultiPlatformLibrary - # для корректной установки фреймворка нужно сначала скомпилировать котлин библиотеку - compile-kotlin-framework.sh (в корневой директории репозитория) + # at first run ./gradlew :sample:mpp-library:syncMultiPlatformLibraryDebugFrameworkIosSimulatorArm64 pod 'MultiPlatformLibrary', :path => '../mpp-library' end diff --git a/sample/ios-app/Podfile.lock b/sample/ios-app/Podfile.lock index 2092641..0a7c980 100644 --- a/sample/ios-app/Podfile.lock +++ b/sample/ios-app/Podfile.lock @@ -11,6 +11,6 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: MultiPlatformLibrary: 2a9f43df7bd018c32611a2087c1e2ef74847394c -PODFILE CHECKSUM: 68b1a7b3453f9dbea0e91a6439f872724d5c91ce +PODFILE CHECKSUM: ad3ecd1afe182c0aea10da9a77e9652b5f68993b -COCOAPODS: 1.11.3 +COCOAPODS: 1.16.2 diff --git a/sample/ios-app/TestProj.xcodeproj/project.pbxproj b/sample/ios-app/TestProj.xcodeproj/project.pbxproj index 1443eb6..627b61e 100644 --- a/sample/ios-app/TestProj.xcodeproj/project.pbxproj +++ b/sample/ios-app/TestProj.xcodeproj/project.pbxproj @@ -112,7 +112,7 @@ 287627FB1F319065007FA12B /* Sources */, 287627FC1F319065007FA12B /* Frameworks */, 287627FD1F319065007FA12B /* Resources */, - 07695594F733E91F16ACB8C4 /* [CP] Embed Pods Frameworks */, + A87E251FA49FF4830EB4D71E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -173,7 +173,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 07695594F733E91F16ACB8C4 /* [CP] Embed Pods Frameworks */ = { + A87E251FA49FF4830EB4D71E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( diff --git a/sample/mpp-library/build.gradle.kts b/sample/mpp-library/build.gradle.kts index 8e79908..1cf14bb 100644 --- a/sample/mpp-library/build.gradle.kts +++ b/sample/mpp-library/build.gradle.kts @@ -2,6 +2,9 @@ * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ +import dev.icerock.moko.network.tasks.GenerateTask +import io.gitlab.arturbosch.detekt.Detekt + plugins { id("com.android.library") id("dev.icerock.moko.gradle.android.base") @@ -30,16 +33,16 @@ dependencies { commonMainApi(libs.mokoMvvmCore) commonMainApi(libs.mokoMvvmLiveData) - commonMainApi(project(":network")) - commonMainApi(project(":network-bignum")) - commonMainApi(project(":network-engine")) - commonMainApi(project(":network-errors")) + commonMainApi(projects.network) + commonMainApi(projects.networkBignum) + commonMainApi(projects.networkEngine) + commonMainApi(projects.networkErrors) androidMainImplementation(libs.lifecycleViewModel) commonTestImplementation(libs.ktorClientMock) commonTestImplementation(libs.mokoTest) - commonTestImplementation(libs.kotlinTestAnnotations) + commonTestImplementation(libs.kotlinTest) androidTestImplementation(libs.kotlinTestJUnit) } @@ -128,3 +131,8 @@ tasks.withType() testResourcesDir.copyRecursively(destinationDirectory.get().asFile, overwrite = true) } } + +val generateTasks = tasks.withType() +tasks.withType().configureEach { + dependsOn(generateTasks) +} diff --git a/sample/mpp-library/src/androidMain/AndroidManifest.xml b/sample/mpp-library/src/androidMain/AndroidManifest.xml deleted file mode 100755 index 8f69414..0000000 --- a/sample/mpp-library/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/sample/websocket-echo-server/build.gradle.kts b/sample/websocket-echo-server/build.gradle.kts index e32f4e4..8638c92 100644 --- a/sample/websocket-echo-server/build.gradle.kts +++ b/sample/websocket-echo-server/build.gradle.kts @@ -16,8 +16,8 @@ java { } dependencies { - implementation("io.ktor:ktor-server-netty:3.3.2") - implementation("io.ktor:ktor-server-core:3.3.2") - implementation("io.ktor:ktor-websockets:3.3.2") - implementation("ch.qos.logback:logback-classic:1.5.21") + implementation(libs.ktorServerNetty) + implementation(libs.ktorServerCore) + implementation(libs.ktorServerWebSockets) + implementation(libs.logback) } diff --git a/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt b/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt index 394f033..407e072 100644 --- a/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt +++ b/sample/websocket-echo-server/src/main/kotlin/com/icerockdev/server/Application.kt @@ -4,27 +4,26 @@ package com.icerockdev.server -import io.ktor.application.Application -import io.ktor.application.call -import io.ktor.application.install import io.ktor.http.ContentType -import io.ktor.http.cio.websocket.Frame -import io.ktor.http.cio.websocket.pingPeriod -import io.ktor.http.cio.websocket.readText -import io.ktor.http.cio.websocket.timeout -import io.ktor.response.respondText -import io.ktor.routing.get -import io.ktor.routing.routing -import io.ktor.websocket.WebSockets -import io.ktor.websocket.webSocket -import java.time.Duration +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.response.respondText +import io.ktor.server.routing.get +import io.ktor.server.routing.routing +import io.ktor.server.websocket.WebSockets +import io.ktor.server.websocket.pingPeriod +import io.ktor.server.websocket.timeout +import io.ktor.server.websocket.webSocket +import io.ktor.websocket.Frame +import io.ktor.websocket.readText +import kotlin.time.Duration.Companion.seconds fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { install(WebSockets) { - pingPeriod = Duration.ofSeconds(15) - timeout = Duration.ofSeconds(15) + pingPeriod = 15.seconds + timeout = 15.seconds maxFrameSize = Long.MAX_VALUE masking = false } diff --git a/settings.gradle.kts b/settings.gradle.kts index e7c8bd1..9a10261 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,8 @@ * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + dependencyResolutionManagement { repositories { mavenCentral() From dd6f48ccda7a62bf547def037f3538217d1fa84c Mon Sep 17 00:00:00 2001 From: Kuzmin <«vkuzmin@icerockdev.com»> Date: Wed, 19 Nov 2025 11:29:58 +0300 Subject: [PATCH 4/4] fix RefreshTokenPluginTest --- .../network/plugins/RefreshTokenPlugin.kt | 13 +++++---- .../moko/network/plugins/TokenPlugin.kt | 3 +- .../kotlin/RefreshTokenPluginTest.kt | 29 ++++++++++++++----- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt index 4418004..45b26e0 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/RefreshTokenPlugin.kt @@ -7,7 +7,6 @@ package dev.icerock.moko.network.plugins import io.ktor.client.HttpClient import io.ktor.client.plugins.HttpClientPlugin import io.ktor.client.request.HttpRequest -import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.request import io.ktor.client.request.takeFrom import io.ktor.client.statement.HttpReceivePipeline @@ -51,11 +50,14 @@ class RefreshTokenPlugin( } refreshTokenHttpPluginMutex.withLock { + val originalRequest = subject.request + // If token of the request isn't actual, then token has already been updated and // let's just to try repeat request if (!plugin.isCredentialsActual(subject.request)) { - val requestBuilder = HttpRequestBuilder().takeFrom(subject.request) - val result: HttpResponse = scope.request(requestBuilder) + val result: HttpResponse = scope.request { + takeFrom(originalRequest) + } proceedWith(result) return@intercept } @@ -64,8 +66,9 @@ class RefreshTokenPlugin( // refresh request. if (plugin.updateTokenHandler.invoke()) { // If the request refresh was successful, then let's just to try repeat request - val requestBuilder = HttpRequestBuilder().takeFrom(subject.request) - val result: HttpResponse = scope.request(requestBuilder) + val result: HttpResponse = scope.request { + takeFrom(originalRequest) + } proceedWith(result) } else { // If the request refresh was unsuccessful diff --git a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt index 9639369..a48b062 100644 --- a/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt +++ b/network/src/commonMain/kotlin/dev/icerock/moko/network/plugins/TokenPlugin.kt @@ -30,11 +30,12 @@ class TokenPlugin private constructor( override fun prepare(block: Config.() -> Unit) = Config().apply(block).build() override fun install(plugin: TokenPlugin, scope: HttpClient) { - scope.requestPipeline.intercept(HttpRequestPipeline.State) { + scope.requestPipeline.intercept(HttpRequestPipeline.Before) { plugin.tokenProvider.getToken()?.apply { context.headers.remove(plugin.tokenHeaderName) context.header(plugin.tokenHeaderName, this) } + proceed() } } } diff --git a/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt b/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt index 6610d7f..e3741c2 100644 --- a/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt +++ b/network/src/commonTest/kotlin/RefreshTokenPluginTest.kt @@ -9,6 +9,8 @@ import io.ktor.client.engine.mock.MockEngine import io.ktor.client.engine.mock.MockRequestHandler import io.ktor.client.engine.mock.respondError import io.ktor.client.engine.mock.respondOk +import io.ktor.client.request.HttpRequest +import io.ktor.client.request.HttpRequestData import io.ktor.client.request.get import io.ktor.client.statement.request import io.ktor.http.HttpStatusCode @@ -49,6 +51,8 @@ class RefreshTokenPluginTest { val invalidToken = "123" val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) + var lastSuccessfulRequest: HttpRequestData? = null + val client = createMockClient( tokenProvider = { tokenHolder.value }, pluginConfig = { @@ -63,7 +67,10 @@ class RefreshTokenPluginTest { ) { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } val result = runBlocking { @@ -71,7 +78,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } @Test @@ -80,6 +87,7 @@ class RefreshTokenPluginTest { val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) var isFirstTime = true + var lastSuccessfulRequest: HttpRequestData? = null val client = createMockClient( tokenProvider = object : TokenPlugin.TokenProvider { @@ -105,7 +113,10 @@ class RefreshTokenPluginTest { handler = { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } ) @@ -122,7 +133,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } @Test @@ -131,6 +142,7 @@ class RefreshTokenPluginTest { val validToken = "124" val tokenHolder = MutableStateFlow(invalidToken) var isFirstTime = true + var lastSuccessfulRequest: HttpRequestData? = null val client = createMockClient( tokenProvider = object : TokenPlugin.TokenProvider { @@ -154,7 +166,10 @@ class RefreshTokenPluginTest { handler = { request -> if (request.headers[AUTH_HEADER_NAME] == invalidToken) { respondError(status = HttpStatusCode.Unauthorized) - } else respondOk() + } else { + lastSuccessfulRequest = request + respondOk() + } } ) @@ -171,7 +186,7 @@ class RefreshTokenPluginTest { } assertEquals(expected = HttpStatusCode.OK, actual = result.status) - assertEquals(expected = validToken, actual = result.request.headers[AUTH_HEADER_NAME]) + assertEquals(expected = validToken, actual = lastSuccessfulRequest?.headers?.get(AUTH_HEADER_NAME)) } private fun createMockClient( @@ -183,6 +198,7 @@ class RefreshTokenPluginTest { engine { addHandler(handler) } + install(RefreshTokenPlugin, pluginConfig) if (tokenProvider != null) { install(TokenPlugin) { @@ -190,7 +206,6 @@ class RefreshTokenPluginTest { this.tokenProvider = tokenProvider } } - install(RefreshTokenPlugin, pluginConfig) } }