You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中访问KMM共享的MutableStateFlow单例对象

在SwiftUI中访问KMM单例的StateFlow并接收更新

核心思路

Kotlin的StateFlow在iOS端会被转换为NativeFlow,我们需要将其包装成SwiftUI可识别的可观察对象,通过@Published结合ObservableObject实现UI自动响应状态变化。

步骤1:实现Swift单例Wrapper类

创建一个遵循ObservableObject的Swift单例类,内部持有KMM单例实例,将StateFlow的变化同步到@Published属性中。

代码实现

import Combine
import shared // 导入你的KMM共享模块

class MySingletonWrapper: ObservableObject {
    // Swift端线程安全的单例实例
    static let shared = MySingletonWrapper()
    
    // 管理Flow订阅的生命周期
    private var cancellables = Set<AnyCancellable>()
    
    // 供SwiftUI监听的属性,变化时自动触发UI更新
    @Published var selectedType: MyEnum
    
    private let kmmSingleton: MySingeltonClass
    
    private init() {
        // 获取KMM侧的单例实例
        kmmSingleton = MySingeltonClass.getInstance()
        
        // 初始化当前选中类型的初始值
        selectedType = kmmSingleton.selectedType.value
        
        // 订阅StateFlow的变化,同步到@Published属性
        kmmSingleton.selectedType
            .receive(on: DispatchQueue.main) // 切换到主线程更新UI
            .sink { [weak self] newType in
                self?.selectedType = newType
            }
            .store(in: &cancellables)
    }
    
    // 转发设置类型的方法到KMM单例
    func setType(_ scheme: MyEnum) {
        kmmSingleton.setType(scheme: scheme)
    }
}

步骤2:在SwiftUI视图中使用Wrapper

在SwiftUI视图里,通过@StateObject(单例场景下优先使用,保证生命周期稳定)持有Wrapper实例,直接绑定属性即可自动响应状态变化。

示例视图代码

import SwiftUI

struct ContentView: View {
    // 持有Wrapper单例,跟随视图生命周期管理
    @StateObject private var singletonWrapper = MySingletonWrapper.shared
    
    var body: some View {
        VStack(spacing: 20) {
            Text("当前选择类型: \(singletonWrapper.selectedType.rawValue)")
            
            Button("切换到TYPEA") {
                singletonWrapper.setType(.TYPEA)
            }
            
            Button("切换到TYPEB") {
                singletonWrapper.setType(.TYPEB)
            }
            
            Button("切换到TYPEC") {
                singletonWrapper.setType(.TYPEC)
            }
        }
        .padding()
    }
}

关键细节说明

  • 线程切换:必须通过receive(on: DispatchQueue.main)将Flow事件切换到主线程,否则SwiftUI更新UI时会出现线程异常。
  • 内存安全:订阅时使用[weak self]避免循环引用,即使是单例也保持良好的编码习惯。
  • 初始值同步:在Wrapper初始化时先获取StateFlow的当前值,确保UI初始状态与KMM侧一致。
  • 单例一致性:Swift侧Wrapper的单例实现与KMM侧逻辑对应,保证全局唯一实例。

内容的提问来源于stack exchange,提问作者ajw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:42:50