如何在iOS SwiftUI中调用KMM共享Kotlin代码的Flow获取用户信息?
KMM iOS SwiftUI 调用 Kotlin Flow<UserInfo?> 的实现方案
核心前提
Kotlin/Native会自动将Kotlin的Flow类型转换为iOS端Combine框架的AnyPublisher,因此我们可以基于Combine和SwiftUI的响应式机制实现和Android端一致的逻辑。
实现步骤
1. 编写ViewModel层逻辑
创建符合SwiftUI响应式要求的ViewModel,通过Combine订阅KMM共享层返回的流,并将数据同步到可观察的状态属性中:
import Combine import shared // 导入你的KMM共享模块 class UserViewModel: ObservableObject { // 可观察的用户信息状态,变化时自动通知UI刷新 @Published var userInfo: UserInfo? = nil // 管理订阅生命周期,避免内存泄漏 private var cancellables = Set<AnyCancellable>() // 注入KMM共享层的仓库实例 private let repo: YourSharedRepoType init(repo: YourSharedRepoType) { self.repo = repo } func getUserInfo() { // 调用KMM共享层的getUserProfile方法,接收转换后的Combine Publisher repo.getUserProfile() // 切换到主线程更新UI(SwiftUI状态更新必须在主线程) .receive(on: DispatchQueue.main) // 订阅流的事件 .sink( receiveCompletion: { completion in // 处理错误逻辑,对应Android端的catch if case .failure(let error) = completion { print("no User found: \(error.localizedDescription)") } }, receiveValue: { [weak self] user in // 更新用户信息状态 self?.userInfo = user } ) // 将订阅加入生命周期管理集合 .store(in: &cancellables) } }
2. UI层调用逻辑
在SwiftUI视图中使用@StateObject持有ViewModel,在视图出现时触发数据获取,并根据状态渲染UI:
struct UserProfileView: View { // 初始化ViewModel,这里假设仓库实例已提前准备好 @StateObject private var viewModel = UserViewModel(repo: YourSharedRepoInstance) var body: some View { VStack(spacing: 16) { if let user = viewModel.userInfo { // 渲染用户信息 Text("用户名: \(user.name ?? "未设置")") Text("邮箱: \(user.email ?? "未绑定")") } else { // 加载状态提示 ProgressView("加载用户信息中...") } } // 视图出现时触发数据获取 .onAppear { viewModel.getUserInfo() } } }
关键说明
@Published属性:ViewModel中的核心响应式属性,当值变化时会自动发送通知,驱动SwiftUI视图刷新。receive(on: DispatchQueue.main):强制将UI更新操作切换到主线程,符合SwiftUI的线程要求。- 订阅生命周期管理:
cancellables集合存储订阅对象,确保ViewModel销毁时自动取消订阅,避免内存泄漏。 - 错误处理:通过
sink的receiveCompletion闭包捕获错误,对应Android端Flow.catch的逻辑。
内容的提问来源于stack exchange,提问作者Cipri
相关产品推荐
相关产品推荐

