首页 > 解决方案 > JSON 无法使用 Codable 解析

问题描述

我正在尝试解析这个 json 字符串:

let jsonString  = """
{
  "items": [
    {
      "snippet": {
        "publishedAt": "2020-05-20T16:00:23Z",
        "title": "Lesson 2 - One Day Build",
        "description": "Description for Lesson 2",
        "thumbnails": {
          "high": {
            "url": "https://i.ytimg.com/vi/PvvwZW-dRwg/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/PvvwZW-dRwg/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "resourceId": {
          "videoId": "PvvwZW-dRwg"
        }
      }
    },
    {
      "snippet": {
        "publishedAt": "2020-05-26T16:00:23Z",
        "title": "Lesson 3 - One Day Build",
        "description": "Description for Lesson 3",
        "thumbnails": {
          "high": {
            "url": "https://i.ytimg.com/vi/m3XbTkMZMPE/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/m3XbTkMZMPE/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "resourceId": {
          "videoId": "m3XbTkMZMPE"
        }
      }
    }
  ]
}
"""

我创建了这些结构(来自 QuickType):

// MARK: - Welcome
struct Welcome: Codable {
    let items: Item
}

// MARK: - Item
struct Item: Codable {
    let snippet: Snippet
}

// MARK: - Snippet
struct Snippet: Codable {
    let publishedAt: Date
    let title, snippetDescription: String
    let thumbnails: Thumbnails
    let resourceID: ResourceID
}

// MARK: - ResourceID
struct ResourceID: Codable {
    let videoID: String
}

// MARK: - Thumbnails
struct Thumbnails: Codable {
    let high, maxres: High
}

// MARK: - High
struct High: Codable {
    let url: String
    let width, height: Int
}

我正在调用这个函数:

func ParseJson() {

    // Array for  the list of video objects
    var videos = [Video]()

    if let jsonData = jsonString.data(using: .utf8) {
        let decoder = JSONDecoder()
        
        do {
            let parsedJson = try decoder.decode(Welcome.self, from: jsonData)
            print("here")
        } catch {
            print(error.localizedDescription)
        }
      
      // Output the contents of the array
      dump(videos)
    } else {
      print("Error, unable to parse JSON")
    }
}

根据我找到的教程和在线资源,只要这里的结构正确,我应该可以将json字符串解码为结构。输出始终是来自 catch 语句的“操作无法完成”。任何帮助表示赞赏。

谢谢

标签: jsonswiftcodable

解决方案


您的代码中有一堆错误:

  • Welcome.items是一个Items 的数组,而不仅仅是一个。
  • Snippet.publishedAt是 ISO 8601 格式,所以你需要相应地设置dateDecodingStrategy解码器的。
  • 按键拼写错误:
    • description, 不是snippetDescription
    • resourceId, 不是resouceID
    • videoId, 不是videoID

这是更新的结构和解码代码:

// MARK: - Welcome
struct Welcome: Codable {
    let items: [Item]
}

// MARK: - Item
struct Item: Codable {
    let snippet: Snippet
}

// MARK: - Snippet
struct Snippet: Codable {
    let publishedAt: Date
    let title, description: String
    let thumbnails: Thumbnails
    let resourceId: ResourceID
}

// MARK: - ResourceID
struct ResourceID: Codable {
    let videoId: String
}

// MARK: - Thumbnails
struct Thumbnails: Codable {
    let high, maxres: High
}

// MARK: - High
struct High: Codable {
    let url: String
    let width, height: Int
}

if let jsonData = jsonString.data(using: .utf8) {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    do {
        let parsedJson = try decoder.decode(Welcome.self, from: jsonData)
        print("here")
    } catch {
        print(error)
    }
} else {
  print("Error, unable to parse JSON")
}

推荐阅读