Issue Overcoming Missing Values in API App

60 Views Asked by At

I was playing with a Swift app someone made on Youtube that accesses the Google Books API and returns the results of a (hard-coded) query. While playing with it, I noticed it kept crashing. Playing with it a little I realized it crashes when it tries to bring in books that don't have authors. As much as I have tried to play with the code, though, and pass in all sort of nil catchers I can't figure out how to fix it. I'm probably being an absolute idiot. Could someone help me figure out how to fix this?

This is the original code. The problem happens when it tries to pass in a book without any authors (I think the problem happens starting on the line at the bottom saying:

let authors = i["volumeInfo"]["authors"].array!")
import SwiftUI
import SwiftyJSON
import SDWebImageSwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView{
            Home()
            .navigationTitle("Books")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Home: View {
    @ObservedObject var Books = getData()

    var body: some View {
        List(Books.data) { i in
            HStack {
                if i.imurl != "" {
                    WebImage(url: URL(string: i.imurl)!)
                        .resizable()
                        .frame(width: 120, height: 170)
                        .cornerRadius(10)
                }
                else {
                    Image("book_thumbnail")
                        .resizable()
                        .frame(width: 120, height: 170)
                        .cornerRadius(10)
                
                }
            
                VStack(alignment: .leading, spacing: 10) {
                    Text(i.title)
                        .fontWeight(.bold)
                
                    Text(i.authors)
                
                    Text(i.desc)
                        .font(.caption)
                        .lineLimit(4)
                        .multilineTextAlignment(.leading)
                }
            }
        }
    }
}

class getData: ObservableObject{
    @Published var data = [Book]()

    init() {
        let url = "https://www.googleapis.com/books/v1/volumes?q=Harry+Potter&maxResults=40"
        
        let session = URLSession(configuration: .default)
        
        session.dataTask(with: URL(string: url)!) {(data, _, err) in
            
            if err != nil {
                print((err?.localizedDescription)!)
                return
            }
            
            let json = try! JSON(data: data!)
            let items = json["items"].array!
            
            for i in items {
                let id = i["id"].stringValue
                let title = i["volumeInfo"]["title"].stringValue
                let authors = i["volumeInfo"]["authors"].array!
                var author = ""
                
                for j in authors{
                    author += "\(j.stringValue)"
                }
                
                let description =  i["volumeInfo"]["description"].stringValue
                let imurl = i["volumeInfo"]["imageLinks"]["thumbnail"].stringValue
                let url1 = i["volumeInfo"]["previewLink"].stringValue

                DispatchQueue.main.async {
                    self.data.append(Book(id: id, title: title, authors: author, desc:     
description, imurl: imurl, url: url1))
                }
            }
        }.resume()
    }
}

struct Book: Identifiable {
    var id : String
    var title : String
    var authors : String
    var desc : String
    var imurl : String
    var url : String
}

I have tried a bunch of nil handling things I've looked up, which seem to work... until I realized the author information had vanished from the interface.

0

There are 0 best solutions below