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

KMM Compose如何实现共享模块与iOS原生的回调及结果返回?

KMM共享模块调用iOS原生后台操作并获取结果的解决方案

1. 定义共享模块的平台抽象接口

在commonMain目录下创建平台操作的抽象类/函数,用expect声明需要各平台实现的方法:

// commonMain/kotlin/[你的包名]/PlatformOperations.kt
import kotlinx.coroutines.suspendCancellableCoroutine

// 声明后台处理数据的挂起函数,适配异步操作
expect suspend fun processBackgroundData(input: String): String

// 可选:如果需要获取平台信息,也可以用expect/actual
expect fun getPlatform(): String

2. 实现Android端的具体逻辑

在androidMain目录下实现actual函数:

// androidMain/kotlin/[你的包名]/PlatformOperations.kt
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

actual suspend fun processBackgroundData(input: String): String {
    // 在IO线程执行后台操作,避免阻塞UI
    return withContext(Dispatchers.IO) {
        // 模拟耗时操作,替换为实际业务逻辑
        Thread.sleep(1000)
        "Android 处理结果: $input"
    }
}

actual fun getPlatform(): String = "Android"

3. 实现iOS端的原生逻辑

第一步:编写iOS原生Swift工具类

在iOS项目中创建Swift文件,实现后台操作的原生逻辑:

// iOS项目/PlatformHelpers.swift
import Foundation

@objc class PlatformHelpers: NSObject {
    // 后台队列执行操作,通过回调返回结果
    @objc static func processBackgroundData(_ input: String, completion: @escaping (String) -> Void) {
        DispatchQueue.global(qos: .background).async {
            // 模拟耗时操作,替换为实际iOS原生逻辑
            Thread.sleep(forTimeInterval: 1)
            let result = "iOS 处理结果: \(input)"
            // 切回主队列返回结果(如果需要更新UI,否则可直接调用completion)
            DispatchQueue.main.async {
                completion(result)
            }
        }
    }
    
    @objc static func getPlatform() -> String {
        return "iOS"
    }
}

第二步:在共享模块iosMain中对接原生代码

将Swift的回调风格代码转换为Kotlin协程,实现actual函数:

// iosMain/kotlin/[你的包名]/PlatformOperations.kt
import kotlinx.coroutines.suspendCancellableCoroutine

actual suspend fun processBackgroundData(input: String): String = suspendCancellableCoroutine { continuation ->
    PlatformHelpers.processBackgroundData(input) { result ->
        continuation.resume(result)
    }
}

actual fun getPlatform(): String = PlatformHelpers.getPlatform()

4. 修改共享模块UI组件调用逻辑

更新Compose组件,在协程作用域内调用后台操作函数:

@Composable
fun App() {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.SpaceAround
    ) {
        var counter by remember { mutableIntStateOf(0) }
        var processResult by remember { mutableStateOf<String?>(null) }

        Button(
            onClick = {
                counter++
                // 启动协程执行后台操作
                LaunchedEffect(counter) {
                    val result = processBackgroundData("来自 ${getPlatform()} 的请求")
                    processResult = result
                    android.util.Log.d("TAG", "处理结果: $result")
                }
            }
        ) {
            Text("触发后台操作")
        }

        Text("点击次数: $counter")
        processResult?.let {
            Text("后台返回结果: $it")
        }
    }
}

5. 简化iOS端UI层代码

移除原有的回调参数,直接初始化Compose视图:

import UIKit
import SwiftUI
import shared

struct ComposeView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        return Main_iosKt.MainViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

struct ContentView: View {
    var body: some View {
        ComposeView()
            .ignoresSafeArea(.all, edges: .bottom)
    }
}

关键注意点

  • 后台操作必须放在对应平台的后台线程执行,避免阻塞UI线程
  • 用Kotlin协程的suspendCancellableCoroutine将iOS的回调风格代码转为协程,适配共享模块的挂起函数
  • expect函数的签名必须与各平台actual函数完全一致
  • 如果需要处理取消逻辑,可在suspendCancellableCoroutine中添加continuation.invokeOnCancellation

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:30:33