💬

[Swift]JSONデータを受け取る

2021/10/04に公開

はじめに

SwiftでWebAPIから受け取ったJSONデータをパースする方法について説明していきます。

環境

  • Xcode 12.5
  • Swift 5.4

JSONデータ

今回はOpenBDから受け取ったJSONデータを使用して説明していきます。
下のJSONデータは金のフレーズのISBNコードをリクエストした結果です。

[
  {
    "onix": {
      "RecordReference": "9784023315686",
      "NotificationType": "03",
      "ProductIdentifier": {
        "ProductIDType": "15",
        "IDValue": "9784023315686"
      },
      "DescriptiveDetail": {
        "ProductComposition": "00",
        "ProductForm": "BA",
        "ProductFormDetail": "B112",
        "Measure": [
          {
            "MeasureType": "01",
            "Measurement": "172",
            "MeasureUnitCode": "mm"
          },
          {
            "MeasureType": "02",
            "Measurement": "107",
            "MeasureUnitCode": "mm"
          }
        ],
        "TitleDetail": {
          "TitleType": "01",
          "TitleElement": {
            "TitleElementLevel": "01",
            "TitleText": {
              "collationkey": "トイックエルアンドアールテスト",
              "content": "TOEIC L&R TEST"
            },
            "Subtitle": {
              "collationkey": "デルタントッキュウキンノフレーズ",
              "content": "出る単特急金のフレーズ"
            }
          }
        },
        "Contributor": [
          {
            "SequenceNumber": "1",
            "ContributorRole": [
              "A01"
            ],
            "PersonName": {
              "collationkey": "ティーイーエックスカトウ",
              "content": "TEX加藤"
            }
          }
        ],
        "Language": [
          {
            "LanguageRole": "01",
            "LanguageCode": "jpn",
            "CountryCode": "JP"
          }
        ],
        "Subject": [
          {
            "MainSubject": "",
            "SubjectSchemeIdentifier": "78",
            "SubjectCode": "0082"
          }
        ],
        "Audience": [
          {
            "AudienceCodeType": "22",
            "AudienceCodeValue": "00"
          }
        ]
      },
      "CollateralDetail": {
        "TextContent": [
          {
            "TextType": "03",
            "ContentAudience": "00",
            "Text": "【語学/英米語】TOEIC界の絶対バイブル「金フレ」が、新形式に対応して完全改訂。著者のTEX氏が3年かけて吟味、推敲を重ねた「100%の単語帳」。質・内容・コスパ、これ以上のTOEIC単語集はありません! 面白いです。スコアも上がります。"
          }
        ]
      },
      "PublishingDetail": {
        "Imprint": {
          "ImprintIdentifier": [
            {
              "ImprintIDType": "24",
              "IDValue": "0042"
            },
            {
              "ImprintIDType": "19",
              "IDValue": "02"
            }
          ],
          "ImprintName": "朝日新聞出版"
        },
        "Publisher": {
          "PublishingRole": "01",
          "PublisherIdentifier": [
            {
              "PublisherIDType": "24",
              "IDValue": "0042"
            },
            {
              "PublisherIDType": "19",
              "IDValue": "02"
            }
          ],
          "PublisherName": "朝日新聞出版"
        },
        "PublishingDate": [
          {
            "PublishingDateRole": "01",
            "Date": "20170106"
          },
          {
            "PublishingDateRole": "02",
            "Date": "20170106"
          }
        ]
      },
      "ProductSupply": {
        "SupplyDetail": {
          "ReturnsConditions": {
            "ReturnsCodeType": "04",
            "ReturnsCode": "03"
          },
          "ProductAvailability": "99",
          "Price": [
            {
              "PriceType": "03",
              "PriceAmount": "890",
              "CurrencyCode": "JPY"
            }
          ]
        }
      }
    },
    "hanmoto": {
      "datecreated": "2016-12-16 16:06:45",
      "datemodified": "2016-12-16 16:06:45"
    },
    "summary": {
      "isbn": "9784023315686",
      "title": "TOEIC L&R TEST",
      "volume": "",
      "series": "",
      "publisher": "朝日新聞出版",
      "pubdate": "20170106",
      "cover": "",
      "author": "TEX加藤/著"
    }
  }
]

ターゲット

このJSONデータからタイトル本の内容のみを取り出していきます。
タイトル:「summary」→「title」
本の内容:「onix」→「CollateralDetail」→「[TextContent]」→「Text」

クラスの用意

JSONデータを受け取るクラスを用意します。

1.Swift fileを作成

「File」→「New」→「File]で「Swift File」を選択し、適当な名前を付けて作成してください。
この中にクラスを作成していきます。

2.クラスの作成

今回はクラス名を「Book」としました。このクラスに「Docodable」を付けてください。
「Docodable」とは、JSONのデコードをする時に使うプロトコルです。

class Book: Decodable {
}

タイトル

タイトルは「summary」→「title」にあります。そのため、上で作成したBookクラスを次のようにします。
「summary」と「title」のスペルミスをしないように注意してください。

class Book: Decodable {
    let summary:Summary
}

class Summary: Decodable {
    let title: String
}

本の内容

本の内容は「onix」→「CollateralDetail」→「[TextContent]」→「Text」にあります。そのため次のようにします。
ここでもスペルミスをしないように注意してください。

class Book: Decodable {
    let summary:Summary
    let onix: Onix
}

class Summary: Decodable {
    let title: String
}

class Onix: Decodable {
    let CollateralDetail: CCollateralDetail
}

class CCollateralDetail: Decodable {
    let TextContent: [CTextContent]
}

class CTextContent: Decodable {
    let Text: String
}

これでクラスの用意は終わりです。

JSONデータのパースと取り出しかた

JSONDecoderを使用して、JSONデータをパースします。JSONDecoderには、上で作成したクラスを指定します。
また、このJSONデータは全体が[]で囲われているので、配列で指定します。

URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data else {
	return
    }
    
    let bookdata:[Book] = try JSONDecoder().decode([Book].self, from: data)
}

タイトルと本の内容は次のように取り出すことができます。

print(bookdata[0].summary.title)
print(bookdata[0].onix.CollateralDetail.TextContent[0].Text)

おわりに

JSONデータをパースするときに、必要なデータのみを取り出す方法について苦労したので記事にしてみました。

Discussion