post Image
[iOS][Swift 4] CodableでJSONのパース

Swift 4からCodableが追加されて、JSONのパースが簡単になった。

Encoding and Decoding Custom Types

以下のようなJSONをパースする場合
https://rss.itunes.apple.com/api/v1/us/apple-music/new-music/2/explicit.json
※URLはRSS Feed Generatorで生成

{
    "feed":{
        "title":"New Releases",
        "id":"https://rss.itunes.apple.com/api/v1/us/apple-music/new-music/2/explicit.json",
        "author":{
            "name":"iTunes Store",
            "uri":"http://wwww.apple.com/us/itunes/"
        },
        "links":[
            {"self":"https://rss.itunes.apple.com/api/v1/us/apple-music/new-music/2/explicit.json"},
            {"alternate":"https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=976405703"}
        ],
        "copyright":"Copyright © 2017 Apple Inc. All Rights Reserved.",
        "country":"us",
        "icon":"http://itunes.apple.com/favicon.ico",
        "updated":"2017-08-12T01:30:53.000-07:00",
        "results":[
            {
                "artistId":"991187319",
                "artistName":"Moneybagg Yo",
                "artistUrl":"https://itunes.apple.com/us/artist/moneybagg-yo/id991187319",
                "artworkUrl100":"http://is1.mzstatic.com/image/thumb/Music118/v4/28/25/c8/2825c846-e976-bd16-2fbf-f5bdf3334877/source/200x200bb.png",
                "copyright":"℗ 2017 N-Less Entertainment, LLC distributed by Interscope Records",
                "genres":[
                    {
                        "genreId":"18",
                        "name":"Hip-Hop/Rap",
                        "url":"https://itunes.apple.com/us/genre/id18"
                    },
                    {
                        "genreId":"34",
                        "name":"Music",
                        "url":"https://itunes.apple.com/us/genre/id34"
                    }
                ],
                "id":"1267471554",
                "kind":"album",
                "name":"Federal 3X",
                "releaseDate":"2017-08-11",
                "url":"https://itunes.apple.com/us/album/federal-3x/id1267471554"
            },
            {
                "artistId":"334854763",
                "artistName":"Kesha",
                "artistUrl":"https://itunes.apple.com/us/artist/kesha/id334854763",
                "artworkUrl100":"http://is1.mzstatic.com/image/thumb/Music117/v4/06/19/3e/06193ee9-3caa-642c-901c-d0097470c50b/source/200x200bb.png",
                "copyright":"℗ 2017 Kemosabe Records",
                "genres":[
                    {
                        "genreId":"14",
                        "name":"Pop",
                        "url":"https://itunes.apple.com/us/genre/id14"
                    },
                    {
                        "genreId":"34",
                        "name":"Music",
                        "url":"https://itunes.apple.com/us/genre/id34"
                    }
                ],
                "id":"1253656856",
                "kind":"album",
                "name":"Rainbow",
                "releaseDate":"2017-08-11",
                "url":"https://itunes.apple.com/us/album/rainbow/id1253656856"
            }
        ]
    }
}

Codableを使って、簡単にパースできる。

struct RssFeedResultGenre: Codable {
    let genreId: String
    let name: String
    let url: URL
}

struct RssFeedResult: Codable {
    let artistId: String
    let artistName: String
    let artistUrl: URL
    let artworkUrl100: URL
    let copyright: String
    let genres: [RssFeedResultGenre]
    let id: String
    let kind: String
    let name: String
    let releaseDate: String
    let url: URL
}

struct RssFeedAuthor: Codable {
    let name: String
    let uri: URL
}

struct RssFeed: Codable {
    let title: String
    let id: String
    let author: RssFeedAuthor
    let links: [Dictionary<String, String>]
    let copyright: String
    let country: String
    let icon: URL
    let updated: Date
    let results: [RssFeedResult]
}

struct Rss: Codable {
    let feed: RssFeed
}
let url = URL(string: "https://rss.itunes.apple.com/api/v1/us/apple-music/new-music/2/explicit.json")!

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"   // "2017-08-12T01:30:53.000-07:00"
let decoder: JSONDecoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

do {
    let data = try Data(contentsOf: url, options: [])
    let rss = try decoder.decode(Rss.self, from: data)
    print(rss)
} catch {
    print(error)
}

『 Swift 』Article List