1

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.

HangarRash
  • 7,314
  • 5
  • 5
  • 32
AzAzinZ
  • 21
  • 2
  • 2
    `SwiftyJSON` is an honorable library, but today it's outdated. Use `Codable`, you will get even comprehensible error messages – vadian Jun 20 '23 at 20:47
  • 1
    Find a tutorial that doesn’t use the outdated SwiftyJSON framework but instead uses Codable. As for the crash, never force unwrap variables where you are not absolutely sure about its content. Use `if let` instead like `if let authors = i["volumeInfo"]["authors"].array { … }` – Joakim Danielson Jun 20 '23 at 20:50
  • whatever framework/library you use, **do not** use `!` in your code ever. You use them all over the place, remove them all and check non `nil` before, or `if let x = ...`, or `do {...}catch {...}` with `try`, etc... **do not** use `!` in your code. – workingdog support Ukraine Jun 21 '23 at 05:42
  • Thank you all for your wonderful help! I believe using if let is working for me now! – AzAzinZ Jun 21 '23 at 16:29

0 Answers0