【问题标题】:How can I decode two different response JSON in one request?如何在一个请求中解码两个不同的响应 JSON?
【发布时间】:2021-01-29 13:27:23
【问题描述】:

我正在尝试从 Google 的 Book API 获得响应。在那里我可以得到响应,但例如,在某些书中有description 或许多其他键响应JSON。如果我根据描述键设计我的结构,其他没有描述的书籍给了我 dataCorrupted 错误并且没有解码 JSON。如果我不这样做,我会在其他有描述的书中得到同样的错误。我希望我能解释一下自己。如何正确解决?

这是我的根类可编码:

import Foundation

struct RootClass : Codable {

        let items : [Item]?
        let kind : String?
        let totalItems : Int?

        enum CodingKeys: String, CodingKey {
                case items = "items"
                case kind = "kind"
                case totalItems = "totalItems"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                items = try values.decodeIfPresent([Item].self, forKey: .items)
                kind = try values.decodeIfPresent(String.self, forKey: .kind)
                totalItems = try values.decodeIfPresent(Int.self, forKey: .totalItems)
        }

}

我需要到达 root -> items -> volumeInfo。

这里是 Item 可编码结构:

import Foundation

struct Item : Codable {

        let accessInfo : AccessInfo?
        let etag : String?
        let id : String?
        let kind : String?
        let saleInfo : SaleInfo?
        let searchInfo : SearchInfo?
        let selfLink : String?
        let volumeInfo : VolumeInfo?

        enum CodingKeys: String, CodingKey {
                case accessInfo = "accessInfo"
                case etag = "etag"
                case id = "id"
                case kind = "kind"
                case saleInfo = "saleInfo"
                case searchInfo = "searchInfo"
                case selfLink = "selfLink"
                case volumeInfo = "volumeInfo"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
            accessInfo = try AccessInfo(from: decoder)
                etag = try values.decodeIfPresent(String.self, forKey: .etag)
                id = try values.decodeIfPresent(String.self, forKey: .id)
                kind = try values.decodeIfPresent(String.self, forKey: .kind)
            saleInfo = try SaleInfo(from: decoder)
            searchInfo = try SearchInfo(from: decoder)
                selfLink = try values.decodeIfPresent(String.self, forKey: .selfLink)
            volumeInfo = try VolumeInfo(from: decoder)
        }

}

我在这里解析 json:

func parseJSON(searchData: Data) -> [SearchedModel]?{
    
    let decode = JSONDecoder()
    do{
        let decodedData = try decode.decode(RootClass.self, from: searchData)
        // IN HERE I CAN USE FOR LOOP TO ITEMS AND GET VOLUME INFO DATAS BUT ITS ALL NIL

        return mainDataArr
    }catch{
        print(error)
        return nil
    }
    
}

当我尝试循环访问项目并获取卷信息数据时,它全部为零。我不明白为什么这一切都是零?我该如何解决?

这里是 JSON 1 的一部分:

"kind": "books#volumes",
    "totalItems": 1196,
    "items": [
        {
            "kind": "books#volume",
            "id": "4qnmsgEACAAJ",
            "etag": "dYXW8bT6JB0",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/4qnmsgEACAAJ",
            "volumeInfo": {
                "title": "Sineklerin Tanrisi",
                "authors": [
                    "William Golding"
                ],
                "publishedDate": "2014-01-01",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_10",
                        "identifier": "9754582904"
                    },
                    {
                        "type": "ISBN_13",
                        "identifier": "9789754582901"
                    }
                ],
                "readingModes": {
                    "text": false,
                    "image": false
                },
                "pageCount": 261,
                "printType": "BOOK",
                "categories": [
                    "Boys"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "preview-1.0.0",
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=4qnmsgEACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=4qnmsgEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
                },
                "language": "tr",
                "previewLink": "http://books.google.com.tr/books?id=4qnmsgEACAAJ&dq=sineklerin+tanrisi&hl=&cd=1&source=gbs_api",
                "infoLink": "http://books.google.com.tr/books?id=4qnmsgEACAAJ&dq=sineklerin+tanrisi&hl=&source=gbs_api",
                "canonicalVolumeLink": "https://books.google.com/books/about/Sineklerin_Tanrisi.html?hl=&id=4qnmsgEACAAJ"
            },
            "saleInfo": {
                "country": "TR",
                "saleability": "NOT_FOR_SALE",
                "isEbook": false
            },
            "accessInfo": {
                "country": "TR",
                "viewability": "NO_PAGES",
                "embeddable": false,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": false
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=4qnmsgEACAAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "NONE",
                "quoteSharingAllowed": false
            }
        }

这里是 JSON 2(具有相同的请求响应):

"kind": "books#volumes",
    "totalItems": 432,
    "items": [
        {
            "kind": "books#volume",
            "id": "yodWha1LmPsC",
            "etag": "2bZz2CDqiq4",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/yodWha1LmPsC",
            "volumeInfo": {
                "title": "Momo the Monkey Arrives",
                "authors": [
                    "Shariffa Keshavjee"
                ],
                "publisher": "Master Publishing",
                "publishedDate": "2012-09-21",
                "description": "Momo the Monkey Arrives is the first in a series of illustrated children's books about the rescue of a monkey and how his presence livens up the household of two children: a boy and a girl. Along the way, as they take care of Momo, Geno and Alid learn how to give the best possible care to a monkey like him, and how to be more responsible children. The adventures of Momo are based on a true story.",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_13",
                        "identifier": "9789966158987"
                    },
                    {
                        "type": "ISBN_10",
                        "identifier": "9966158987"
                    }
                ],
                "readingModes": {
                    "text": true,
                    "image": true
                },
                "pageCount": 28,
                "printType": "BOOK",
                "categories": [
                    "Juvenile Fiction"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "1.4.4.0.preview.3",
                "panelizationSummary": {
                    "containsEpubBubbles": false,
                    "containsImageBubbles": false
                },
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=yodWha1LmPsC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=yodWha1LmPsC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
                },
                "language": "en",
                "previewLink": "http://books.google.com.tr/books?id=yodWha1LmPsC&pg=PT25&dq=momo&hl=&cd=1&source=gbs_api",
                "infoLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC&source=gbs_api",
                "canonicalVolumeLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC"
            },
            "saleInfo": {
                "country": "TR",
                "saleability": "FOR_SALE",
                "isEbook": true,
                "listPrice": {
                    "amount": 35.04,
                    "currencyCode": "TRY"
                },
                "retailPrice": {
                    "amount": 35.04,
                    "currencyCode": "TRY"
                },
                "buyLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC&rdid=book-yodWha1LmPsC&rdot=1&source=gbs_api",
                "offers": [
                    {
                        "finskyOfferType": 1,
                        "listPrice": {
                            "amountInMicros": 35040000,
                            "currencyCode": "TRY"
                        },
                        "retailPrice": {
                            "amountInMicros": 35040000,
                            "currencyCode": "TRY"
                        }
                    }
                ]
            },
            "accessInfo": {
                "country": "TR",
                "viewability": "PARTIAL",
                "embeddable": true,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": true
                },
                "pdf": {
                    "isAvailable": true
                },
                "webReaderLink": "http://play.google.com/books/reader?id=yodWha1LmPsC&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "SAMPLE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "<b>Momo</b> the Monkey Adventure Series <b>Momo</b> the Monkey Arrives <b>Momo</b> Makes a <br>\nMess <b>Momo</b> Comes to the Rescue <b>Momo</b> Moves to the Orphanage Look out for <br>\nthese stories about <b>Momo</b> and his friends. More coming soon! Master Publishing<br>\n&nbsp;..."
            }
        }

【问题讨论】:

标签: json swift parsing


【解决方案1】:

“数据损坏”错误似乎是由于textSnippet 中存在\n。如果我们手动处理,我无法重现任何问题。这是一个完整(与您的代码不同)示例,它使用您提供的 JSON(修补为有效的 JSON)在 iOS 项目中正确编译和运行:

let json1 = """
{
    "kind": "books#volumes",
    "totalItems": 1196,
    "items": [
        {
            "kind": "books#volume",
            "id": "4qnmsgEACAAJ",
            "etag": "dYXW8bT6JB0",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/4qnmsgEACAAJ",
            "volumeInfo": {
                "title": "Sineklerin Tanrisi",
                "authors": [
                    "William Golding"
                ],
                "publishedDate": "2014-01-01",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_10",
                        "identifier": "9754582904"
                    },
                    {
                        "type": "ISBN_13",
                        "identifier": "9789754582901"
                    }
                ],
                "readingModes": {
                    "text": false,
                    "image": false
                },
                "pageCount": 261,
                "printType": "BOOK",
                "categories": [
                    "Boys"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "preview-1.0.0",
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=4qnmsgEACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=4qnmsgEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
                },
                "language": "tr",
                "previewLink": "http://books.google.com.tr/books?id=4qnmsgEACAAJ&dq=sineklerin+tanrisi&hl=&cd=1&source=gbs_api",
                "infoLink": "http://books.google.com.tr/books?id=4qnmsgEACAAJ&dq=sineklerin+tanrisi&hl=&source=gbs_api",
                "canonicalVolumeLink": "https://books.google.com/books/about/Sineklerin_Tanrisi.html?hl=&id=4qnmsgEACAAJ"
            },
            "saleInfo": {
                "country": "TR",
                "saleability": "NOT_FOR_SALE",
                "isEbook": false
            },
            "accessInfo": {
                "country": "TR",
                "viewability": "NO_PAGES",
                "embeddable": false,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": false
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=4qnmsgEACAAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "NONE",
                "quoteSharingAllowed": false
            }
        }
    ]
}
"""

let json2 = """
{
    "kind": "books#volumes",
    "totalItems": 432,
    "items": [
        {
            "kind": "books#volume",
            "id": "yodWha1LmPsC",
            "etag": "2bZz2CDqiq4",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/yodWha1LmPsC",
            "volumeInfo": {
                "title": "Momo the Monkey Arrives",
                "authors": [
                    "Shariffa Keshavjee"
                ],
                "publisher": "Master Publishing",
                "publishedDate": "2012-09-21",
                "description": "Momo the Monkey Arrives is the first in a series of illustrated children's books about the rescue of a monkey and how his presence livens up the household of two children: a boy and a girl. Along the way, as they take care of Momo, Geno and Alid learn how to give the best possible care to a monkey like him, and how to be more responsible children. The adventures of Momo are based on a true story.",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_13",
                        "identifier": "9789966158987"
                    },
                    {
                        "type": "ISBN_10",
                        "identifier": "9966158987"
                    }
                ],
                "readingModes": {
                    "text": true,
                    "image": true
                },
                "pageCount": 28,
                "printType": "BOOK",
                "categories": [
                    "Juvenile Fiction"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "1.4.4.0.preview.3",
                "panelizationSummary": {
                    "containsEpubBubbles": false,
                    "containsImageBubbles": false
                },
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=yodWha1LmPsC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=yodWha1LmPsC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
                },
                "language": "en",
                "previewLink": "http://books.google.com.tr/books?id=yodWha1LmPsC&pg=PT25&dq=momo&hl=&cd=1&source=gbs_api",
                "infoLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC&source=gbs_api",
                "canonicalVolumeLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC"
            },
            "saleInfo": {
                "country": "TR",
                "saleability": "FOR_SALE",
                "isEbook": true,
                "listPrice": {
                    "amount": 35.04,
                    "currencyCode": "TRY"
                },
                "retailPrice": {
                    "amount": 35.04,
                    "currencyCode": "TRY"
                },
                "buyLink": "https://play.google.com/store/books/details?id=yodWha1LmPsC&rdid=book-yodWha1LmPsC&rdot=1&source=gbs_api",
                "offers": [
                    {
                        "finskyOfferType": 1,
                        "listPrice": {
                            "amountInMicros": 35040000,
                            "currencyCode": "TRY"
                        },
                        "retailPrice": {
                            "amountInMicros": 35040000,
                            "currencyCode": "TRY"
                        }
                    }
                ]
            },
            "accessInfo": {
                "country": "TR",
                "viewability": "PARTIAL",
                "embeddable": true,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": true
                },
                "pdf": {
                    "isAvailable": true
                },
                "webReaderLink": "http://play.google.com/books/reader?id=yodWha1LmPsC&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "SAMPLE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "<b>Momo</b> the Monkey Adventure Series <b>Momo</b> the Monkey Arrives <b>Momo</b> Makes a <br>\\nMess <b>Momo</b> Comes to the Rescue <b>Momo</b> Moves to the Orphanage Look out for <br>\\nthese stories about <b>Momo</b> and his friends. More coming soon! Master Publishing<br>\\n&nbsp;..."
            }
        }
    ]
}
"""

struct Base : Codable {
    let kind : String
    let totalItems : Int
    let items : [Items]
}
struct Items : Codable {
    let kind : String
    let id : String
    let etag : String
    let selfLink : String
    let volumeInfo : VolumeInfo
    let saleInfo : SaleInfo?
    let accessInfo : AccessInfo
    let searchInfo : SearchInfo?
}
struct SaleInfo : Codable {
    let country : String
    let saleability : String
    let isEbook : Bool
    let listPrice : ListPrice?
    let retailPrice : RetailPrice?
    let buyLink : String?
    let offers : [Offers]?
}
struct Offers : Codable {
    let finskyOfferType : Int
    let listPrice : ListPrice
    let retailPrice : RetailPrice
}
struct ListPrice : Codable {
    let amountInMicros : Int?
    let currencyCode : String
}
struct ReadingModes : Codable {
    let text : Bool
    let image : Bool
}
struct Epub : Codable {
    let isAvailable : Bool
}
struct Pdf : Codable {
    let isAvailable : Bool
}
struct RetailPrice : Codable {
    let amountInMicros : Int?
    let currencyCode : String
}
struct SearchInfo : Codable {
    let textSnippet : String
}
struct ImageLinks : Codable {
    let smallThumbnail : String
    let thumbnail : String
}
struct IndustryIdentifiers : Codable {
    let type : String
    let identifier : String
}
struct PanelizationSummary : Codable {
    let containsEpubBubbles : Bool
    let containsImageBubbles : Bool
}
struct VolumeInfo : Codable {
    let title : String
    let authors : [String]
    let publisher : String?
    let publishedDate : String
    let description : String?
    let industryIdentifiers : [IndustryIdentifiers]
    let readingModes : ReadingModes
    let pageCount : Int
    let printType : String
    let categories : [String]
    let maturityRating : String
    let allowAnonLogging : Bool
    let contentVersion : String
    let panelizationSummary : PanelizationSummary?
    let imageLinks : ImageLinks
    let language : String
    let previewLink : String
    let infoLink : String
    let canonicalVolumeLink : String
}
struct AccessInfo : Codable {
    let country : String
    let viewability : String
    let embeddable : Bool
    let publicDomain : Bool
    let textToSpeechPermission : String
    let epub : Epub
    let pdf : Pdf
    let webReaderLink : String
    let accessViewStatus : String
    let quoteSharingAllowed : Bool
}


class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let data1 = json1.data(using: .utf8)!
        do {
            let result = try JSONDecoder().decode(Base.self, from: data1)
            print("success1")
            print(result)
        } catch {
            print(error)
        }
        let data2 = json2.data(using: .utf8)!
        do {
            let result = try JSONDecoder().decode(Base.self, from: data2)
            print("success2")
            print(result)
        } catch {
            print(error)
        }


    }


}

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多