Aki*_*ala 3 kotlin swift kotlin-multiplatform swiftui
我有一个带有 MutableStateFlow 的 KmmShared 单例类,它可以在 Android 上正常工作。我需要知道访问此 Singleton 类及其 MutableStateFlow 变量的最佳方法,并在 SwiftUI 应用程序中进行更新。
class MySingeltonClass {
private val _selectedType: MutableStateFlow<MyEnum> = MutableStateFlow(getUserPrefsType())
var selectedType = _selectedType.asStateFlow()
private fun getUserPrefsType() : MyEnum {
// Get Enum from DB
}
fun setType(scheme: MyEnum) {
// Set Enum in DB
_selectedType.value = scheme
}
companion object {
private lateinit var instance: MySingeltonClass
fun getInstance(): MySingeltonClass {
if (!this::instance.isInitialized) {
instance = MySingeltonClass()
}
return instance
}
}
}
enum class MyEnum {
TYPEA, TYPEB, TYPEC;
}
Run Code Online (Sandbox Code Playgroud)
如果我可以有MySingeltonWrapperClass
a@Published var selectedType
或 a@ObservedObject private var selectedType
是我试图在 Swift 中实现的目标。
这是一个有点棘手的话题。Flow
SwiftUI 应用程序中/的主要问题StateFlow
在于 Kotlin <-> Swift 互操作性。因为它有几个限制:
CoroutineScope
才能取消作业有几种解决方法可用:
Flow
用 Kotlin封装class
。您可以在官方 KMM 示例存储库中找到此技术的绝佳示例。首先,作者介绍了新的类 CFlow
:
fun interface Closeable {
fun close()
}
class CFlow<T: Any> internal constructor(private val origin: Flow<T>) : Flow<T> by origin {
fun watch(block: (T) -> Unit): Closeable {
val job = Job()
onEach {
block(it)
}.launchIn(CoroutineScope(Dispatchers.Main + job))
return Closeable { job.cancel() }
}
}
internal fun <T: Any> Flow<T>.wrap(): CFlow<T> = CFlow(this)
Run Code Online (Sandbox Code Playgroud)
class ObservableFeedStore: ObservableObject {
@Published public var state: FeedState = FeedState(progress: false, feeds: [], selectedFeed: nil)
var stateWatcher : Closeable?
init(store: FeedStore) {
stateWatcher = self.store.watchState().watch { [weak self] state in
self?.state = state
}
}
deinit {
stateWatcher?.close()
}
}
Run Code Online (Sandbox Code Playgroud)
当你设置这个库时,你可以AnyPublisher
为你的 Kotlin Flow
/创建 Swift StateFlow
:
let publisher = createPublisher(for: yourFlow)
Run Code Online (Sandbox Code Playgroud)
Flow
/ StateFlow
。您可以使用简单的替代方案。看一下Decompose 项目及其Value
类。abstract class Value<out T : Any> {
abstract val value: T
abstract fun subscribe(observer: (T) -> Unit)
abstract fun unsubscribe(observer: (T) -> Unit)
}
Run Code Online (Sandbox Code Playgroud)
您仍然可以非常轻松地在 Compose 应用程序中使用它来从 Decompose 中State
获取样本:
@Composable
fun <T : Any> Value<T>.subscribeAsState(policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()): State<T> {
val state = remember(this, policy) { mutableStateOf(value, policy) }
DisposableEffect(this) {
val observer: (T) -> Unit = { state.value = it }
subscribe(observer)
onDispose {
unsubscribe(observer)
}
}
return state
}
Run Code Online (Sandbox Code Playgroud)
在 SwiftUI 中,您可以使用ObservableValue
Decompose 的助手:
public class ObservableValue<T : AnyObject> : ObservableObject {
private let observableValue: Value<T>
@Published
var value: T
private var observer: ((T) -> Void)?
init(_ value: Value<T>) {
observableValue = value
self.value = observableValue.value
observer = { [weak self] value in self?.value = value }
observableValue.subscribe(observer: observer!)
}
deinit {
observableValue.unsubscribe(observer: self.observer!)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
948 次 |
最近记录: |