質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.78%

Codableを使用したJsonのマッピングができない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 453

tochimon

score 7

前提・実現したいこと

GoogleブックスAPIを使ってISBNコードから書籍を検索するアプリを制作しているのですが、「The data couldn’t be read because it isn’t in the correct format.」
とエラーが表示されてしまいます。
構造体の書き方が間違えているのかなと思ったのですが、下記のレスポンスをマッピングする場合の構造体の記述方法は自分のやり方で合っていますでしょうか?

レスポンス

{
    "kind": "books#volumes",
    "totalItems": 1,
    "items": [
        {
            "kind": "books#volume",
            "id": "s4CRHAAACAAJ",
            "etag": "deolUbOxJwI",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/s4CRHAAACAAJ",
            "volumeInfo": {
                "title": "アラビアの夜の種族",
                "authors": [
                    "古川日出男"
                ],
                "publishedDate": "2006-07",
                "description": "聖遷暦1213年。偽りの平穏に満ちたエジプト。迫り来るナポレオン艦隊、侵掠の凶兆に、迎え撃つ支配階級奴隷アイユーブの秘策はただひとつ、極上の献上品。それは読む者を破滅に導き、歴史を覆す書物、『災厄の書』―。アイユーブの術計は周到に準備される。権力者を眩惑し滅ぼす奔放な空想。物語は夜、密かにカイロの片隅で譚り書き綴られる。「妖術師アーダムはほんとうに醜い男でございました...」。驚異の物語、第一部。",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_10",
                        "identifier": "4043636032"
                    },
                    {
                        "type": "ISBN_13",
                        "identifier": "9784043636037"
                    }
                ],
                "readingModes": {
                    "text": false,
                    "image": false
                },
                "pageCount": 277,
                "printType": "BOOK",
                "categories": [
                    "Detective and mystery stories"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "preview-1.0.0",
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=s4CRHAAACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=s4CRHAAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
                },
                "language": "ja",
                "previewLink": "http://books.google.co.jp/books?id=s4CRHAAACAAJ&dq=isbn:9784043636037&hl=&cd=1&source=gbs_api",
                "infoLink": "http://books.google.co.jp/books?id=s4CRHAAACAAJ&dq=isbn:9784043636037&hl=&source=gbs_api",
                "canonicalVolumeLink": "https://books.google.com/books/about/%E3%82%A2%E3%83%A9%E3%83%93%E3%82%A2%E3%81%AE%E5%A4%9C%E3%81%AE%E7%A8%AE%E6%97%8F.html?hl=&id=s4CRHAAACAAJ"
            },
            "saleInfo": {
                "country": "JP",
                "saleability": "NOT_FOR_SALE",
                "isEbook": false
            },
            "accessInfo": {
                "country": "JP",
                "viewability": "NO_PAGES",
                "embeddable": false,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": false
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=s4CRHAAACAAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "NONE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "聖遷暦1213年。偽りの平穏に満ちたエジプト。迫り来るナポレオン艦隊、侵掠の凶兆に、迎え撃つ支配階級奴隷アイユーブの秘策はただひとつ、極上の献上品。それは読む者を破 ..."
            }
        }
    ]
}

構造体(Codable)

        struct Article: Codable {
            var kind: String
            var totalItems: String
            var items: [items]
            struct items: Codable {
                var kind: String
                var id: String
                var etag: String
                var selfLink: String
                struct volumeInfo: Codable {
                    var title: String
                    var authors: [String]
                    var publishedDate: Date
                    var description: String
                    var industryIdentifiers: [industryIdentifiers]
                    struct industryIdentifiers: Codable {
                        var type: String
                        var identifier: String
                    }
                    struct readingModes: Codable {
                        var text: Bool
                        var image: Bool
                    }
                    var pageCount: Int
                    var printType: String
                    var categories: [String]
                    var maturityRating: String
                    var allowAnonLogging: Bool
                    var contentVersion: String
                    struct imageLinks: Codable {
                        var smallThumbnail: String
                        var thumbnail: String
                    }
                    var language: String
                    var previewLink: String
                    var infoLink: String
                    var canonicalVolumeLink: String
                }
                struct saleInfo: Codable {
                    var country: String
                    var saleability: String
                    var isEbook: Bool
                }
                struct accessInfo: Codable {
                    var country: String
                    var viewability: String
                    var embeddable: Bool
                    var publicDomain: Bool
                    var textToSpeechPermission: String
                    struct epub: Codable {
                        var isAvailable: Bool
                    }
                    struct pdf: Codable {
                        var isAvailable: Bool
                    }
                    var webReaderLink: String
                    var accessViewStatus: String
                    var quoteSharingAllowed: Bool
                }
                struct searchInfo: Codable {
                    var textSnippet: String
                }
            }
        }

実行コード

        let url = "https://www.googleapis.com/books/v1/volumes"


        guard var urlComponents = URLComponents(string: url) else {
            return
        }
        // https://www.googleapis.com/books/v1/volumes?q=isbn:9784043636037
        urlComponents.queryItems = [
            URLQueryItem(name: "q", value: "isbn:9784043636037"),
        ]

        let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in

            guard let jsonData = data else {
                return
            }
            print(jsonData)
            do {
                let articles = try JSONDecoder().decode([Article].self, from: jsonData)
                print(articles)
            } catch {
                print(error.localizedDescription)
            }
        }
        task.resume()

補足情報

https://qiita.com/abouch/items/aca979b71ad792478687
上記のページを参考にさせて頂いてます。
構造体とurlを参考ページのものに合わせると実行できました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • akaakoz

    2019/04/19 01:10

    デバッグのどの箇所でエラーが出てますか?

    キャンセル

回答 2

checkベストアンサー

0

ここですね。(テスト済み)

var totalItems: Int //ここがStringになってた
var publishedDate: String //ここがDateになってた

let articles = try JSONDecoder().decode(Article.self, from; jsonData)
//ここがlet articles = try JSONDecoder().decode([Article].self, from; jsonData)だった

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/19 07:05

    回答ありがとうございました!
    解決しました!
    テストまでしてくださってありがとうございます!

    キャンセル

-1

var totalItems: String
var totalItems: Int

let articles = try JSONDecoder().decode([Article].self, from: jsonData)
let articles = try JSONDecoder().decode(Article.self, from: jsonData)

(今日、人生で初めてSwiftのコード書いたよ)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/19 07:06

    回答ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る