From b94f8c9083913d2c1cfa818064807c6a80cc578b Mon Sep 17 00:00:00 2001 From: KotlinGeekDev Date: Mon, 12 Jan 2026 14:52:12 +0100 Subject: [PATCH] Foundations(iOS Sourceset): - Fix test resource loading for iOS targets(using Gradle env. variables). - Bring in the SwiftPackageManager for KMP plugin, to use Swift libraries for iOS implementations(and configure accordingly). - Bring in cachemap dependency(for iOS LargeCache implementation). --- gradle.properties | 5 ++- quartz/build.gradle.kts | 41 ++++++++++++++++++- .../quartz/TestResourceLoader.kt | 20 +++------ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/gradle.properties b/gradle.properties index 99f780b98..9226500a8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -27,4 +27,7 @@ android.nonFinalResIds=false kotlin.daemon.jvmargs=-Xmx12g -XX:MaxMetaspaceSize=3g # because we use a custom jvmAndroid target -kotlin.mpp.applyDefaultHierarchyTemplate=false \ No newline at end of file +kotlin.mpp.applyDefaultHierarchyTemplate=false + +# This is needed for the Swift bridge to work. +kotlin.mpp.enableCInteropCommonization=true \ No newline at end of file diff --git a/quartz/build.gradle.kts b/quartz/build.gradle.kts index a9f1d39e6..779270746 100644 --- a/quartz/build.gradle.kts +++ b/quartz/build.gradle.kts @@ -1,11 +1,17 @@ +@file:OptIn(ExperimentalSpmForKmpFeature::class) + import com.vanniktech.maven.publish.KotlinMultiplatform +import io.github.frankois944.spmForKmp.swiftPackageConfig +import io.github.frankois944.spmForKmp.utils.ExperimentalSpmForKmpFeature import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidLibrary) alias(libs.plugins.serialization) alias(libs.plugins.vanniktech.mavenPublish) + id("io.github.frankois944.spmForKmp") version "1.4.0" } android { @@ -74,6 +80,27 @@ kotlin { // https://developer.android.com/kotlin/multiplatform/migrate val xcfName = "quartz-kmpKit" + listOf( + iosArm64(), + iosX64(), + iosSimulatorArm64() + ).forEach { target -> + target.swiftPackageConfig(cinteropName = "swiftbridge") { + minIos = "17" + minMacos = "14" + dependency { + remotePackageVersion( + url = uri("https://github.com/swift-standards/swift-rfc-3986.git"), + packageName = "swift-rfc-3986", + products = { + add("RFC 3986") + }, + version = "0.1.0" + ) + } + } + } + iosX64 { binaries.framework { @@ -92,6 +119,18 @@ kotlin { baseName = xcfName } } + //This makes sure that the resource file directory is visible for iOS tests. + val rootDir = "${rootProject.rootDir.path}/quartz/src/iosTest/resources" + + tasks.withType().configureEach { + environment("TEST_RESOURCES_ROOT", rootDir) + } + + tasks.withType().configureEach { + environment("TEST_RESOURCES_ROOT", rootDir) + // This is necessary to have the variable propagated on iOS + environment("SIMCTL_CHILD_TEST_RESOURCES_ROOT", rootDir) + } // Source set declarations. // Declaring a target automatically creates a source set with the same name. By default, the @@ -211,7 +250,7 @@ kotlin { iosMain { dependsOn(commonMain.get()) dependencies { - + implementation("io.github.charlietap:cachemap:0.2.4") } } diff --git a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/TestResourceLoader.kt b/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/TestResourceLoader.kt index 029347f73..5d0a81cfe 100644 --- a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/TestResourceLoader.kt +++ b/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/TestResourceLoader.kt @@ -20,26 +20,18 @@ */ package com.vitorpamplona.quartz -import kotlinx.cinterop.BetaInteropApi import kotlinx.cinterop.ExperimentalForeignApi -import platform.Foundation.NSBundle +import kotlinx.cinterop.toKString import platform.Foundation.NSString import platform.Foundation.NSUTF8StringEncoding import platform.Foundation.stringWithContentsOfFile -import platform.darwin.NSObject -import platform.darwin.NSObjectMeta +import platform.posix.getenv actual class TestResourceLoader { - @OptIn(ExperimentalForeignApi::class, BetaInteropApi::class) + @OptIn(ExperimentalForeignApi::class) actual fun loadString(file: String): String { - val bundle = NSBundle.bundleForClass(BundleMarker) - val path = - bundle.pathForResource(file, ofType = null) - ?: throw IllegalArgumentException("Resource not found: $file") - return NSString.stringWithContentsOfFile(path, encoding = NSUTF8StringEncoding, error = null)!! - } - - private class BundleMarker : NSObject() { - companion object : NSObjectMeta() + val resourceDir = getenv("TEST_RESOURCES_ROOT")?.toKString() + val filePath = "$resourceDir/$file" + return NSString.stringWithContentsOfFile(filePath, encoding = NSUTF8StringEncoding, error = null) as String } }