You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Swift调用Google Books API时无作者书籍引发的崩溃问题

修复Google Books API Swift应用的崩溃问题

问题核心

崩溃的直接原因是let authors = i["volumeInfo"]["authors"].array!这一行的强制解包:当书籍没有作者信息时,array方法返回nil,使用!强制解包会直接触发运行时崩溃。此外代码中还有多处强制解包操作,都是潜在的崩溃风险点。

完整修复代码

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) { book in
            HStack {
                if let imageUrl = URL(string: book.imurl), !book.imurl.isEmpty {
                    WebImage(url: imageUrl)
                        .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(book.title)
                        .fontWeight(.bold)
                
                    Text(book.authors)
                
                    Text(book.desc)
                        .font(.caption)
                        .lineLimit(4)
                        .multilineTextAlignment(.leading)
                }
            }
        }
    }
}

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

    init() {
        guard let url = URL(string: "https://www.googleapis.com/books/v1/volumes?q=Harry+Potter&maxResults=40") else {
            print("Invalid URL")
            return
        }
        
        let session = URLSession(configuration: .default)
        
        session.dataTask(with: url) { [weak self] data, _, error in
            guard let self = self else { return }
            
            if let error = error {
                print("Request error: \(error.localizedDescription)")
                return
            }
            
            guard let jsonData = data else {
                print("No data received")
                return
            }
            
            guard let json = try? JSON(data: jsonData) else {
                print("Failed to parse JSON")
                return
            }
            
            guard let items = json["items"].array else {
                print("No items found in response")
                return
            }
            
            for item in items {
                let id = item["id"].stringValue
                let title = item["volumeInfo"]["title"].stringValue
                // 处理作者数组:nil时返回空数组,避免强制解包崩溃
                let authorsArray = item["volumeInfo"]["authors"].array ?? []
                // 将作者数组拼接为字符串,多个作者用逗号分隔
                let authors = authorsArray.map { $0.stringValue }.joined(separator: ", ")
                // 没有作者时设置默认文本,保证界面有内容显示
                let displayAuthors = authors.isEmpty ? "Unknown Author" : authors
                
                let description = item["volumeInfo"]["description"].stringValue
                let imurl = item["volumeInfo"]["imageLinks"]["thumbnail"].stringValue
                let url1 = item["volumeInfo"]["previewLink"].stringValue

                DispatchQueue.main.async {
                    self.data.append(Book(
                        id: id,
                        title: title,
                        authors: displayAuthors,
                        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
}

关键修改说明

  1. 作者信息处理

    • 把强制解包的array!替换为array ?? [],用空数组替代nil,彻底避免崩溃
    • 拼接作者字符串后,若结果为空则设置默认文本Unknown Author,保证界面始终有内容显示
  2. 移除所有强制解包操作

    • URL创建用guard let校验有效性,无效时输出日志而非崩溃
    • JSON解析用try?替代try!,解析失败时捕获错误并输出日志
    • WebImage的URL创建用可选绑定,避免无效URL导致的潜在崩溃
  3. 代码可读性优化

    • 类名getData改为GetData(符合Swift大驼峰命名规范)
    • 变量名Books改为books、i改为book/item,提升代码辨识度
    • 用map + joined替代循环拼接作者字符串,代码更简洁高效

内容的提问来源于stack exchange,提问作者AzAzinZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:52:54