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

使用Bundle解码本地JSON文件时Xcode预览进程崩溃无编译错误如何解决?

问题原因&解决方案
  • 类型不匹配:JSON中DOUBAN_SCORE、DOUBAN_VOTES、MINS三个字段的实际值是字符串类型(带双引号),但你的Movie1模型里对应定义的是Double?、Int?、Double?数值类型,JSONDecoder无法自动将字符串转成数值,直接解码失败。
  • 根数据结构不匹配:你给出的JSON示例根节点是单个Movie1对象,但是解码时你指定了目标类型为[Movie1]数组,结构对不上也会导致解码失败。
  • 不可见字符干扰:JSON的第一个键MOVIE_ID前面存在一个零宽空格不可见字符,会导致和模型里的MOVIE_ID键匹配失败,无法解析对应字段。
  • 强制错误处理风险:你的Bundle扩展里用try?忽略了所有具体错误,一旦解码失败直接触发fatalError,会直接导致进程崩溃;同时Xcode Canvas预览的沙箱路径和常规运行环境不同,预览时有可能无法读取到JSON文件,直接触发崩溃。
  • 数组越界风险:你直接通过datas[1]取值,若数组长度不足2会触发数组越界崩溃。

修复步骤

1. 修正JSON数据

  • 去掉MOVIE_ID前面的不可见字符,保证键名和模型完全一致
  • 去掉三个数值字段的双引号,改成纯数值:"DOUBAN_SCORE":8.2、"DOUBAN_VOTES":187、"MINS":0
  • 如果需要解析成数组,给整个JSON外层套上中括号[],变成数组结构

2. 优化Bundle扩展的错误处理,方便排查问题

import Foundation
extension Bundle{
    func decode<T:Codable>(filename:String) throws -> T {
        guard let url = self.url(forResource: filename, withExtension: nil) else {
            throw NSError(domain: "BundleDecode", code: -1, userInfo: [NSLocalizedDescriptionKey: "找不到文件\(filename)"])
        }
        let data = try Data(contentsOf: url)
        return try JSONDecoder().decode(T.self, from: data)
    }
}

3. 调整视图代码,避免预览崩溃

struct homePage: View {
    // 用State延迟加载,避免初始化时直接解码失败
    @State private var datas: [Movie1] = []
    
    var body: some View {
        HStack {
            Text("hello")
            // 先判断数组长度再取值,避免越界
            if datas.count > 1 {
                Text(datas[1].ACTORS ?? "none")
            } else {
                Text("暂无数据")
            }
        }
        .onAppear {
            do {
                datas = try Bundle.main.decode(filename: "movieData1.json")
            } catch {
                // 预览时如果解码失败可以打印错误,不会直接崩溃
                print("解码失败:\(error)")
                // 预览时可以补充测试假数据保证预览正常
                #if DEBUG
                datas = [Movie1(
                    MOVIE_ID: "test001",
                    NAME: "测试影片",
                    ALIAS: nil,
                    ACTORS: "测试演员",
                    COVER: nil,
                    DIRECTORS: nil,
                    DOUBAN_SCORE: nil,
                    DOUBAN_VOTES: nil,
                    GENRES: nil,
                    IMDB_ID: nil,
                    LANGUAGES: nil,
                    MINS: nil,
                    OFFICIAL_SITE: nil,
                    REGIONS: nil,
                    RELEASE_DATE: nil,
                    SLUG: nil,
                    STORYLINE: nil,
                    TAGS: nil,
                    YEAR: nil,
                    ACTOR_IDS: nil,
                    DIRECTOR_IDS: nil
                )]
                #endif
            }
        }
    }
}

如果你的JSON根节点是单个对象而非数组,将datas的类型改为Movie1?即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:27:02