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

在SwiftUI中解析Kotlin Multiplatform的Result对象

KMM中SwiftUI端处理自定义Result密封类的解决方案

问题背景

在Kotlin多平台(KMM)项目的共享模块中,定义了如下密封类作为Ktor API请求的返回值:

sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val errorMessage: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

该类在Kotlin中可通过when语句正常解析,但在SwiftUI中使用switch处理时,出现“Reference to member 'success' cannot be resolved without contextual type.”错误,Error和Loading状态也存在同类问题。

用户的Swift错误代码如下:

func searchCounts() async {
  do {
     let result = try await searchAPI.getSearchResponse()
     print(result.self)
      switch result {
          case .success(let searchResponse): // Error Message
             self.counts = searchResponse
           case .failure(let error):  // Error Message
                print("Error: \(error.localizedDescription)")
           case .loading():  // Error Message
                print("Error:")
                    }
        } catch {
            print("Error: \(error)")
        }
    }

项目整体方案可行,SwiftUI中能打印API请求的JSON内容,但无法正确处理Success、Error、Loading三种状态。

正确处理方式

Kotlin密封类在Swift中会被映射为带关联类型的枚举,需注意命名和语法差异,具体修正步骤如下:

  1. 遵循Kotlin到Swift的命名映射规则

    • Kotlin的Success数据类在Swift中对应.success(首字母自动小写)
    • Error数据类对应.error
    • Loading单例对象对应.loading(无参数)
  2. 添加类型注解(可选但推荐)
    给result添加明确的类型注解,帮助Swift编译器推断类型,避免上下文类型错误:

    let result: Result<SearchResponse> = try await searchAPI.getSearchResponse()
    

    其中SearchResponse是你的API返回的具体数据类型。

  3. 修正switch语句语法
    针对自定义Result类的三个状态,正确的Swift switch写法如下:

    func searchCounts() async {
        do {
            let result = try await searchAPI.getSearchResponse()
            
            switch result {
            case .success(let data):
                // 处理成功数据,data对应Kotlin中Success的data字段
                self.counts = data
            case .error(let errorMessage):
                // 处理业务错误,errorMessage对应Kotlin中Error的errorMessage字段
                print("Error: \(errorMessage)")
            case .loading:
                // 处理加载状态,Loading是单例无关联值
                print("Loading...")
            }
        } catch {
            // 捕获网络请求层面的异常(如连接失败、序列化错误),与Result.Error区分开
            print("Request failed: \(error.localizedDescription)")
        }
    }
    
  4. 区分两类错误场景

    • do-catch块捕获的是网络请求过程中的系统异常
    • switch中的.error是Kotlin代码主动返回的业务逻辑错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:54:53