是否可以使用可能的随机数组或字典或null来解码json?

问题描述 投票:0回答:1

我的目标是将 HTTP 请求发送到 API。问题是

responseBody.data.content
结构是随机的。它始终是的字典。 any 可以是数组、字典、字典数组或 null。我在绘制此地图时遇到困难。

我的预期结果是:

responseBody.data.content
不为空。

我的实际结果是:

responseBody.data.content
为空。

数据结构

import Foundation

struct GetDocumentByUrlApiResponse: Codable {
    let data: Data?
    
    struct Data: Codable {
        let document_id: String?
        let detail: Detail?
        let content: Content?
        
        struct Detail: Codable {
            let doc_meta_id: String?
            let document: String?
            let type: String?
            let title: String?
            let number: String?
            let year: Int?
            let url: String?
        }
        
        enum Content: Codable {
            case array([String])
            case dictionary([String: String?])
            case null
            
            init(from decoder: Decoder) throws {
                let container = try decoder.singleValueContainer()
                if let arrayValue = try? container.decode([String].self) {
                    self = .array(arrayValue)
                } else if let dictionaryValue = try? container.decode([String: String?].self) {
                    self = .dictionary(dictionaryValue)
                } else {
                    self = .null
                }
            }
            
            func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                switch self {
                case .array(let value):
                    try container.encode(value)
                case .dictionary(let value):
                    try container.encode(value)
                case .null:
                    try container.encodeNil()
                }
            }
        }
    }
}

extension GetDocumentByUrlApiResponse.Data.Detail: Equatable {}

extension GetDocumentByUrlApiResponse.Data.Content: Equatable {}

extension GetDocumentByUrlApiResponse.Data: Equatable {
    static func == (lhs: GetDocumentByUrlApiResponse.Data, rhs: GetDocumentByUrlApiResponse.Data) -> Bool {
        return lhs.document_id == rhs.document_id &&
        lhs.detail == rhs.detail &&
        lhs.content == rhs.content
    }
}

extension GetDocumentByUrlApiResponse: Equatable {}

成功测试案例

    var decoder: JSONDecoder!
    
    override func setUpWithError() throws {
        decoder = JSONDecoder()
    }
    
    override func tearDownWithError() throws {
        decoder = nil
    }
    
    func testDecodeNil() {
        let responseBody = "{}"
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response, GetDocumentByUrlApiResponse(data: nil))
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }
    
    func testDecodeDataNil() {
        let responseBody = """
        {
            "data": null
        }
        """
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response.data, nil)
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }
    
    func testDecodeData() {
        let responseBody = """
        {
            "data": {
                "document_id": null,
                "detail": null,
                "content": null
            }
        }
        """
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response.data?.document_id, nil)
            XCTAssertEqual(response.data?.detail, nil)
            XCTAssertEqual(response.data?.content, nil)
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }
    
    func testDecodeDataDocumentId() {
        let responseBody = """
        {
            "data": {
                "document_id": "c777ae50-0b75-11ea-9601-275a86aaae7f",
                "detail": null,
                "content": null
            }
        }
        """
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response.data?.document_id, "c777ae50-0b75-11ea-9601-275a86aaae7f")
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }
    
    func testDecodeDataDetailNil() {
        let responseBody = """
        {
            "data": {
                "document_id": null,
                "detail": {
                    "doc_meta_id": null,
                    "document": null,
                    "type": null,
                    "title": null,
                    "number": null,
                    "year": null,
                    "url": null
                },
                "content": null
            }
        }
        """
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response.data?.detail?.doc_meta_id, nil)
            XCTAssertEqual(response.data?.detail?.document, nil)
            XCTAssertEqual(response.data?.detail?.type, nil)
            XCTAssertEqual(response.data?.detail?.title, nil)
            XCTAssertEqual(response.data?.detail?.number, nil)
            XCTAssertEqual(response.data?.detail?.year, nil)
            XCTAssertEqual(response.data?.detail?.url, nil)
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }
    
    func testDecodeDataDetail() {
        let responseBody = """
        {
            "data": {
                "document_id": null,
                "detail": {
                    "doc_meta_id": "c7790de0-0b75-11ea-9601-275a86aaae7f",
                    "document": "Undang-Undang Nomor 18 Tahun 2009 Tentang Peternakan dan Kesehatan Hewan",
                    "type": "Undang-Undang",
                    "title": "Peternakan dan Kesehatan Hewan",
                    "number": "18",
                    "year": 2009,
                    "url": "uu-18-2009"
                },
                "content": null
            }
        }
        """
        
        do {
            let response = try decoder.decode(GetDocumentByUrlApiResponse.self, from: Data(responseBody.utf8))
            
            XCTAssertEqual(response.data?.detail?.doc_meta_id, "c7790de0-0b75-11ea-9601-275a86aaae7f")
            XCTAssertEqual(response.data?.detail?.document, "Undang-Undang Nomor 18 Tahun 2009 Tentang Peternakan dan Kesehatan Hewan")
            XCTAssertEqual(response.data?.detail?.type, "Undang-Undang")
            XCTAssertEqual(response.data?.detail?.title, "Peternakan dan Kesehatan Hewan")
            XCTAssertEqual(response.data?.detail?.number, "18")
            XCTAssertEqual(response.data?.detail?.year, 2009)
            XCTAssertEqual(response.data?.detail?.url, "uu-18-2009")
        } catch {
            XCTFail("Error decoding JSON: \(error)")
        }
    }

当前失败的测试用例

{
    "data": {
        "document_id": "c777ae50-0b75-11ea-9601-275a86aaae7f",
        "detail": {
            "doc_meta_id": "c7790de0-0b75-11ea-9601-275a86aaae7f",
            "document": "Undang-Undang Nomor 18 Tahun 2009 Tentang Peternakan dan Kesehatan Hewan",
            "type": "Undang-Undang",
            "title": "Peternakan dan Kesehatan Hewan",
            "number": "18",
            "year": 2009,
            "url": "uu-18-2009"
        },
        "content": {
            "menimbang": [{
                "@huruf": {
                    "a": [
                        "bahwa hewan sebagai karunia dan amanat Tuhan Yang Maha Esa mempunyai peranan penting dalam penyediaan pangan asal hewan dan hasil hewan lainnya serta jasa bagi manusia yang pemanfaatannya perlu diarahkan untuk kesejahteraan masyarakat;"
                    ],
                    "b": [
                        "bahwa untuk mencapai maksud tersebut perlu diselenggarakan kesehatan hewan yang melindungi kesehatan manusia dan hewan beserta ekosistemnya sebagai prasyarat terselenggaranya peternakan yang maju, berdaya saing, dan berkelanjutan serta penyediaan pangan yang aman, sehat, utuh, dan halal sehingga perlu didayagunakan untuk kemakmuran dan kesejahteraan masyarakat;"
                    ],
                    "c": [
                        "bahwa dengan perkembangan keadaan tuntutan otonomi daerah dan globalisasi, peraturan perundang- undangan di bidang peternakan dan kesehatan hewan yang berlaku saat ini sudah tidak sesuai lagi sebagai landasan hukum bagi penyelenggaraan peternakan dan kesehatan hewan;"
                    ],
                    "d": [
                        "bahwa berdasarkan pertimbangan sebagaimana dimaksud dalam huruf a, huruf b, dan huruf c, perlu membentuk Undang-Undang tentang Peternakan dan Kesehatan Hewan;"
                    ]
                }
            }],
            "mengingat": [
                "Pasal 5 ayat (1), Pasal 20, dan Pasal 33 Undang- Undang Dasar Negara Republik Indonesia Tahun 1945;"
            ],
            "memperhatikan": null,
            "mendengar": null,
            "persetujuan": [
                "Bersama",
                "DEWAN PERWAKILAN RAKYAT REPUBLIK INDONESIA",
                "dan",
                "PRESIDEN REPUBLIK INDONESIA,"
            ],
            "memutuskan": null,
            "menetapkan": [
                "UNDANG-UNDANG TENTANG PETERNAKAN DAN KESEHATAN HEWAN."
            ],
            "bab": {
                "bab i~ketentuan umum": [{
                    "@pasal": {
                        "pasal 1": [
                            "Dalam Undang-Undang ini yang dimaksud dengan:",
                            {
                                "@angka": {
                                    "1": [
                                        "Peternakan adalah segala urusan yang berkaitan dengan sumber daya fisik, benih, bibit dan/atau bakalan, pakan, alat dan mesin peternakan, budi daya ternak, panen, pascapanen, pengolahan, pemasaran, dan pengusahaannya."
                                    ]
                                }
                            }
                        ]
                    }
                }],
                "bab ii~asas dan tujuan": [{
                    "@pasal": {
                        "pasal 2": [{
                            "@ayat": {
                                "(1)": [
                                    "Peternakan dan kesehatan hewan dapat diselenggarakan di seluruh wilayah Negara Kesatuan Republik Indonesia yang dilaksanakan secara tersendiri dan/atau melalui integrasi dengan budi daya tanaman pangan, hortikultura, perkebunan, perikanan, kehutanan, atau bidang lainnya yang terkait."
                                ]
                            }
                        }]
                    }
                }],
                "bab iii~sumber daya": [{
                    "@bagian": {
                        "bagian kesatu~lahan": [{
                            "@pasal": {
                                "pasal 4": [
                                    "Untuk menjamin kepastian terselenggaranya peternakan dan kesehatan hewan diperlukan penyediaan lahan yang memenuhi persyaratan teknis peternakan dan kesehatan hewan."
                                ]
                            }
                        }]
                    }
                }]
            },
            "ditetapkan": null,
            "disahkan": null,
            "diundangkan": [
                "Di Jakarta, Pada Tanggal 4 Juni 2009",
                "MENTERI HUKUM DAN HAK ASASI MANUSIA REPUBLIK INDONESIA,",
                "Ttd.",
                "ANDI MATTALATTA"
            ]
        }
    }
}
swift xctest
1个回答
0
投票

你可以像这样解码任意 JSON

let decoded = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]

并访问可能的属性,如下所示

decoded?["content"]
© www.soinside.com 2019 - 2024. All rights reserved.