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

PromiseKit从Swift2升级到Swift4后类型转换错误求助

问题分析与解决方案

我来帮你拆解下这个升级后遇到的问题——这本质是PromiseKit从适配Swift 2的旧版本升级到Swift 4对应的新版本(一般是v6.x及以上)时,API规则发生了重大变化导致的,核心是两个关键点:

1. Guarantee与Promise的类型边界变严格了

在Swift 2时代的PromiseKit中,代表「不会失败的异步操作」的Guarantee和代表「可能失败的异步操作」的Promise可以比较宽松地互相转换,但新版本里它们是独立的类型,无法隐式转换。

从你的代码看,MultiCache的get()方法大概率返回的是Guarantee(缓存读取操作通常不会抛出错误),那么when组合多个Guarantee后返回的是Guarantee<(T1, T2)>类型,但你的函数声明返回的是Promise<NSArray>,这就触发了类型不匹配的错误。

2. then与map的职责被明确拆分

旧版PromiseKit里,then既可以用来串联异步操作(返回新的Promise),也可以同步转换结果值;但新版本中:

  • then仅用于返回新的Promise/Guarantee的异步链式场景
  • 同步转换结果值需要用map方法

你当前的闭包是直接返回NSArray(同步计算的结果),用then就不符合新版本的API规则,这也是错误的诱因之一。


修改后的代码示例

针对你的代码,只需要做两处关键调整:

  1. 把then替换成map来处理同步值转换
  2. 如果函数必须返回Promise,就用.promise方法把Guarantee转换成Promise(或者直接把函数返回类型改成Guarantee<NSArray>,更贴合缓存操作的语义)
func getPlayerGameLog(sportName: String) -> Promise<NSArray> { 
    let team = (self as? PlayerWithPositionAndGame)?.team 
    let position = (self as? PlayerWithPositionAndGame)?.position 
    if sportName == "mlb" { 
        return when(fulfilled: Data.mlbPlayerGameLogs[id].get(), Data.sportsTeams[sportName].get())
            .map { (result, teams) -> NSArray in 
                if result.count == 0 { 
                    return [] 
                } else { 
                    // 你的业务处理代码
                    return gameStats 
                } 
            }
            .promise // 将Guarantee转换为Promise,匹配函数返回类型
    } else if sportName == "nfl" { 
        return when(fulfilled: Data.nflPlayerGameLogs[id].get(), Data.sportsTeams[sportName].get())
            .map { (result, teams) -> NSArray in 
                if result.count == 0 { 
                    return [] 
                } else { 
                    // 你的业务处理代码
                    return gameStats 
                } 
            }
            .promise
    } else { 
        return Data.nbaPlayerGameLogs[id].get()
            .map { gameLogs -> NSArray in 
                return [] 
            }
            .promise
    } 
} 

额外建议

  • 如果确认缓存操作不会失败,建议把函数返回类型改成Guarantee<NSArray>,这样可以去掉.promise转换,类型语义更准确。
  • 尽量把NSArray/NSDictionary替换成Swift原生的[Any]/[String: Any](或者更具体的模型类型),Swift 4+对原生集合类型的支持更好,类型安全性也更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:46:42