From b187b63195afd06c150d355dec145b66541a9d37 Mon Sep 17 00:00:00 2001 From: Cilly Leang Date: Thu, 5 Mar 2026 00:00:18 +1100 Subject: [PATCH] feat: ios support --- composeApp/build.gradle.kts | 21 +++++++++++++++++++ .../spmMaplibre/StartYourBridgeHere.swift | 15 +++++++++++++ gradle.properties | 2 ++ gradle/libs.versions.toml | 4 +++- iosApp/iosApp/Info.plist | 2 ++ .../kotlin/moe/lava/banksia/room/Database.kt | 8 +++++++ .../moe/lava/banksia/di/PlatformModule.ios.kt | 18 +++++++++++++++- .../moe/lava/banksia/util/Logging.ios.kt | 7 +++++-- 8 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 composeApp/src/swift/spmMaplibre/StartYourBridgeHere.swift diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 02c6e0f..68df64c 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -1,5 +1,6 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import java.net.URI plugins { alias(libs.plugins.kotlinMultiplatform) @@ -8,6 +9,7 @@ plugins { alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeCompiler) alias(libs.plugins.secretsGradle) + alias(libs.plugins.spm) } kotlin { @@ -27,10 +29,17 @@ kotlin { iosArm64(), iosSimulatorArm64() ).forEach { iosTarget -> + iosTarget.compilations { + getByName("main") { + cinterops.create("spmMaplibre") + } + } iosTarget.binaries.framework { baseName = "ComposeApp" isStatic = true } +// iosTarget.swiftPackageConfig(cinteropName = "banksia") { +// } } sourceSets { @@ -109,3 +118,15 @@ compose.resources { publicResClass = true packageOfResClass = "moe.lava.banksia.resources" } + +swiftPackageConfig { + create("spmMaplibre") { + dependency { + remotePackageVersion( + url = URI("https://github.com/maplibre/maplibre-gl-native-distribution.git"), + products = { add("MapLibre") }, + version = "6.17.1", + ) + } + } +} diff --git a/composeApp/src/swift/spmMaplibre/StartYourBridgeHere.swift b/composeApp/src/swift/spmMaplibre/StartYourBridgeHere.swift new file mode 100644 index 0000000..d53c4d7 --- /dev/null +++ b/composeApp/src/swift/spmMaplibre/StartYourBridgeHere.swift @@ -0,0 +1,15 @@ +import Foundation +/** +This is a starting class to set up your bridge. +Ensure that your class is public and has the @objcMembers / @objc annotation. +This file has been created because the folder is empty. +Ignore this file if you don't need it or set "spmforkmp.disableStartupFile=true" inside your gradle file +**/ + +/** +@objcMembers public class StartHere: NSObject { + public override init() { + super.init() + } +} +**/ \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index f0cf36f..80feb8f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,3 +12,5 @@ android.useAndroidX=true #Ktor io.ktor.development=true + +kotlin.mpp.enableCInteropCommonization=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 638a098..b54a4eb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,9 +29,10 @@ material = "1.7.3" material3 = "1.11.0-alpha02" okio = "3.16.4" playServicesLocation = "21.3.0" -sqlite = "2.6.2" room = "2.8.4" secretsGradlePlugin = "2.0.1" +spm = "1.4.9" +sqlite = "2.6.2" wire = "5.5.0" [libraries] @@ -95,4 +96,5 @@ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ktor = { id = "io.ktor.plugin", version.ref = "ktor" } room = { id = "androidx.room", version.ref = "room" } secretsGradle = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin" } +spm = { id = "io.github.frankois944.spmForKmp", version.ref = "spm" } wire = { id = "com.squareup.wire", version.ref = "wire" } diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist index 412e378..22d2bc6 100644 --- a/iosApp/iosApp/Info.plist +++ b/iosApp/iosApp/Info.plist @@ -46,5 +46,7 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + NSLocationWhenInUseUsageDescription + This permission is required to display your current location diff --git a/shared/src/commonMain/kotlin/moe/lava/banksia/room/Database.kt b/shared/src/commonMain/kotlin/moe/lava/banksia/room/Database.kt index 163461a..0a5024d 100644 --- a/shared/src/commonMain/kotlin/moe/lava/banksia/room/Database.kt +++ b/shared/src/commonMain/kotlin/moe/lava/banksia/room/Database.kt @@ -1,7 +1,9 @@ package moe.lava.banksia.room import androidx.room.AutoMigration +import androidx.room.ConstructedBy import androidx.room.RoomDatabase +import androidx.room.RoomDatabaseConstructor import androidx.room.TypeConverters import androidx.sqlite.driver.bundled.BundledSQLiteDriver import kotlinx.coroutines.Dispatchers @@ -37,6 +39,7 @@ import androidx.room.Database as DatabaseAnnotation ] ) @TypeConverters(RouteTypeConverter::class) +@ConstructedBy(DatabaseConstructor::class) abstract class Database : RoomDatabase() { abstract val versionMetadataDao: VersionMetadataDao abstract val routeDao: RouteDao @@ -54,3 +57,8 @@ abstract class Database : RoomDatabase() { .build() } } + +@Suppress("KotlinNoActualForExpect") +expect object DatabaseConstructor : RoomDatabaseConstructor { + override fun initialize(): Database +} \ No newline at end of file diff --git a/shared/src/iosMain/kotlin/moe/lava/banksia/di/PlatformModule.ios.kt b/shared/src/iosMain/kotlin/moe/lava/banksia/di/PlatformModule.ios.kt index 8597856..d5f83a2 100644 --- a/shared/src/iosMain/kotlin/moe/lava/banksia/di/PlatformModule.ios.kt +++ b/shared/src/iosMain/kotlin/moe/lava/banksia/di/PlatformModule.ios.kt @@ -1,14 +1,30 @@ package moe.lava.banksia.di +import androidx.room.Room import androidx.room.RoomDatabase +import kotlinx.cinterop.ExperimentalForeignApi import moe.lava.banksia.room.Database import org.koin.core.parameter.ParametersHolder import org.koin.core.scope.Scope import org.koin.dsl.module +import platform.Foundation.NSDocumentDirectory +import platform.Foundation.NSFileManager +import platform.Foundation.NSUserDomainMask class IosDatabaseBuilder() : PlatformDatabaseBuilder { + @OptIn(ExperimentalForeignApi::class) override fun getBuilder(): RoomDatabase.Builder { - TODO("Not yet implemented") + val path = NSFileManager.defaultManager.URLForDirectory( + directory = NSDocumentDirectory, + inDomain = NSUserDomainMask, + appropriateForURL = null, + create = false, + error = null, + ) + val dbPath = path!!.path + "/room.db" + return Room.databaseBuilder( + name = dbPath + ) } } diff --git a/shared/src/iosMain/kotlin/moe/lava/banksia/util/Logging.ios.kt b/shared/src/iosMain/kotlin/moe/lava/banksia/util/Logging.ios.kt index b58b89a..c24034d 100644 --- a/shared/src/iosMain/kotlin/moe/lava/banksia/util/Logging.ios.kt +++ b/shared/src/iosMain/kotlin/moe/lava/banksia/util/Logging.ios.kt @@ -1,9 +1,12 @@ package moe.lava.banksia.util +import platform.Foundation.NSLog + +// TODO: use better logging functions maybe(?) actual fun log(tag: String, msg: String) { - TODO("Not yet implemented") + NSLog("$tag: $msg") } actual fun error(tag: String, msg: String, throwable: Throwable?) { - TODO("Not yet implemented") + NSLog("$tag: $msg: ${throwable?.stackTraceToString()}") }