SwiftUI加载本地JSON触发Bundle解码扩展fatalError问题求助
问题修复方案
核心错误原因排查
shortcuts结构体存在多余的本地生成id字段,JSON中无对应字段,解码时会触发字段不匹配错误
- 示例JSON中的
id值包含非法UUID字符(4M8E中的M不属于UUID允许的十六进制字符范围),如果使用UUID类型接收会解码失败
- 示例JSON中的
- 原解码方法未打印具体错误信息,无法快速定位问题
- 需确认JSON最外层为数组结构(因为你解码的是
[topic].self数组类型),且文件已正确加入项目Target
- 需确认JSON最外层为数组结构(因为你解码的是
具体修正代码
1. 修正数据结构
// 类型名符合Swift规范首字母大写 struct Topic: Codable, Identifiable { // 如果JSON的id确实存在非十六进制字符,改成String类型即可 var id: String var name: String var group: [Shortcut] } struct Shortcut: Codable, Equatable, Identifiable{ // 本地生成的id不需要参与解码,通过CodingKeys排除 var id = UUID() var name: String var windows: String var mac: String enum CodingKeys: String, CodingKey { case name, windows, mac } }
2. 优化解码方法,打印具体错误
import UIKit extension Bundle { func decode<T: Decodable>(_ type: T.Type, from file: String) -> T { guard let url = self.url(forResource: file, withExtension: nil) else { fatalError("Bundle中找不到文件:\(file)") } guard let data = try? Data(contentsOf: url) else { fatalError("无法读取文件\(file)的数据") } let decoder = JSONDecoder() do { let loaded = try decoder.decode(T.self, from: data) return loaded } catch { // 打印详细错误,方便后续排查其他问题 fatalError("文件\(file)解码失败:\n错误详情:\(error)") } } }
3. 确认JSON格式
确保你的main.json最外层是数组包裹,且所有id值和你定义的类型匹配,如果保留UUID类型需确保所有id都是合法UUID:
[ { "id": "EF1CC5BB-4785-4A8E-AB98-5FA4E00B6A66", "name" : "opening the box", "group" : [ { "name" : "Open box", "windows" : "Double-click", "mac" : "right-click" }, { "name" : "Duplicate", "windows" : "right click and choose from options", "mac" : "option + drag" } ] }, // 其他同结构条目 ]
4. 检查文件配置
选中项目中的main.json,在右侧文件检查器的「Target Membership」中确认已经勾选了你当前的APP目标,避免Bundle找不到文件。
内容的提问来源于stack exchange,提问作者aadityaaa
相关产品推荐
相关产品推荐

