预期解码 Dictionary<String, Any> 但找到一个数组而不是 JSON SwiftUI

Posted

技术标签:

【中文标题】预期解码 Dictionary<String, Any> 但找到一个数组而不是 JSON SwiftUI【英文标题】:Expected to decode Dictionary<String, Any> but found an array instead JSON SwiftUI 【发布时间】:2020-06-02 19:42:14 【问题描述】:

我在尝试使用 SwiftUI 解码 JSON 时遇到错误。

typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "platforms", intValue: nil)], debugDescription: "本应解码字典,但找到了一个数组。",underlyingError: nil))

我相信这与找到一个带有平台的空数组有关,但我试图弄清楚如何调用该信息,然后在内容视图中显示它。

我认为这是因为我在 getGames 网络服务中使用了字段,我可能搞砸了我拉取 API 的方式。我也不知道在哪里打印 JSON,所以我可以看到实际被拉取的内容。

我要解码的 JSON 是:


    "id": 22636,
    "name": "Call of Duty: Black Ops - Annihilation",
    "platforms": [
      
        "id": 6,
        "name": "PC (Microsoft Windows)"
      ,
      
        "id": 9,
        "name": "PlayStation 3"
      ,
      
        "id": 12,
        "name": "Xbox 360"
      
    ]

我的游戏结构看起来像:

Game.swift
struct Game: Codable, Identifiable 
    let id: Int
    let name: String
    let summary: String?
    let platforms: Platforms


struct Platforms: Codable, Identifiable 
    let id: Int
    let name: String


我的 Web 服务使用字段来仅获取 API 的特定部分:

GameService.swift
public class GameService: ObservableObject 

    @Published var games = [Game]()

    init()
        getGames()
    

    func getGames() 

        let parameters = "fields name, summary, platforms.name; where platforms = (48,6,49); limit 10;"
        let postData = parameters.data(using: .utf8)

        let url = URL(string: "https://api-v3.igdb.com/games/")!

        var request = URLRequest(url: url)
        request.addValue("HIDDEN", forHTTPHeaderField: "user-key")
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = postData

        URLSession.shared.dataTask(with: request)  data, response, error in
            do 
                if let d = data 
// DO I NEED TO ADJUST THE JSONDecoder to Array<Game>.self?
                    let decodedLists = try JSONDecoder().decode([Game].self, from: d)
                    DispatchQueue.main.async 
                        self.games = decodedLists
                    
                 else 
                    print("No data in response: \(error?.localizedDescription ?? "Unknown Error").")
                
             catch 
                print("\(error)")
            
        .resume()
    

【问题讨论】:

平台是一个数组。就这样更新吧:let platforms: [Platforms] @FrancescoDeliro 当我尝试得到一个 Xcode 错误时说类型 [Platforms] 没有成员“名称” 是的,因为现在您必须处理一个数组而不是单个值。你在哪里得到错误? @FrancescoDeliro 在视图中。文本(game.platforms.name) 我回答添加了一个例子。让我知道它是否适合你 【参考方案1】:

您在 JSON 中接收到一个平台数组,因此您必须更新您的 Game 结构才能解析它:

struct Game: Codable, Identifiable 
    let id: Int
    let name: String
    let summary: String?
    let platforms: [Platforms]

并使用它,例如:

List 
    ForEach(game.platforms)  platform in
        Text(platform.name)
    

【讨论】:

仍然获得类型 [platforms] 的值没有成员“名称”。 ``` VStack List(gamesList.games) VStack 中的游戏(对齐方式:.leading) Text(game.name) if game.summary != nil Text(game.summary ?? "No Game Summary") ForEach(game.platforms) platform in Text(platform.name) ``` 我观察到的对象是调用 GameService() 的 gamesList 您是否更新了所有使用 game.platforms.name 的地方? 我想通了。我的 Platforms Struct 外壳不在我的 Game 结构内。随时更新您的答案,我会将其标记为正确。谢谢你! 欢迎您@andywalt!好的!答案与您关于解析错误的问题有关:) 但您可以编辑您的问题,显示修复错误后如何处理数组!谢谢!

以上是关于预期解码 Dictionary<String, Any> 但找到一个数组而不是 JSON SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

类型不匹配。预期解码 Dictionary<String, Any> 但找到了一个数组

解码错误:“应解码 Dictionary<String, Any>,但找到了一个数组。”

Swift4 JSONDecoder 期望解码 Dictionary<String, Any> 但找到了一个数组 [重复]

SWIFT“应解码 Dictionary<String, Any>,但找到了一个数组。”,underlyingError: nil))

Swift Codable 期望解码 Dictionary<String, Any> 但找到了一个字符串/数据

错误:“应解码 Dictionary<String, Any>,但找到了一个数组。” ——但我还没有定义字典? [复制]