代码之家  ›  专栏  ›  技术社区  ›  Tony Merritt

解析JSON、iOS、Swift4

  •  -1
  • Tony Merritt  · 技术社区  · 6 年前

    我正试图解析一些json,但输出似乎为零。

    我不知道我错在哪里,我需要一些帮助来解决这个问题。

    struct albumInfo: Decodable {
    var name: String?
    var artist: String?
    var url: String?
    var playcount: String?
    var listeners: String?
    var releasedate: String?
    var summary: String?
    }   
    
    
    class SearchVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
        Choice = "album"
        Album = "Believe"
        Artist = "Cher"
    
        let tryURL = "\(BASE_URL)\(Choice!).getinfo&api_key=\(API_KEY)&artist=\(Artist!)&album=\(Album!)&format=json"
        print(tryURL)
    
        guard let url = URL(string: tryURL) else { return }
    
    
        URLSession.shared.dataTask(with: url) { (data, response, err) in
    
            guard let data = data else { return }
    
                do {
                let albumDescription = try JSONDecoder().decode(albumInfo.self, from: data)
    
                    print(albumDescription.artist)
    
                }catch let jsonErr {
                    print("Error seroalizing json", jsonErr)
            }
        }.resume()
    
    }
    

    这是tryUrl显示的数据。

    enter image description here

    3 回复  |  直到 6 年前
        1
  •  1
  •   vadian    6 年前

    首先,请遵循结构名称以大写字母开头的命名约定。

    主要有两个问题:

    1. 根对象是一个只有一个键的字典 album 包含带键的字典 name , listeners 等。
    2. 钥匙 summary 在另一本字典里找钥匙 wiki

    JSON的结构非常容易识别。每对牙套内的身体( {} )表示单独的结构。

    再远一点没有钥匙 releasedate let ). url 可以声明为 URL

    将结构更改为

    struct Root : Decodable {
        let album : AlbumInfo
    }
    
    struct AlbumInfo: Decodable {
        let name: String
        let artist: String
        let url: URL
        let playcount: String
        let listeners: String
        let releasedate: String?
        let wiki : Wiki
    }   
    
    struct Wiki: Decodable {
        let content: String     
        let published: String
        let summary: String
    }
    

    然后解码 Root

    let albumDescription = try JSONDecoder().decode(Root.self, from: data)
    print(albumDescription.album.artist)
    
        2
  •  0
  •   Daniel Amarante    6 年前

        3
  •  0
  •   Dandelion    6 年前

    这些类与json不对应,我想您应该使用以下方法(新类实现您的解码、编码协议):

    class JsonInfo {
    var album : albumInfo
    }
    
    do {
    let albumDescription = try JSONDecoder().decode(albumInfo.self, from: data)
    
    print(albumDescription.album.artist)
    
    }catch let jsonErr {
    print("Error seroalizing json", jsonErr)
    }