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

Swift 5解析指定JSON报错:期望数组却得字典,如何解决?

解决Swift JSONDecoder解码时的类型不匹配错误

问题原因

你遇到的错误逻辑很清晰:Expected to decode Array but found a dictionary instead.——你的JSON最外层是一个字典结构(对应Swift中的对象实例),但你直接尝试把它解码成[MyMovie].self(数组类型),两者类型完全不匹配,自然触发了崩溃。

先拆解下你的JSON层级结构,核心数组藏在内部:

{
  "id": "libMovies",
  "jsonrpc": "2.0",
  "result": {
    "limits": { ... },
    "movies": [ { ... } ] // 这才是你要的电影数组
  }
}

解决方案:构建匹配的层级模型

你需要从外到内创建对应JSON结构的Swift模型,而不是跳过外层直接解码电影数组。以下是完整的模型代码(注意属性类型要和JSON值严格匹配,比如movieid是整数,rating根据实际值用Double/Float):

// 根模型:对应整个JSON的最外层字典
struct MovieResponse: Codable {
    let id: String
    let jsonrpc: String
    let result: ResultData
}

// 对应result字段的子结构
struct ResultData: Codable {
    let limits: Limits
    let movies: [MyMovie]
}

// 对应limits字段的子结构
struct Limits: Codable {
    let end: Int
    let start: Int
    let total: Int
}

// 你的电影模型(补充完整层级)
struct MyMovie: Codable {
    let art: Art
    let file: String
    let label: String
    let movieid: Int
    let playcount: Int
    let rating: Double // 可根据实际JSON的rating类型调整为Float/Int
    let thumbnail: String
}

// 对应art字段的子结构
struct Art: Codable {
    let fanart: String
    let poster: String
}

正确的解码代码

现在需要先解码根模型,再从内部取出目标电影数组:

do {
    guard let data = data else {
        // 处理data为nil的异常情况
        return
    }
    let response = try JSONDecoder().decode(MovieResponse.self, from: data)
    let targetMovies = response.result.movies
    // 这里就可以正常使用电影数组了
    print("成功获取到\(targetMovies.count)部电影")
} catch {
    print("解码失败:\(error.localizedDescription)")
}

关键提醒

绝对不要用try!——它会在解码失败时直接导致App崩溃,就像你现在遇到的情况。一定要用do-catch块捕获并处理错误,既能提升App健壮性,也方便后续排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:47:36