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

Swift 5如何通过路径对Bundle中的plist文件执行解归档操作

解决方案

你遇到的报错本质是unarchivedObject(ofClass:from:)接口不支持直接传入文件路径,需要你先把Bundle里的plist文件读取为Data类型再传入,同时要注意匹配你存储的数组类型,完整的实现逻辑如下:

最简适配代码

guard let fileURL = Bundle.main.url(forResource: MoleName.DNA_ideal_comps.rawValue, withExtension: "plist"),
      let moleData = try? Data(contentsOf: fileURL),
      let components = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: moleData) as? [SCNNode],
      components.count >= 4 else {
          print("Couldn't find molecule (DNA_ideal_comps)")
          return
      }

// 后续赋值逻辑和原有代码完全一致
scaleNode_2 = components[0]     // DNA A
fixedNode_2 = components[1]     // 化学键
scaleNode_3 = components[2]     // DNA B
fixedNode_3 = components[3]     // 化学键

注意点

你之前的写法报错还有一个原因:你存储的是[SCNNode]数组类型,属于Swift结构体,无法直接被unarchivedObject(ofClass:from:)识别,需要先解档为Objective-C的NSArray类型,再桥接为Swift数组。

兼容旧归档的鲁棒性写法

如果你的旧归档没有开启安全编码,用上面的最简写法可能会报错,可以用自定义NSKeyedUnarchiver的方式适配:

func unarchiveNodeList(fileName: String) -> [SCNNode]? {
    // 获取文件URL
    guard let fileURL = Bundle.main.url(forResource: fileName, withExtension: "plist"),
          // 读取文件为Data
          let data = try? Data(contentsOf: fileURL) else {
        return nil
    }
    do {
        let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
        // 旧归档未开安全编码需要设为false,新生成的归档建议开启设为true
        unarchiver.requiresSecureCoding = false
        // 解档根对象,指定允许的类集合
        guard let nodeArray = unarchiver.decodeObject(
            of: [NSArray.self, SCNNode.self], 
            forKey: NSKeyedArchiveRootObjectKey
        ) as? [SCNNode], nodeArray.count >=4 else {
            unarchiver.finishDecoding()
            return nil
        }
        unarchiver.finishDecoding()
        return nodeArray
    } catch {
        print("文件\(fileName)解档失败:\(error.localizedDescription)")
        return nil
    }
}

// 调用示例
guard let components = unarchiveNodeList(fileName: MoleName.DNA_ideal_comps.rawValue) else {
    print("Couldn't find molecule (DNA_ideal_comps)")
    return
}
// 后续赋值逻辑不变

这种写法的容错性更高,也方便你批量处理90个plist文件,直接传入对应文件名调用即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:15:04