建模“对象”类型以解码JSON

时间:2018-05-02 22:03:55

标签: ios json swift model

我正在向Apple Music API发送多个calls,它返回一组Resource个对象。 Resource对象有一个名为object类型属性的属性,具体取决于它是SongPlaylist还是Album

如何为资源对象建模,以便解码JSON并创建歌曲,播放列表和专辑对象?

struct Resource {
    let id : String?
    let type : String?
    let href : String?
    let attributes : "What goes here?"
}

更新1:

我尝试了Joe的第二个建议并设置了我的结构:

struct Resource: Decodable{

    enum Attribute {
        case song(Song), playlist(Playlist)
    }

    let id : String?
    let type : String?
    let href : String?
    let attributes: Attribute?

    enum CodingKeys : CodingKey{
        case id, type, href, attributes
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(String.self, forKey: .id)
        type = try values.decode(String.self, forKey: .type)
        href = try values.decode(String.self, forKey: .href)
        switch type {
        case "library-songs":
            attributes = try .song(values.decode(Song.self, forKey: .attributes))
        case "library-playlists":
            attributes = try .playlist(values.decode(Playlist.self, forKey: .attributes))
        default:
            attributes = nil
        }
    }
}

struct Song : Decodable {
    let playParams : PlayParams?
    let trackNumber : Int?
    let durationInMillis : Int?
    let name : String?
    let albumName : String?
    let artwork : Artwork?
    let contentRating : String?
    let artistName : String?
}

struct Artwork : Decodable {
    let width : Int?
    let height : Int?
    let url : String?
}
struct PlayParams : Decodable {
    let id : String?
    let kind : String?
    let isLibrary : Bool?
}

示例JSON对于歌曲来说是这样的:

{
  "data": [
    {
      "id": "i.4YBNbl3IXVJQRM",
      "type": "library-songs",
      "href": "/v1/me/library/songs/i.4YBNbl3IXVJQRM",
      "attributes": {
        "albumName": "\"Awaken, My Love!\"",
        "artwork": {
          "width": 1200,
          "height": 1200,
          "url": "https://is5-ssl.mzstatic.com/image/thumb/Music71/v4/00/d0/d7/00d0d743-b0de-31d8-09eb-0796269bb555/UMG_cvrart_00044003187658_01_RGB72_1800x1800_16UMGIM77118.jpg/{w}x{h}bb.jpg"
        },
        "durationInMillis": 326933,
        "playParams": {
          "id": "i.4YBNbl3IXVJQRM",
          "kind": "song",
          "isLibrary": true
        },
        "artistName": "Childish Gambino",
        "trackNumber": 6,
        "name": "Redbone",
        "contentRating": "explicit"
      }
    },
    {
      "id": "i.mmpeOrZiLqoKOv",
      "type": "library-songs",
      "href": "/v1/me/library/songs/i.mmpeOrZiLqoKOv",
      "attributes": {
        "albumName": "Funk Wav Bounces Vol. 1",
        "artwork": {
          "width": 1200,
          "height": 1200,
          "url": "https://is5-ssl.mzstatic.com/image/thumb/Music127/v4/8b/37/23/8b372308-f764-d03a-5bda-a7a456292547/886446469607.jpg/{w}x{h}bb.jpg"
        },
        "durationInMillis": 272659,
        "playParams": {
          "id": "i.mmpeOrZiLqoKOv",
          "kind": "song",
          "isLibrary": true
        },
        "artistName": "Calvin Harris",
        "trackNumber": 4,
        "name": "Rollin (feat. Future & Khalid)",
        "contentRating": "explicit"
      }
    },
    {
      "id": "i.JL1aVxNtzmYDJG",
      "type": "library-songs",
      "href": "/v1/me/library/songs/i.JL1aVxNtzmYDJG",
      "attributes": {
        "albumName": "The Weekend (Funk Wav Remix) - Single",
        "artwork": {
          "width": 1200,
          "height": 1200,
          "url": "https://is4-ssl.mzstatic.com/image/thumb/Music118/v4/aa/d5/e5/aad5e5e3-dff5-7d8f-5747-b695ad9f2299/886446852157.jpg/{w}x{h}bb.jpg"
        },
        "durationInMillis": 171806,
        "playParams": {
          "id": "i.JL1aVxNtzmYDJG",
          "kind": "song",
          "isLibrary": true
        },
        "artistName": "SZA & Calvin Harris",
        "trackNumber": 1,
        "name": "The Weekend (Funk Wav Remix)"
      }
    }
  ]
}

使用以下方法解码数据时

      let resource = try? JSONDecoder().decode([Resource].self, from: data!)
    print(resource!)

我收到致命错误:在解开可选值时意外发现nil

更新2:

我想出了这个问题。顶部的额外层正在搞砸解码。我添加了另一个级别:

struct Welcome: Codable {
    let data: [Datum]
}

struct Datum: Codable {
    let id, type, href: String
    let attributes: Attributes
}

struct Attributes: Codable {
    let albumName: String
    let artwork: Artwork
    let durationInMillis: Int
    let playParams: PlayParams
    let artistName: String
    let trackNumber: Int
    let name: String
    let contentRating: String?
}

struct Artwork: Codable {
    let width, height: Int
    let url: String
}

struct PlayParams: Codable {
    let id, kind: String
    let isLibrary: Bool
}

这适用于歌曲,但我会尝试重新实现歌曲和播放列表。

0 个答案:

没有答案