Xcode Playground无法从Bundle读取文件问题
Xcode Playground无法从Bundle读取文件问题

Xcode Playground无法从Bundle读取文件问题

读取JSON文件

在Playground环境中,当我尝试从Bundle.main文件中读取JSON文件时,发现无法读取到JSON文件的路径。

当我调用loadJSON方法时,发现Xcode预览并没有for-in循环的print输出:

func loadJSON() -> [CryptoDTO] {
    guard let url = Bundle.main.url(forResource: "coins", withExtension: "json"),let data = try? Data(contentsOf: url) else {
        return []
    }
    let decoder = JSONDecoder()
    do {
        let cryptos = try decoder.decode([CryptoDTO].self, from: data)
        for crypto in cryptos {
            print("Name: \(crypto.name), Price: \(crypto.currentPrice)")
        }
        return cryptos
    } catch {
        print("Decoding failed: \(error)")
        return []
    }
}

在排查的过程中,给url判断语句添加print输出。

guard let url = Bundle.main.url(forResource: "coins", withExtension: "json"),let data = try? Data(contentsOf: url) else {
    print("url或data失败,输出为空")
    return []
}

发现Xcode输出这个报错信息:url或data失败,输出为空。

接着,我尝试打印Bundle里所有资源路径,检查包含coins.json文件:

for path in Bundle.main.paths(forResourcesOfType: "json", inDirectory: nil) {
    print("路径:\(path)")
}
guard let url = Bundle.main.url(forResource: "coins" ,withExtension: "json") else {
    print("url获取失败")
    return []
}

最后没有输出Bundle的任何资源,并且输出“url获取失败”。

经过查询了解到,Playground中的Bundle.main是“沙盒”空壳

在 Swift Playground(包括 macOS Playground 和 Xcode 的 Playground page)中:

Bundle.main 指向的是临时执行环境的包。

并不会自动包含手动拖进 Playground 的文件,即使能在Xcode左边列表看到它。

所以 Bundle.main.url(forResource:withExtension:) 会返回 nil。

Playground 中读取 JSON 文件的正确方式

需要用 #file, URL(fileURLWithPath:) 等方式明确指向文件路径:

import Foundation

let fileURL = URL(fileURLWithPath: #file) // 当前文件路径
    .deletingLastPathComponent()
    .appendingPathComponent("coins.json")

do {
    let data = try Data(contentsOf: fileURL)
    let decoder = JSONDecoder()
    let cryptos = try decoder.decode([CryptoDTO].self, from: data)
    for crypto in cryptos {
        print("Name: \(crypto.name), Price: \(crypto.currentPrice)")
    }
} catch {
    print("读取或解析失败:\(error)")
}

确保 coins.json 文件和 Playground 文件 .playground 在同一目录下,或者相应调整路径。

总结

通过 #file, URL(fileURLWithPath:) 可以在Playground中获取文件路径。

let url = URL(fileURLWithPath: #file)
    .deletingLastPathComponent()
    .appendingPathComponent("coins.json")

输出的URL路径为:

url:file:///Users/fangjunyu.com/Documents/iOS%E5%BC%80%E5%8F%91/iOS%E5%BA%94%E7%94%A8-%E6%B5%8B%E8%AF%95/SwiftUI28year.swiftpm/coins.json

但是更推荐的方式是,将项目代码移到Xcode真实的iOS/macOS App项目中。因为Playground并不是最合适的环境。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注