Search code examples
jsonswiftgoogle-books-api

How to fetch only certain values from a complex JSON (Google Books API) in Swfit


I've been trying to develop an app which fetches certain information of a book from Google Books API (name, author and image) and display the image inside a collection view

var bookInfo = [Book]()

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

    

override func awakeFromNib() {
    super.awakeFromNib()
    collectionView.delegate = self
    collectionView.dataSource = self
    
    let url = URL(string: urlString)
    
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        do {
            self.bookInfo = try JSONDecoder().decode([Book].self, from: data!)
            for info in self.bookInfo {
                print(info.bookName)
            }
        }
        catch {
            print("error")
        }
    }
    
}

Below is a struct which represents the contents I'm trying to capture but not sure if this is entirely correct.

struct Book: Codable {
    var bookName: String
    var imageURL: String
    var pageCount: Int
    var author: String
    var format: String
}


struct volumeInfo: Codable {
    var bookInfo: [Book]
}

When running this code, I don't get any errors but the app is unable to fetch anything and my UIImageView is empty.


Solution

  • The Book struct you are using wouldn't work because it doesn't match the JSON response. This is the entire struct but, you can remove keys(properties) that are not required and it would still work:

    struct Book: Codable {
        let kind, id, etag, selfLink: String
        let volumeInfo: VolumeInfo
        let saleInfo: SaleInfo
        let accessInfo: AccessInfo
    }
    
    struct AccessInfo: Codable {
        let country, viewability: String
        let embeddable, publicDomain: Bool
        let textToSpeechPermission: String
        let epub, pdf: Epub
        let webReaderLink, accessViewStatus: String
        let quoteSharingAllowed: Bool
    }
    
    struct Epub: Codable {
        let isAvailable: Bool
    }
    
    struct SaleInfo: Codable {
        let country, saleability: String
        let isEbook: Bool
    }
    
    struct VolumeInfo: Codable {
        let title: String
        let authors: [String]
        let publisher, publishedDate, description: String
        let industryIdentifiers: [IndustryIdentifier]
        let readingModes: ReadingModes
        let pageCount, printedPageCount: Int
        let dimensions: Dimensions
        let printType: String
        let categories: [String]
        let averageRating: Double
        let ratingsCount: Int
        let maturityRating: String
        let allowAnonLogging: Bool
        let contentVersion: String
        let panelizationSummary: PanelizationSummary
        let imageLinks: ImageLinks
        let language, previewLink, infoLink, canonicalVolumeLink: String
    }
    
    struct Dimensions: Codable {
        let height, width, thickness: String
    }
    
    struct ImageLinks: Codable {
        let smallThumbnail, thumbnail: String
    }
    
    struct IndustryIdentifier: Codable {
        let type, identifier: String
    }
    
    struct PanelizationSummary: Codable {
        let containsEpubBubbles, containsImageBubbles: Bool
    }
    
    struct ReadingModes: Codable {
        let text, image: Bool
    }