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

Swift调用Airtable API解码失败求助:title字段缺失错误

问题原因

错误提示明确说明:第3条记录(Index 2)的fields对象中没有title字段。这是Airtable API的特性导致的:如果表格中某条记录的字段为空,返回的JSON会直接省略该字段;而你定义的FieldsDto中title和image都是必填的非可选类型,JSONDecoder遇到缺失的key就会抛出解码错误。

解决方案

1. 修改FieldsDto为可选字段(推荐)

将title和image改为可选类型,确保字段缺失时仍能正常解码,后续再处理空值:

struct ResponseDto: Decodable {
    let records: [RecordDto]
    
    struct RecordDto: Decodable {
        let id: String
        let createdTime: String
        let fields: FieldsDto
    }
    
    struct FieldsDto: Decodable {
        let title: String?
        let image: String?
    }
}

2. 过滤无效数据并映射到Film

转换时过滤掉缺少title或image的记录,避免无效数据进入列表:

// 替换原有的循环逻辑
DispatchQueue.main.async {
    self.films = response.records.compactMap { record in
        guard let title = record.fields.title, let image = record.fields.image else {
            return nil // 过滤字段不全的记录
        }
        return Film(title: title, image: image)
    }
}

3. 优化异步请求逻辑(可选)

你使用了async函数却仍用传统dataTask,可以改用URLSession的async/await API,代码更简洁且无需手动管理主线程:

class UsersViewModel: ObservableObject {
    @Published var films = [Film]()
    
    func fetchUsers() async {
        guard let url = URL(string: "https://api.airtable.com/v0/appMl82aryE3VlpSx/Series") else {
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("Bearer mykey", forHTTPHeaderField: "Authorization")
        
        do {
            let (data, response) = try await URLSession.shared.data(for: request)
            guard (response as? HTTPURLResponse)?.statusCode == 200 else {
                print("无效状态码")
                return
            }
            
            let responseDto = try JSONDecoder().decode(ResponseDto.self, from: data)
            let newFilms = responseDto.records.compactMap { record in
                guard let title = record.fields.title, let image = record.fields.image else {
                    return nil
                }
                return Film(title: title, image: image)
            }
            
            // 主线程更新UI
            await MainActor.run {
                self.films = newFilms
            }
        } catch {
            print("请求错误: \(error)")
        }
    }
}

4. 优化Film的唯一标识(可选)

Airtable返回的record.id是天然的唯一标识,比自动生成的UUID更合适,修改后:

struct Film: Identifiable {
    let id: String // 直接使用Airtable的记录ID
    let title: String
    let image: String
}

// 映射时传入ID
return Film(id: record.id, title: title, image: image)
额外检查

登录Airtable后台查看Series表格,确认第3条记录的title字段是否为空。补全字段也能解决当前错误,但从API健壮性角度,优先推荐使用可选字段的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:50:25