如何使用 Swift Codable 将复杂的 Json 打印到 CollectionView?

How do I print a complex Json to the CollectionView using Swift Codable?

我正在学习 Swift 5. 我正在使用 Codable 进行 JSON 解析。

我想将特定数据从JSON打印到CollectionView

目前数据解析成功,但不知道如何输出到CollectionView

我想将所有 JSON 数据的 TR_DT 打印到 CollectionView 的单元格中。

我打印了最多 yyyyMm 的数据。不知道输出更深TR_DT.

我该怎么办?

请初学者多多指教。 :)

(下面附上源码)

{

"list": [
    {
        "summary": [
            {
                "IN_AMT": 0,
                "OK_AMT": 0,
                "TR_MONTH": "201906"
            },
            {
                "IN_AMT": 0,
                "OK_AMT": 24256210,
                "TR_MONTH": "201907"
            }
        ],
        "yyyyMm": "201907",
        "list": [
            {
                "TR_DT": "20190623"
            },
            {
                "TR_DT": "20190624"
            },
            {
                "TR_DT": "20190625"
            },
            {
                "TR_DT": "20190626"
            },
            {
                "TR_DT": "20190627"
            },
            {
                "TR_DT": "20190628"
            },
            {
                "TR_DT": "20190629"
            }
                ]
    }
        ]
}

此源是 Jsondata。

import Foundation

// MARK: - Calendar
struct Calendar: Codable {
    let list: [CalendarList]
}

// MARK: - CalendarList
struct CalendarList: Codable {
    let summary: [Summary]
    let yyyyMm: String
    let list: [ListList]
}

// MARK: - ListList
struct ListList: Codable {
    let trDt: String

    enum CodingKeys: String, CodingKey {
        case trDt = "TR_DT"
    }
}

// MARK: - Summary
struct Summary: Codable {
    let inAmt, okAmt: Int
    let trMonth: String

    enum CodingKeys: String, CodingKey {
        case inAmt = "IN_AMT"
        case okAmt = "OK_AMT"
        case trMonth = "TR_MONTH"
    }
}

此来源为模特

import UIKit

class ViewController: UIViewController {

    var arrData = [List]()
    var sumData = [Summary]()
    let urlJSON = url

    @IBOutlet var calendarCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.


        guard let url = URL(string: urlJSON) else {return}
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else {return}
            guard error == nil else {return}
            do {
                let decoder = JSONDecoder()
                let APIResponse = try decoder.decode(CalendarModel.self, from: data)

                self.arrData = APIResponse.list!

                DispatchQueue.main.async{
                    self.calendarCollectionView.reloadData()
                }

            } catch let error {
                print("Failed to decode JSON:", error)
            }
        }.resume()
    }


}


extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return arrData.count
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CalendarCell.identifier, for: indexPath) as! CalendarCell

        let data = arrData[indexPath.row]


        return cell
    }

}

此来源是 ViewController。

首先,arrData必须是[ListList]类型,即

var arrData = [ListList]()

您需要像这样解析数据,

do {
    let response = try JSONDecoder().decode(Calendar.self, from: data)
    arrData = response.list.first?.list ?? []
    DispatchQueue.main.async {[weak self] in
        self?.calendarCollectionView.reloadData()
    }
} catch {
    print(error)
}

现在,像这样在 collectionView(_: cellForItemAt:) 中使用 arrData

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CalendarCell.identifier, for: indexPath) as! CalendarCell
    let data = arrData[indexPath.row].trDt
    //use data as text to set in the label
    return cell
}