Skip to content

Commit

Permalink
Compose Swift Bridge changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kpgalligan committed Nov 6, 2024
1 parent 44b208e commit b984e1e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 3 deletions.
35 changes: 35 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
id("co.touchlab.skie") version "0.9.3"
id("com.google.devtools.ksp") version "2.0.21-1.0.26"
}

kotlin {
Expand Down Expand Up @@ -43,6 +46,7 @@ kotlin {
implementation(compose.components.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation("co.touchlab.compose:compose-swift-bridge:0.1.0")
}
}
}
Expand Down Expand Up @@ -76,5 +80,36 @@ android {

dependencies {
debugImplementation(compose.uiTooling)
dependencies {
val composeSwiftBridgeKsp = "co.touchlab.compose:compose-swift-bridge-ksp:0.1.0"
"kspCommonMainMetadata"(composeSwiftBridgeKsp) // Common Main generation required

// iOS targets
"kspIosSimulatorArm64"(composeSwiftBridgeKsp)
"kspIosArm64"(composeSwiftBridgeKsp)
"kspIosX64"(composeSwiftBridgeKsp)

// All targets your module support, here, is Android only as a example
"kspAndroid"(composeSwiftBridgeKsp)

// add the SKIE SubPlugin that will generate the Swift code
skieSubPlugin("co.touchlab.compose:compose-swift-bridge-skie:0.1.0")
}
}

// Adds the required targetName for the KSP plugin
tasks.withType<com.google.devtools.ksp.gradle.KspTaskNative>().configureEach {
options.add(SubpluginOption("apoption", "compose-swift-bridge.targetName=$target"))
}

// support for generating ksp code in commonCode
// see https://github.com/google/ksp/issues/567
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
if (name != "kspCommonMainKotlinMetadata") {
dependsOn("kspCommonMainKotlinMetadata")
}
}

kotlin.sourceSets.commonMain {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kgalligan.mapview

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign

@Composable
actual fun ShowNativeText(modifier: Modifier, someText: SomeText) {
Text(modifier = modifier, textAlign = TextAlign.Center, text = someText.s)
}
16 changes: 15 additions & 1 deletion composeApp/src/commonMain/kotlin/com/kgalligan/mapview/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import co.touchlab.compose.swift.bridge.ExpectSwiftView
import co.touchlab.compose.swift.bridge.ViewType
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.ui.tooling.preview.Preview

Expand All @@ -25,6 +29,8 @@ fun App() {
Button(onClick = { showContent = !showContent }) {
Text("Click me!")
}
ShowNativeText(Modifier.fillMaxWidth()
.height(30.dp), SomeText("I'm a native view!"))
AnimatedVisibility(showContent) {
val greeting = remember { Greeting().greet() }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Expand All @@ -34,4 +40,12 @@ fun App() {
}
}
}
}
}

data class SomeText(val s:String)

@ExpectSwiftView(
type = ViewType.SwiftUI
)
@Composable
expect fun ShowNativeText(modifier: Modifier = Modifier, someText: SomeText)
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
@file:Suppress("unused", "FunctionName")

package com.kgalligan.mapview

import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.window.ComposeUIViewController
import co.touchlab.compose.swift.bridge.ComposeNativeViewFactory
import co.touchlab.compose.swift.bridge.LocalNativeViewFactory
import platform.UIKit.UIViewController

fun MainViewController() = ComposeUIViewController { App() }
fun MainViewController(
generatedViewFactory: ComposeNativeViewFactory
): UIViewController = ComposeUIViewController {
CompositionLocalProvider(
LocalNativeViewFactory provides generatedViewFactory,
) {
App()
}
}
16 changes: 15 additions & 1 deletion iosApp/iosApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ComposeApp

struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
MainViewController(generatedViewFactory: SwiftUINativeViewFactory())
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
Expand All @@ -17,5 +17,19 @@ struct ContentView: View {
}
}

class SwiftUINativeViewFactory : NativeViewFactory {
func createShowNativeText(observable: ComposeApp.ShowNativeTextObservable) -> AnyView {
return AnyView(SimpleTextView(observable: observable))
}
}

struct SimpleTextView : View {
@ObservedObject var observable: ComposeApp.ShowNativeTextObservable

var body: some View {
Text(observable.someText.s)
.padding()
}
}


0 comments on commit b984e1e

Please sign in to comment.