Skip to content

Commit b98ff39

Browse files
committed
Add UnitEmitter
1 parent 9bc7de3 commit b98ff39

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

Demo/app/src/main/java/com/pureswift/swiftandroid/MainActivity.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,41 @@ import android.os.Bundle
44
import android.util.Log
55
import android.view.View
66
import androidx.activity.ComponentActivity
7+
import androidx.activity.compose.setContent
8+
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.Spacer
11+
import androidx.compose.foundation.layout.fillMaxSize
12+
import androidx.compose.foundation.layout.width
13+
import androidx.compose.material3.Text
14+
import androidx.compose.runtime.Composable
15+
import androidx.compose.runtime.LaunchedEffect
16+
import androidx.compose.runtime.collectAsState
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.runtime.setValue
21+
import androidx.compose.ui.Alignment
22+
import androidx.compose.ui.Modifier
23+
import java.util.Date
724

825
class MainActivity : ComponentActivity() {
926

1027
init {
1128
NativeLibrary.shared()
1229
}
1330

31+
val emitter = UnitEmitter()
32+
1433
override fun onCreate(savedInstanceState: Bundle?) {
1534
super.onCreate(savedInstanceState)
1635
onCreateSwift(savedInstanceState)
1736
//enableEdgeToEdge()
37+
38+
// set composable root view
39+
setContent {
40+
EventReceiver(emitter = emitter)
41+
}
1842
}
1943

2044
external fun onCreateSwift(savedInstanceState: Bundle?)
@@ -24,3 +48,29 @@ class MainActivity : ComponentActivity() {
2448
setContentView(view)
2549
}
2650
}
51+
52+
@Composable
53+
fun EventReceiver(emitter: UnitEmitter) {
54+
55+
val tick by emitter.flow.collectAsState(initial = Unit)
56+
57+
var date by remember { mutableStateOf(Date()) }
58+
59+
LaunchedEffect(Unit) {
60+
emitter.flow.collect {
61+
date = Date()
62+
}
63+
}
64+
65+
Box(
66+
modifier = Modifier.fillMaxSize(),
67+
contentAlignment = Alignment.Center
68+
) {
69+
Column(
70+
horizontalAlignment = Alignment.CenterHorizontally
71+
) {
72+
Text("Hello Swift!")
73+
Text(date.toString())
74+
}
75+
}
76+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.pureswift.swiftandroid
2+
3+
import kotlinx.coroutines.flow.MutableSharedFlow
4+
import kotlinx.coroutines.flow.SharedFlow
5+
6+
class UnitEmitter() {
7+
8+
private val _flow = MutableSharedFlow<Unit>(extraBufferCapacity = 64)
9+
val flow: SharedFlow<Unit> get() = _flow
10+
11+
fun emit() {
12+
//println("Emit")
13+
_flow.tryEmit(Unit)
14+
}
15+
}

Demo/app/src/main/swift/MainActivity.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ open class MainActivity: AndroidApp.Activity {
1616
@JavaMethod
1717
open func setRootView(_ view: AndroidView.View?)
1818

19+
@JavaMethod
20+
open func getEmitter() -> UnitEmitter!
21+
1922
static private(set) var shared: MainActivity!
2023

2124
lazy var textView = TextView(self)
@@ -25,6 +28,8 @@ open class MainActivity: AndroidApp.Activity {
2528
lazy var recyclerView = RecyclerView(self)
2629

2730
lazy var button = AndroidWidget.Button(self)
31+
32+
lazy var emitter = getEmitter()!
2833

2934
lazy var rootViewID: Int32 = try! JavaClass<AndroidView.View>().generateViewId()
3035
}
@@ -56,7 +61,8 @@ private extension MainActivity {
5661
}
5762

5863
// need to recreate views
59-
setRootView()
64+
//setRootView()
65+
startEmitterTimer()
6066

6167
Task {
6268
printBinderVersion()
@@ -105,6 +111,22 @@ private extension MainActivity {
105111
}
106112
}
107113

114+
func startEmitterTimer() {
115+
// update view on timer
116+
Task { [weak self] in
117+
while let self {
118+
emit()
119+
try? await Task.sleep(for: .seconds(1))
120+
}
121+
}
122+
}
123+
124+
@MainActor
125+
func emit() {
126+
Self.log("\(self).\(#function)")
127+
emitter.emit()
128+
}
129+
108130
func setupNavigationStack() {
109131

110132
let fragmentContainer = FrameLayout(self)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// UnitEmitter.swift
3+
// SwiftAndroidApp
4+
//
5+
// Created by Alsey Coleman Miller on 7/13/25.
6+
//
7+
8+
import JavaKit
9+
10+
/// Bridge from Swift to Kotlin Coroutines
11+
@JavaClass("com.pureswift.swiftandroid.UnitEmitter")
12+
open class UnitEmitter: JavaObject {
13+
14+
@JavaMethod
15+
@_nonoverride public convenience init(environment: JNIEnvironment? = nil)
16+
17+
@JavaMethod
18+
func emit()
19+
}

0 commit comments

Comments
 (0)