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

Swift返回JSON数据遇[Plant]转Plant类型错误的解决求助

解决“Cannot convert return expression of type '[Plant]' to return type 'Plant'”错误

问题核心

你遇到的类型不匹配错误,本质是API返回的是Plant数组(对应PlantResponse里的data: [Plant]),但你把网络请求函数的返回类型声明为单个Plant,同时UI状态变量也用了单个Plant?,完全不匹配。另外你的Plant结构体里还有一个多余字段,会直接导致解码失败。

修复步骤

1. 移除Plant结构体的错误字段

你的Plant结构体里定义了let Plant: [Plant],这是完全错误的——API返回的单个Plant对象中不存在该字段,会引发解码失败,直接删除这一行:

struct Plant: Codable {
    let id: Int
    let commonName: String
    let slug: String
    let scientificName: String
    let year: Int
    let bibliography: String
    let author: String
    let status: String
    let rank: String
    let familyCommonName: String
    let family: String
    let genusId: Int
    let genus: String
    let imageUrl: String
    let synonyms: [String]
    let links: Links
    // 删除此行:let Plant: [Plant]
}

2. 修改网络请求函数的返回类型

将fetchPlantsFromAPI的返回类型从Plant改为[Plant],匹配API返回的数组结构:

func fetchPlantsFromAPI() async throws -> [Plant] {
    // 注意:URL中?和token之间的空格要删除,否则URL无效
    let url = URL(string: "https://trefle.io/api/v1/plants?token=d321f518jTdU1t-doZQif3jpzzW9V0mk3nLnDssF1vY&filter[common_name]=beach%20strawberry")!
    do {
        let (data, _) = try await URLSession.shared.data(from: url)

        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        // 替换try!为try,避免强制解包引发崩溃
        let decoded = try decoder.decode(PlantResponse.self, from: data)
        print(decoded.data)
        return decoded.data // 现在返回的数组与函数返回类型完全匹配
    } catch {
        throw error
    }
}

3. 更新UI的状态变量与显示逻辑

把ContentView中的单个Plant?状态变量改为数组类型,并适配数组的显示逻辑:

struct ContentView: View {
    // 改为数组类型,初始化为空数组
    @State var plants: [Plant] = []
    
    var body: some View {
        VStack(alignment: .leading) {
            if !plants.isEmpty {
                Text("共加载到 \(plants.count) 种植物")
                    .font(.title)
                // 示例:显示第一个植物的名称
                Text("第一个植物:\(plants[0].commonName)")
                    .font(.subheadline)
            } else {
                Text("No data available")
            }
        }
        .padding(20.0)
        .task {
            do {
                plants = try await fetchPlantsFromAPI()
            } catch {
                plants = []
                print("加载失败:\(error.localizedDescription)")
            }
        }
    }
}

4. 额外注意事项

  • 禁止使用try!强制解包,改用try配合do-catch处理错误,避免程序崩溃;
  • 确保URL格式正确,删除参数之间的无效空格;
  • 若API可能返回空数组,需在UI中处理空数组的显示逻辑(上述代码已覆盖)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:07:38